Refactoring
This commit is contained in:
@@ -3,69 +3,20 @@ import {
|
|||||||
Get,
|
Get,
|
||||||
Headers,
|
Headers,
|
||||||
Query,
|
Query,
|
||||||
Res,
|
|
||||||
StreamableFile
|
StreamableFile
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { Client as MsGraphClient } from '@microsoft/microsoft-graph-client';
|
import { Client as MsGraphClient } from '@microsoft/microsoft-graph-client';
|
||||||
import { MsGraphService, Public } from '@noahspan/noahspan-modules';
|
import { MsGraphService, Public } from '@noahspan/noahspan-modules';
|
||||||
import { FeatureFlagValue } from '@azure/app-configuration';
|
|
||||||
import { Person } from '@microsoft/microsoft-graph-types';
|
import { Person } from '@microsoft/microsoft-graph-types';
|
||||||
import { AppService } from './app.service';
|
import { AppService } from './app.service';
|
||||||
import { createReadStream } from 'fs';
|
|
||||||
import { join } from 'path';
|
|
||||||
import { arrayBuffer } from 'stream/consumers';
|
|
||||||
import type { Response } from 'express';
|
|
||||||
import { DaprService } from '@noahspan/noahspan-modules';
|
|
||||||
|
|
||||||
@Controller()
|
@Controller()
|
||||||
export class AppController {
|
export class AppController {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly appService: AppService,
|
private readonly appService: AppService,
|
||||||
private readonly daprService: DaprService,
|
|
||||||
private readonly msGraphService: MsGraphService
|
private readonly msGraphService: MsGraphService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
// @Public()
|
|
||||||
// @Get('featureFlags')
|
|
||||||
// async getFeatureFlags(
|
|
||||||
// @Query() query: any
|
|
||||||
// ): Promise<{ key: string; enabled: boolean }[]> {
|
|
||||||
// try {
|
|
||||||
// const featureFlagKeys: string[] =
|
|
||||||
// query.keys && query.keys.toString().includes(';')
|
|
||||||
// ? query.keys.split(';')
|
|
||||||
// : [query.keys];
|
|
||||||
// const featureFlagLabel: string = query.label;
|
|
||||||
// const featureFlags: { key: string; enabled: boolean }[] =
|
|
||||||
// await this.appConfigService.getFeatureFlags(
|
|
||||||
// featureFlagKeys,
|
|
||||||
// featureFlagLabel
|
|
||||||
// );
|
|
||||||
|
|
||||||
// return featureFlags;
|
|
||||||
// } catch (error) {
|
|
||||||
// return error;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
@Public()
|
|
||||||
@Get('featureFlags')
|
|
||||||
async getFeatureFlags(@Query() query: any): Promise<void> {
|
|
||||||
try {
|
|
||||||
// const config = await this.daprService.daprClient.configuration.get('app-config', ['flying-logbook'], {
|
|
||||||
// 'label': 'dev'
|
|
||||||
// })
|
|
||||||
console.log('====== BLAH ======');
|
|
||||||
const config =
|
|
||||||
await this.daprService.daprClient.configuration.get('app-config');
|
|
||||||
|
|
||||||
console.log('====== Config ======: ' + config);
|
|
||||||
} catch (error) {
|
|
||||||
console.log(`======= ERROR ======: ${error}`);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Get('userPhoto')
|
@Get('userPhoto')
|
||||||
async getProfilePhoto(@Headers() headers: any): Promise<StreamableFile> {
|
async getProfilePhoto(@Headers() headers: any): Promise<StreamableFile> {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -4,81 +4,42 @@ import { AppService } from './app.service';
|
|||||||
import { AuthGuard, AuthModule } from '@noahspan/noahspan-modules';
|
import { AuthGuard, AuthModule } from '@noahspan/noahspan-modules';
|
||||||
import { MsGraphModule } from '@noahspan/noahspan-modules';
|
import { MsGraphModule } from '@noahspan/noahspan-modules';
|
||||||
import { APP_GUARD } from '@nestjs/core';
|
import { APP_GUARD } from '@nestjs/core';
|
||||||
|
import { FeatureFlagModule } from './featureFlag/feature-flag.module'
|
||||||
import { LogModule } from './log/log.module';
|
import { LogModule } from './log/log.module';
|
||||||
import { PilotModule } from './pilot/pilot.module';
|
import { PilotModule } from './pilot/pilot.module';
|
||||||
import { APP_FILTER } from '@nestjs/core';
|
import { APP_FILTER } from '@nestjs/core';
|
||||||
import { HttpExceptionFilter } from './filters/http-exception.filter';
|
import { HttpExceptionFilter } from './filters/http-exception.filter';
|
||||||
import { DaprModule, DaprService } from '@noahspan/noahspan-modules';
|
import { ConfigModule, ConfigService } from '@nestjs/config';
|
||||||
import { AzureTableStorageModule } from '@noahspan/azure-database';
|
import configuration from './config/configuration';
|
||||||
|
|
||||||
const secretStoreName = 'key-vault';
|
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
AuthModule.registerAsync({
|
AuthModule.registerAsync({
|
||||||
imports: [DaprModule],
|
imports: [ConfigModule],
|
||||||
useFactory: async (daprService: DaprService) => {
|
useFactory: async (configService: ConfigService) => {
|
||||||
const clientIdSecret = await daprService.daprClient.secret.get(
|
|
||||||
secretStoreName,
|
|
||||||
'client-id'
|
|
||||||
);
|
|
||||||
const clientSecret = await daprService.daprClient.secret.get(
|
|
||||||
secretStoreName,
|
|
||||||
'client-secret'
|
|
||||||
);
|
|
||||||
const tenantIdSecret = await daprService.daprClient.secret.get(
|
|
||||||
secretStoreName,
|
|
||||||
'tenant-id'
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
clientId: clientIdSecret['client-id'].toString(),
|
clientId: configService.get<string>('clientId'),
|
||||||
clientSecret: clientSecret['client-secret'].toString(),
|
clientSecret: configService.get<string>('clientSecret'),
|
||||||
tenantId: tenantIdSecret['tenant-id'].toString()
|
tenantId: configService.get<string>('tenantId')
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
inject: [DaprService]
|
inject: [ConfigService]
|
||||||
}),
|
}),
|
||||||
AzureTableStorageModule.forRootAsync({
|
ConfigModule.forRoot({
|
||||||
imports: [DaprModule],
|
load: [configuration]
|
||||||
useFactory: async (daprService: DaprService) => {
|
|
||||||
const connectionString = await daprService.daprClient.secret.get(
|
|
||||||
secretStoreName,
|
|
||||||
'azure-storage-connection-string'
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
connectionString:
|
|
||||||
connectionString['azure-storage-connection-string'].toString()
|
|
||||||
};
|
|
||||||
},
|
|
||||||
inject: [DaprService]
|
|
||||||
}),
|
}),
|
||||||
DaprModule,
|
FeatureFlagModule,
|
||||||
LogModule,
|
LogModule,
|
||||||
MsGraphModule.registerAsync({
|
MsGraphModule.registerAsync({
|
||||||
imports: [DaprModule],
|
imports: [ConfigModule],
|
||||||
useFactory: async (daprService: DaprService) => {
|
useFactory: async (configService: ConfigService) => {
|
||||||
const clientIdSecret = await daprService.daprClient.secret.get(
|
|
||||||
secretStoreName,
|
|
||||||
'client-id'
|
|
||||||
);
|
|
||||||
const clientSecret = await daprService.daprClient.secret.get(
|
|
||||||
secretStoreName,
|
|
||||||
'client-secret'
|
|
||||||
);
|
|
||||||
const tenantIdSecret = await daprService.daprClient.secret.get(
|
|
||||||
secretStoreName,
|
|
||||||
'tenant-id'
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
clientId: clientIdSecret['client-id'].toString(),
|
clientId: configService.get<string>('clientId'),
|
||||||
clientSecret: clientSecret['client-secret'].toString(),
|
clientSecret: configService.get<string>('clientSecret'),
|
||||||
tenantId: tenantIdSecret['tenant-id'].toString()
|
tenantId: configService.get<string>('tenantId')
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
inject: [DaprService]
|
inject: [ConfigService]
|
||||||
}),
|
}),
|
||||||
PilotModule
|
PilotModule
|
||||||
],
|
],
|
||||||
|
|||||||
6
api/src/config/configuration.ts
Normal file
6
api/src/config/configuration.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
export default () => ({
|
||||||
|
azureStorageConnectionString: process.env.AZURE_STORAGE_CONNECTION_STRING,
|
||||||
|
clientId: process.env.CLIENT_ID,
|
||||||
|
clientSecret: process.env.CLIENT_SECRET,
|
||||||
|
tenantId: process.env.TENANT_ID
|
||||||
|
})
|
||||||
40
api/src/featureFlag/feature-flag.controller.ts
Normal file
40
api/src/featureFlag/feature-flag.controller.ts
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import {
|
||||||
|
Controller,
|
||||||
|
Get,
|
||||||
|
HttpException,
|
||||||
|
Param,
|
||||||
|
} from '@nestjs/common';
|
||||||
|
import { FeatureFlagService } from './feature-flag.service';
|
||||||
|
import { CustomError, Public } from '@noahspan/noahspan-modules';
|
||||||
|
|
||||||
|
@Controller('featureFlags')
|
||||||
|
export class FeatureFlagController {
|
||||||
|
constructor(private readonly featureFlagService: FeatureFlagService) {}
|
||||||
|
|
||||||
|
@Get(':partitionKey/:rowKey')
|
||||||
|
@Public()
|
||||||
|
async find(
|
||||||
|
@Param('partitionKey') partitionKey: string,
|
||||||
|
@Param('rowKey') rowKey: string
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
return await this.featureFlagService.find(partitionKey, rowKey);
|
||||||
|
} catch (error) {
|
||||||
|
const customError = error as CustomError;
|
||||||
|
|
||||||
|
throw new HttpException(customError.message, customError.statusCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get()
|
||||||
|
@Public()
|
||||||
|
async findAll() {
|
||||||
|
try {
|
||||||
|
return await this.featureFlagService.findAll();
|
||||||
|
} catch (error) {
|
||||||
|
const customError = error as CustomError;
|
||||||
|
|
||||||
|
throw new HttpException(customError.message, customError.statusCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
5
api/src/featureFlag/feature-flag.dto.ts
Normal file
5
api/src/featureFlag/feature-flag.dto.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
export class FeatureFlagDto {
|
||||||
|
partitionKey: string;
|
||||||
|
rowKey: string;
|
||||||
|
active: string;
|
||||||
|
}
|
||||||
7
api/src/featureFlag/feature-flag.entity.ts
Normal file
7
api/src/featureFlag/feature-flag.entity.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import { EntityString } from '@noahspan/azure-database';
|
||||||
|
|
||||||
|
export class FeatureFlag {
|
||||||
|
@EntityString() partitionKey: string;
|
||||||
|
@EntityString() rowKey: string;
|
||||||
|
@EntityString() active: string;
|
||||||
|
}
|
||||||
27
api/src/featureFlag/feature-flag.module.ts
Normal file
27
api/src/featureFlag/feature-flag.module.ts
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { FeatureFlagController } from './feature-flag.controller';
|
||||||
|
import { FeatureFlagService } from './feature-flag.service';
|
||||||
|
import { AzureTableStorageModule } from '@noahspan/azure-database';
|
||||||
|
import { ConfigModule, ConfigService } from '@nestjs/config';
|
||||||
|
import { FeatureFlag } from './feature-flag.entity';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [
|
||||||
|
AzureTableStorageModule.forRootAsync({
|
||||||
|
imports: [ConfigModule],
|
||||||
|
useFactory: async (configService: ConfigService) => {
|
||||||
|
return {
|
||||||
|
connectionString: configService.get<string>('azureStorageConnectionString')
|
||||||
|
};
|
||||||
|
},
|
||||||
|
inject: [ConfigService]
|
||||||
|
}),
|
||||||
|
AzureTableStorageModule.forFeature(FeatureFlag, {
|
||||||
|
createTableIfNotExists: false,
|
||||||
|
table: 'featureFlags'
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
controllers: [FeatureFlagController],
|
||||||
|
providers: [FeatureFlagService]
|
||||||
|
})
|
||||||
|
export class FeatureFlagModule {}
|
||||||
18
api/src/featureFlag/feature-flag.service.ts
Normal file
18
api/src/featureFlag/feature-flag.service.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { InjectRepository, Repository } from '@noahspan/azure-database';
|
||||||
|
import { FeatureFlag } from './feature-flag.entity';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class FeatureFlagService {
|
||||||
|
constructor(
|
||||||
|
@InjectRepository(FeatureFlag) private readonly featureFlagRepository: Repository<FeatureFlag>
|
||||||
|
) {}
|
||||||
|
|
||||||
|
async find(partitionKey: string, rowKey: string): Promise<FeatureFlag> {
|
||||||
|
return await this.featureFlagRepository.find(partitionKey, rowKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
async findAll(): Promise<FeatureFlag[]> {
|
||||||
|
return await this.featureFlagRepository.findAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,7 +13,6 @@ export class HttpExceptionFilter implements ExceptionFilter {
|
|||||||
const response = ctx.getResponse<Response>();
|
const response = ctx.getResponse<Response>();
|
||||||
const request = ctx.getRequest<Request>();
|
const request = ctx.getRequest<Request>();
|
||||||
const status = excpetion.getStatus();
|
const status = excpetion.getStatus();
|
||||||
console.log(excpetion.cause);
|
|
||||||
|
|
||||||
response.status(status).json({
|
response.status(status).json({
|
||||||
name: excpetion.cause,
|
name: excpetion.cause,
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ export class LogController {
|
|||||||
const log = new Log();
|
const log = new Log();
|
||||||
|
|
||||||
Object.assign(log, logDto);
|
Object.assign(log, logDto);
|
||||||
console.log(log);
|
|
||||||
return await this.logService.create(log);
|
return await this.logService.create(log);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const customError = error as CustomError;
|
const customError = error as CustomError;
|
||||||
|
|||||||
@@ -1,32 +1,25 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
import { DaprModule, DaprService } from '@noahspan/noahspan-modules';
|
|
||||||
import { LogController } from './log.controller';
|
import { LogController } from './log.controller';
|
||||||
import { LogService } from './log.service';
|
import { LogService } from './log.service';
|
||||||
import { AzureTableStorageModule } from '@noahspan/azure-database';
|
import { AzureTableStorageModule } from '@noahspan/azure-database';
|
||||||
import { Log } from './log.entity';
|
import { Log } from './log.entity';
|
||||||
|
import { ConfigModule, ConfigService } from '@nestjs/config';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
AzureTableStorageModule.forRootAsync({
|
AzureTableStorageModule.forRootAsync({
|
||||||
imports: [DaprModule],
|
imports: [ConfigModule],
|
||||||
useFactory: async (daprService: DaprService) => {
|
useFactory: async (configService: ConfigService) => {
|
||||||
const connectionString = await daprService.daprClient.secret.get(
|
|
||||||
'key-vault',
|
|
||||||
'azure-storage-connection-string'
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
connectionString:
|
connectionString: configService.get<string>('azureStorageConnectionString')
|
||||||
connectionString['azure-storage-connection-string'].toString()
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
inject: [DaprService]
|
inject: [ConfigService]
|
||||||
}),
|
}),
|
||||||
AzureTableStorageModule.forFeature(Log, {
|
AzureTableStorageModule.forFeature(Log, {
|
||||||
createTableIfNotExists: false,
|
createTableIfNotExists: false,
|
||||||
table: 'logs'
|
table: 'logs'
|
||||||
}),
|
}),
|
||||||
DaprModule
|
|
||||||
],
|
],
|
||||||
controllers: [LogController],
|
controllers: [LogController],
|
||||||
providers: [LogService]
|
providers: [LogService]
|
||||||
|
|||||||
@@ -5,8 +5,6 @@ import { v4 as uuidv4 } from 'uuid';
|
|||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class LogService {
|
export class LogService {
|
||||||
private readonly tableName = 'Logbook';
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@InjectRepository(Log) private readonly logRepository: Repository<Log>
|
@InjectRepository(Log) private readonly logRepository: Repository<Log>
|
||||||
) {}
|
) {}
|
||||||
|
|||||||
@@ -1,32 +1,25 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
import { DaprModule, DaprService } from '@noahspan/noahspan-modules';
|
|
||||||
import { PilotController } from './pilot.controller';
|
import { PilotController } from './pilot.controller';
|
||||||
import { PilotService } from './pilot.service';
|
import { PilotService } from './pilot.service';
|
||||||
import { AzureTableStorageModule } from '@noahspan/azure-database';
|
import { AzureTableStorageModule } from '@noahspan/azure-database';
|
||||||
import { Pilot } from './pilot.entity';
|
import { Pilot } from './pilot.entity';
|
||||||
|
import { ConfigModule, ConfigService } from '@nestjs/config';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
AzureTableStorageModule.forRootAsync({
|
AzureTableStorageModule.forRootAsync({
|
||||||
imports: [DaprModule],
|
imports: [ConfigModule],
|
||||||
useFactory: async (daprService: DaprService) => {
|
useFactory: async (configService: ConfigService) => {
|
||||||
const connectionString = await daprService.daprClient.secret.get(
|
|
||||||
'key-vault',
|
|
||||||
'azure-storage-connection-string'
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
connectionString:
|
connectionString: configService.get<string>('azureStorageConnectionString')
|
||||||
connectionString['azure-storage-connection-string'].toString()
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
inject: [DaprService]
|
inject: [ConfigService]
|
||||||
}),
|
}),
|
||||||
AzureTableStorageModule.forFeature(Pilot, {
|
AzureTableStorageModule.forFeature(Pilot, {
|
||||||
createTableIfNotExists: false,
|
createTableIfNotExists: false,
|
||||||
table: 'pilots'
|
table: 'pilots'
|
||||||
}),
|
}),
|
||||||
DaprModule
|
|
||||||
],
|
],
|
||||||
controllers: [PilotController],
|
controllers: [PilotController],
|
||||||
providers: [PilotService]
|
providers: [PilotService]
|
||||||
|
|||||||
@@ -15,12 +15,17 @@ const App: React.FC<unknown> = () => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const getFeatureFlags = async () => {
|
const getFeatureFlags = async () => {
|
||||||
try {
|
try {
|
||||||
const featureFlagKeys: string = 'flying-pilots';
|
const featureFlags: { key: string; enabled: boolean }[] = []
|
||||||
const response: AxiosResponse = await httpClient.get(
|
const response: AxiosResponse = await httpClient.get(
|
||||||
`api/featureFlags?keys=${featureFlagKeys}&label=${import.meta.env.MODE}`
|
'api/featureFlags'
|
||||||
);
|
);
|
||||||
console.log(response);
|
|
||||||
const featureFlags: { key: string; enabled: boolean }[] = response.data;
|
for (const featureFlag of response.data) {
|
||||||
|
featureFlags.push({
|
||||||
|
key: featureFlag.rowKey,
|
||||||
|
enabled: featureFlag.active === 'true' ? true : false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
if (featureFlags.length > 0) {
|
if (featureFlags.length > 0) {
|
||||||
appContext.dispatch({
|
appContext.dispatch({
|
||||||
@@ -40,7 +45,7 @@ const App: React.FC<unknown> = () => {
|
|||||||
<div>
|
<div>
|
||||||
<SiteNav />
|
<SiteNav />
|
||||||
<Routes>
|
<Routes>
|
||||||
{useFeatureFlag('flying-pilots')?.enabled && (
|
{useFeatureFlag('pilots')?.enabled && (
|
||||||
<Route path="/pilots" element={<Pilots />} />
|
<Route path="/pilots" element={<Pilots />} />
|
||||||
)}
|
)}
|
||||||
<Route path="/" element={<Logbook />} />
|
<Route path="/" element={<Logbook />} />
|
||||||
|
|||||||
@@ -5,6 +5,6 @@ export const useFeatureFlag = (featureFlagKey: string) => {
|
|||||||
const featureFlag = appContext.state.featureFlags.find(
|
const featureFlag = appContext.state.featureFlags.find(
|
||||||
(featureFlag) => featureFlag.key === featureFlagKey
|
(featureFlag) => featureFlag.key === featureFlagKey
|
||||||
);
|
);
|
||||||
|
console.log(featureFlag)
|
||||||
return featureFlag;
|
return featureFlag;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ locals {
|
|||||||
dev = "flying-app-dev"
|
dev = "flying-app-dev"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
container_app_app_container_image = {
|
container_app_app_container_image = {
|
||||||
dev = "noahspan/flying-app:v0.0.1"
|
dev = "noahspan/flying-app:v0.0.1"
|
||||||
}
|
}
|
||||||
@@ -32,6 +31,10 @@ locals {
|
|||||||
dev = "flying-dev"
|
dev = "flying-dev"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logbook_feature_flag_active = {
|
||||||
|
dev = "true"
|
||||||
|
}
|
||||||
|
|
||||||
key_vault_name = {
|
key_vault_name = {
|
||||||
dev = "noahspanflyingkeyvault"
|
dev = "noahspanflyingkeyvault"
|
||||||
}
|
}
|
||||||
@@ -40,11 +43,11 @@ locals {
|
|||||||
dev = "flying-log-analytics-workspace-dev"
|
dev = "flying-log-analytics-workspace-dev"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pilots_feature_flag_active = {
|
||||||
|
dev = "true"
|
||||||
|
}
|
||||||
|
|
||||||
storage_account_name = {
|
storage_account_name = {
|
||||||
dev = "noahspanflyingdev"
|
dev = "noahspanflyingdev"
|
||||||
}
|
}
|
||||||
|
|
||||||
user_assigned_identity_name = {
|
|
||||||
dev = "noahspanflyingdevuser"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -34,14 +34,18 @@ output "key_vault_name" {
|
|||||||
value = local.key_vault_name[var.environment]
|
value = local.key_vault_name[var.environment]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
output "logbook_feature_flag_active" {
|
||||||
|
value = local.logbook_feature_flag_active[var.environment]
|
||||||
|
}
|
||||||
|
|
||||||
output "log_analytics_workspace_name" {
|
output "log_analytics_workspace_name" {
|
||||||
value = local.log_analytics_workspace_name[var.environment]
|
value = local.log_analytics_workspace_name[var.environment]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
output "pilots_feature_flag_active" {
|
||||||
|
value = local.pilots_feature_flag_active[var.environment]
|
||||||
|
}
|
||||||
|
|
||||||
output "storage_account_name" {
|
output "storage_account_name" {
|
||||||
value = local.storage_account_name[var.environment]
|
value = local.storage_account_name[var.environment]
|
||||||
}
|
}
|
||||||
|
|
||||||
output "user_assigned_identity_name" {
|
|
||||||
value = local.user_assigned_identity_name[var.environment]
|
|
||||||
}
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
resource "azurerm_container_app_environment_dapr_component" "table_storage_pilots_dapr_component" {
|
|
||||||
name = "table-storage-pilots"
|
|
||||||
container_app_environment_id = azurerm_container_app_environment.container_app_environment.id
|
|
||||||
component_type = "state.azure.tablestorage"
|
|
||||||
version = "v1"
|
|
||||||
|
|
||||||
metadata {
|
|
||||||
name = "accountName"
|
|
||||||
value = azurerm_storage_account.storage_account.name
|
|
||||||
}
|
|
||||||
|
|
||||||
metadata {
|
|
||||||
name = "azureClientId"
|
|
||||||
value = azurerm_user_assigned_identity.user_assigned_identity.id
|
|
||||||
}
|
|
||||||
|
|
||||||
metadata {
|
|
||||||
name = "tableName"
|
|
||||||
value = "Pilots"
|
|
||||||
}
|
|
||||||
|
|
||||||
scopes = [ azurerm_container_app.container_app_api.dapr[0].app_id ]
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "azurerm_container_app_environment_dapr_component" "table_storage_logbook_dapr_component" {
|
|
||||||
name = "table-storage-logbook"
|
|
||||||
container_app_environment_id = azurerm_container_app_environment.container_app_environment.id
|
|
||||||
component_type = "state.azure.tablestorage"
|
|
||||||
version = "v1"
|
|
||||||
|
|
||||||
metadata {
|
|
||||||
name = "accountName"
|
|
||||||
value = azurerm_storage_account.storage_account.name
|
|
||||||
}
|
|
||||||
|
|
||||||
metadata {
|
|
||||||
name = "azureClientId"
|
|
||||||
value = azurerm_user_assigned_identity.user_assigned_identity.client_id
|
|
||||||
}
|
|
||||||
|
|
||||||
metadata {
|
|
||||||
name = "tableName"
|
|
||||||
value = "Logbook"
|
|
||||||
}
|
|
||||||
|
|
||||||
scopes = [ azurerm_container_app.container_app_api.dapr[0].app_id ]
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "azurerm_container_app_environment_dapr_component" "key_vault_dapr_component" {
|
|
||||||
name = "key-vault"
|
|
||||||
container_app_environment_id = azurerm_container_app_environment.container_app_environment.id
|
|
||||||
component_type = "secretstores.azure.keyvault"
|
|
||||||
version = "v1"
|
|
||||||
|
|
||||||
metadata {
|
|
||||||
name = "vaultName"
|
|
||||||
value = azurerm_key_vault.key_vault.name
|
|
||||||
}
|
|
||||||
|
|
||||||
metadata {
|
|
||||||
name = "azureClientId"
|
|
||||||
value = azurerm_user_assigned_identity.user_assigned_identity.client_id
|
|
||||||
}
|
|
||||||
|
|
||||||
scopes = [ azurerm_container_app.container_app_api.dapr[0].app_id ]
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
resource "azurerm_user_assigned_identity" "user_assigned_identity" {
|
|
||||||
name = module.environment.user_assigned_identity_name
|
|
||||||
resource_group_name = data.azurerm_resource_group.resource_group.name
|
|
||||||
location = data.azurerm_resource_group.resource_group.location
|
|
||||||
}
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
resource "azurerm_key_vault" "key_vault" {
|
|
||||||
name = module.environment.key_vault_name
|
|
||||||
resource_group_name = data.azurerm_resource_group.resource_group.name
|
|
||||||
location = data.azurerm_resource_group.resource_group.location
|
|
||||||
tenant_id = data.azurerm_client_config.current.tenant_id
|
|
||||||
soft_delete_retention_days = 7
|
|
||||||
sku_name = "standard"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "azurerm_key_vault_access_policy" "key_vault_access_policy_cli" {
|
|
||||||
key_vault_id = azurerm_key_vault.key_vault.id
|
|
||||||
tenant_id = data.azurerm_client_config.current.tenant_id
|
|
||||||
object_id = data.azurerm_client_config.current.object_id
|
|
||||||
|
|
||||||
key_permissions = [
|
|
||||||
"Create",
|
|
||||||
"Get",
|
|
||||||
]
|
|
||||||
|
|
||||||
secret_permissions = [
|
|
||||||
"Set",
|
|
||||||
"Get",
|
|
||||||
"Delete",
|
|
||||||
"Purge",
|
|
||||||
"Recover"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "azurerm_key_vault_access_policy" "key_vault_access_policy_user_assigned_identity" {
|
|
||||||
key_vault_id = azurerm_key_vault.key_vault.id
|
|
||||||
tenant_id = data.azurerm_client_config.current.tenant_id
|
|
||||||
object_id = azurerm_user_assigned_identity.user_assigned_identity.principal_id
|
|
||||||
|
|
||||||
key_permissions = [
|
|
||||||
"Create",
|
|
||||||
"Get",
|
|
||||||
]
|
|
||||||
|
|
||||||
secret_permissions = [
|
|
||||||
"Set",
|
|
||||||
"Get",
|
|
||||||
"Delete",
|
|
||||||
"Purge",
|
|
||||||
"Recover"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "azurerm_key_vault_secret" "client_id_key_vault_secret" {
|
|
||||||
name = "client-id"
|
|
||||||
value = var.CLIENT_ID
|
|
||||||
key_vault_id = azurerm_key_vault.key_vault.id
|
|
||||||
|
|
||||||
depends_on = [ azurerm_key_vault_access_policy.key_vault_access_policy_cli ]
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "azurerm_key_vault_secret" "client_secret_key_vault_secret" {
|
|
||||||
name = "client-secret"
|
|
||||||
value = var.CLIENT_SECRET
|
|
||||||
key_vault_id = azurerm_key_vault.key_vault.id
|
|
||||||
|
|
||||||
depends_on = [ azurerm_key_vault_access_policy.key_vault_access_policy_cli ]
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "azurerm_key_vault_secret" "tenant_id_key_vault_secret" {
|
|
||||||
name = "tenant-id"
|
|
||||||
value = var.TENANT_ID
|
|
||||||
key_vault_id = azurerm_key_vault.key_vault.id
|
|
||||||
|
|
||||||
depends_on = [ azurerm_key_vault_access_policy.key_vault_access_policy_cli ]
|
|
||||||
}
|
|
||||||
@@ -42,6 +42,26 @@ resource "azurerm_container_app" "container_app_api" {
|
|||||||
image = module.environment.container_app_api_container_image
|
image = module.environment.container_app_api_container_image
|
||||||
cpu = 0.25
|
cpu = 0.25
|
||||||
memory = "0.5Gi"
|
memory = "0.5Gi"
|
||||||
|
|
||||||
|
env {
|
||||||
|
name = "AZURE_STORAGE_CONNECTION_STRING"
|
||||||
|
secret_name = "azure-storage-connection-string"
|
||||||
|
}
|
||||||
|
|
||||||
|
env {
|
||||||
|
name = "CLIENT_ID"
|
||||||
|
secret_name = "client-id"
|
||||||
|
}
|
||||||
|
|
||||||
|
env {
|
||||||
|
name = "CLIENT_SECRET"
|
||||||
|
secret_name = "client-secret"
|
||||||
|
}
|
||||||
|
|
||||||
|
env {
|
||||||
|
name = "TENANT_ID"
|
||||||
|
secret_name = "tenant-id"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,6 +82,26 @@ resource "azurerm_container_app" "container_app_api" {
|
|||||||
value = var.DOCKER_IO_PASSWORD
|
value = var.DOCKER_IO_PASSWORD
|
||||||
}
|
}
|
||||||
|
|
||||||
|
secret {
|
||||||
|
name = "azure-storage-connection-string"
|
||||||
|
value = var.AZURE_STORAGE_CONNECTION_STRING
|
||||||
|
}
|
||||||
|
|
||||||
|
secret {
|
||||||
|
name = "client-id"
|
||||||
|
value = var.CLIENT_ID
|
||||||
|
}
|
||||||
|
|
||||||
|
secret {
|
||||||
|
name = "client-secret"
|
||||||
|
value = var.CLIENT_SECRET
|
||||||
|
}
|
||||||
|
|
||||||
|
secret {
|
||||||
|
name = "tenant-id"
|
||||||
|
value = var.TENANT_ID
|
||||||
|
}
|
||||||
|
|
||||||
lifecycle {
|
lifecycle {
|
||||||
ignore_changes = [ template[0].container[0].image ]
|
ignore_changes = [ template[0].container[0].image ]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,11 +4,6 @@ resource "azurerm_storage_account" "storage_account" {
|
|||||||
location = data.azurerm_resource_group.resource_group.location
|
location = data.azurerm_resource_group.resource_group.location
|
||||||
account_tier = "Standard"
|
account_tier = "Standard"
|
||||||
account_replication_type = "LRS"
|
account_replication_type = "LRS"
|
||||||
|
|
||||||
identity {
|
|
||||||
type = "UserAssigned"
|
|
||||||
identity_ids = [azurerm_user_assigned_identity.user_assigned_identity.id]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "azurerm_storage_table" "logs_table" {
|
resource "azurerm_storage_table" "logs_table" {
|
||||||
@@ -20,3 +15,30 @@ resource "azurerm_storage_table" "pilot_table" {
|
|||||||
name = "pilots"
|
name = "pilots"
|
||||||
storage_account_name = azurerm_storage_account.storage_account.name
|
storage_account_name = azurerm_storage_account.storage_account.name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resource "azurerm_storage_table" "feature_flags_table" {
|
||||||
|
name = "featureFlags"
|
||||||
|
storage_account_name = azurerm_storage_account.storage_account.name
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "azurerm_storage_table_entity" "logbook_feature_flag_entity" {
|
||||||
|
storage_table_id = azurerm_storage_table.feature_flags_table.id
|
||||||
|
|
||||||
|
partition_key = "featureFlag"
|
||||||
|
row_key = "logbook"
|
||||||
|
|
||||||
|
entity = {
|
||||||
|
active = module.environment.logbook_feature_flag_active
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "azurerm_storage_table_entity" "pilots_feature_flag_entity" {
|
||||||
|
storage_table_id = azurerm_storage_table.feature_flags_table.id
|
||||||
|
|
||||||
|
partition_key = "featureFlag"
|
||||||
|
row_key = "pilots"
|
||||||
|
|
||||||
|
entity = {
|
||||||
|
active = module.environment.pilots_feature_flag_active
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,10 @@ variable "APP_SUBDOMAIN_NAME" {
|
|||||||
type = string
|
type = string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
variable "AZURE_STORAGE_CONNECTION_STRING" {
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|
||||||
variable "CLIENT_ID" {
|
variable "CLIENT_ID" {
|
||||||
type = string
|
type = string
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user