-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #203 from boostcampwm-2024/v2/TerraformConvertor
V2/terraform convertor
- Loading branch information
Showing
14 changed files
with
383 additions
and
178 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import { ResourceParsingStrategy } from '../util/interface/ResourceParsingStrategy'; | ||
import { NCloudModel } from '../interface/NCloudModel'; | ||
|
||
export abstract class BaseResourceParser implements ResourceParsingStrategy { | ||
protected abstract resourceType: string[]; | ||
|
||
protected abstract createModel(properties: any): NCloudModel; | ||
|
||
canParse(type: string): boolean { | ||
return this.resourceType.includes(type.toLowerCase()); | ||
} | ||
|
||
parse(properties: any): NCloudModel { | ||
this.validateProperties(properties); | ||
return this.createModel(properties); | ||
} | ||
|
||
protected validateProperties(properties: any): void {} | ||
|
||
protected getNameOrDefault(properties: any, defaultPrefix: string): string { | ||
return ( | ||
properties.name?.toLowerCase() || `${defaultPrefix}-${Date.now()}` | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import { BaseResourceParser } from './BaseResourceParser'; | ||
import { ValidationError } from '../util/ValidationError'; | ||
import { NCloudModel } from '../interface/NCloudModel'; | ||
import { NCloudMySQL } from '../model/NCloudMySQL'; | ||
|
||
export class MySQLParesr extends BaseResourceParser { | ||
protected resourceType = ['db-mysql', 'mysql']; | ||
private validationRules: MySQLValidationRules[] = [ | ||
{ | ||
fieldName: 'serviceName', | ||
minLength: 3, | ||
maxLength: 30, | ||
required: true, | ||
}, | ||
{ | ||
fieldName: 'serverNamePrefix', | ||
minLength: 3, | ||
maxLength: 20, | ||
required: true, | ||
}, | ||
{ fieldName: 'userName', minLength: 4, maxLength: 16, required: true }, | ||
{ | ||
fieldName: 'userPassword', | ||
minLength: 8, | ||
maxLength: 20, | ||
required: true, | ||
}, | ||
{ fieldName: 'hostIp', required: true }, | ||
{ | ||
fieldName: 'databaseName', | ||
minLength: 1, | ||
maxLength: 30, | ||
required: true, | ||
}, | ||
]; | ||
|
||
protected validateProperties(properties: any) { | ||
for (const rule of this.validationRules) { | ||
this.validateField(properties, rule); | ||
} | ||
} | ||
|
||
protected validateField(properties: any, rule: MySQLValidationRules): void { | ||
const value = properties[rule.fieldName]; | ||
|
||
if (rule.required && !value) { | ||
throw new ValidationError( | ||
'MySQL', | ||
rule.fieldName, | ||
'필수 속성이 없습니다.', | ||
); | ||
} | ||
|
||
if (value && rule.minLength && value.length < rule.minLength) { | ||
throw new ValidationError( | ||
'MySQL', | ||
rule.fieldName, | ||
'최소 길이보다 짧습니다.', | ||
); | ||
} | ||
|
||
if (value && rule.maxLength && value.length > rule.maxLength) { | ||
throw new ValidationError( | ||
'MySQL', | ||
rule.fieldName, | ||
'최대 길이를 초과했습니다.', | ||
); | ||
} | ||
} | ||
|
||
protected createModel(properties: any): NCloudModel { | ||
return new NCloudMySQL({ | ||
serviceName: properties.serviceName || 'mysql', | ||
serverNamePrefix: properties.serverNamePrefix, | ||
userName: properties.userName, | ||
userPassword: properties.userPassword, | ||
hostIp: properties.hostIp, | ||
databaseName: properties.databaseName, | ||
subnet: properties.subnet, | ||
vpc: properties.vpc, | ||
}); | ||
} | ||
} |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { ResourceParsingStrategy } from '../util/interface/ResourceParsingStrategy'; | ||
import { VPCParser } from './VPCParser'; | ||
import { NCloudModel } from '../interface/NCloudModel'; | ||
import { MySQLParesr } from './MySQLParesr'; | ||
import { ServerParser } from './ServerParser'; | ||
import { SubnetParser } from './SubnetParser'; | ||
|
||
export class ResourceParserFactory { | ||
private static strategy: ResourceParsingStrategy[] = [ | ||
new VPCParser(), | ||
new MySQLParesr(), | ||
new ServerParser(), | ||
new SubnetParser() | ||
]; | ||
|
||
static getParser(type: string): ResourceParsingStrategy{ | ||
const parser = this.strategy.find(s => s.canParse(type)); | ||
if(!parser) { | ||
throw new Error('올바르지 않은 리소스 타입입니다'); | ||
} | ||
return parser; | ||
} | ||
|
||
static parseResource(type: string, properties: any): NCloudModel{ | ||
const parser = this.getParser(type); | ||
return parser.parse(properties); | ||
} | ||
|
||
static registerParser(parser: ResourceParsingStrategy): void { | ||
this.strategy.push(parser); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import { BaseResourceParser } from './BaseResourceParser'; | ||
import { ValidationError } from '../util/ValidationError'; | ||
import { NCloudServer } from '../model/NCloudServer'; | ||
|
||
export class ServerParser extends BaseResourceParser { | ||
protected resourceType = ['server']; | ||
|
||
protected validateProperties(properties: any): void { | ||
if (!properties.server_image_number) { | ||
throw new ValidationError( | ||
'Server', | ||
'serverImageNumber', | ||
'server image number 가 필수입니다.', | ||
); | ||
} | ||
if (!properties.server_spec_code) { | ||
throw new ValidationError( | ||
'Server', | ||
'serverSpecCode', | ||
'server spec code 가 필수입니다.', | ||
); | ||
} | ||
if (!properties.subnet) { | ||
throw new ValidationError( | ||
'Server', | ||
'subnet', | ||
'subnet 이 필수입니다.', | ||
); | ||
} | ||
} | ||
|
||
protected createModel(properties: any): NCloudServer { | ||
return new NCloudServer({ | ||
name: this.getNameOrDefault(properties, 'server'), | ||
serverImageNumber: properties.server_image_number, | ||
serverSpecCode: properties.server_spec_code, | ||
subnetName: properties.subnet, | ||
loginKeyName: properties.loginKeyName, | ||
nicName: properties.nicName, | ||
acgName: properties.acgName, | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import { BaseResourceParser } from './BaseResourceParser'; | ||
import { ValidationError } from '../util/ValidationError'; | ||
import { NCloudSubnet } from '../model/NCloudSubnet'; | ||
|
||
export class SubnetParser extends BaseResourceParser { | ||
protected resourceType = ['subnet']; | ||
|
||
protected validateProperties(properties: any): void { | ||
if (!properties.subnet) { | ||
throw new ValidationError( | ||
'Subnet', | ||
'subnet', | ||
'CIDR block 이 필수 속성입니다.', | ||
); | ||
} | ||
if (!properties.zone) { | ||
throw new ValidationError( | ||
'Subnet', | ||
'zone', | ||
'zone 이 필수 속성입니다.', | ||
); | ||
} | ||
if ( | ||
!properties.subnetType || | ||
!['PUBLIC', 'PRIVATE'].includes(properties.subnetType) | ||
) { | ||
throw new ValidationError( | ||
'Subnet', | ||
'subnetType', | ||
'PUBLIC 또는 PRIVATE 이어야 합니다', | ||
); | ||
} | ||
if ( | ||
properties.usageType && | ||
!['GEN', 'LOADB', 'BM', 'NATGW'].includes(properties.usageType) | ||
) { | ||
throw new ValidationError( | ||
'Subnet', | ||
'usageType', | ||
'GEN, LOADB, BM, NATGW 중 하나여야 합니다', | ||
); | ||
} | ||
} | ||
|
||
protected createModel(properties: any): NCloudSubnet { | ||
return new NCloudSubnet({ | ||
name: this.getNameOrDefault(properties, 'subnet'), | ||
subnet: properties.subnet, | ||
zone: properties.zone, | ||
subnetType: properties.subnetType, | ||
usageType: properties.usageType || 'GEN', | ||
vpcName: properties.vpcName, | ||
networkAclNo: properties.networkAclNo, | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { BaseResourceParser } from './BaseResourceParser'; | ||
import { ValidationError } from '../util/ValidationError'; | ||
import { NCloudVPC } from '../model/NCloudVPC'; | ||
|
||
export class VPCParser extends BaseResourceParser { | ||
protected resourceType = ['vpc']; | ||
|
||
protected validateProperties(properties: any) { | ||
if (!properties.cidrBlock) { | ||
throw new ValidationError( | ||
'VPC', | ||
'ipv4CidrBlock', | ||
'필수 속성이 없습니다.', | ||
); | ||
} | ||
} | ||
|
||
protected createModel(properties: any): NCloudVPC { | ||
return new NCloudVPC({ | ||
name: this.getNameOrDefault(properties, 'vpc'), | ||
ipv4CidrBlock: properties.cidrBlock, | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
interface MySQLValidationRules { | ||
fieldName: string, | ||
minLength?: number, | ||
maxLength?: number, | ||
required: boolean; | ||
} |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
import { ReferenceMetrics } from './ReferenceMetrics'; | ||
|
||
type ReferenceMap = Map<string, string>; | ||
|
||
export class ReferenceReplacer { | ||
private referenceCache = new Map<string, string>(); | ||
|
||
constructor(private resourceNameMap: ReferenceMap) {} | ||
|
||
replaceReferences(properties: { [key: string]: any }): { | ||
[key: string]: any; | ||
} { | ||
const result = { ...properties }; | ||
|
||
for (const [key, value] of Object.entries(result)) { | ||
result[key] = this.transformValue(value); | ||
} | ||
|
||
return result; | ||
} | ||
|
||
private transformValue(value: any): any { | ||
if (typeof value === 'string') { | ||
return this.getCachedReference(value); | ||
} | ||
|
||
if (Array.isArray(value)) { | ||
return value.map((item) => this.transformValue(item)); | ||
} | ||
|
||
if (typeof value === 'object' && value !== null) { | ||
const transformed = { ...value }; | ||
for (const [k, v] of Object.entries(transformed)) { | ||
transformed[k] = this.transformValue(v); | ||
} | ||
return transformed; | ||
} | ||
|
||
return value; | ||
} | ||
|
||
private getCachedReference(value: string): string { | ||
const startTime = performance.now(); | ||
|
||
if (this.referenceCache.has(value)) { | ||
const result = this.referenceCache.get(value)!; | ||
return result; | ||
} | ||
|
||
const resolvedReference = this.resolveReference(value); | ||
this.referenceCache.set(value, resolvedReference); | ||
|
||
return resolvedReference; | ||
} | ||
|
||
private resolveReference(value: string): string { | ||
if (value.startsWith('ncloud_')) { | ||
return value; | ||
} | ||
|
||
const resourceTypeMap = new Map([ | ||
['vpc', 'ncloud_vpc'], | ||
['subnet', 'ncloud_subnet'], | ||
['acg', 'ncloud_access_control_group'], | ||
['nic', 'ncloud_network_interface'], | ||
['server', 'ncloud_server'], | ||
['loginkey', 'ncloud_login_key'], | ||
['nacl', 'ncloud_network_acl'], | ||
['publicip', 'ncloud_public_ip'], | ||
]); | ||
|
||
if (value.endsWith('.default_network_acl_no')) { | ||
const resourceName = value.split('.')[0]; | ||
return `${resourceTypeMap.get('vpc')}.${resourceName}.default_network_acl_no`; | ||
} | ||
|
||
if (value.endsWith('.id')) { | ||
const resourceName = value.split('.')[0]; | ||
const resourceType = resourceTypeMap.get( | ||
resourceName.split('-')[0], | ||
); | ||
return `${resourceType}.${resourceName}.id`; | ||
} | ||
|
||
return value; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
export class ValidationError extends Error{ | ||
constructor( | ||
public readonly resource: string, | ||
public readonly field: string, | ||
message: string | ||
) { | ||
super(`${resource} 에서 ${field}속성이 필요합니다`); | ||
this.name = `ValidationError`; | ||
this.message = message; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import { NCloudModel } from '../../interface/NCloudModel'; | ||
|
||
export interface ResourceParsingStrategy{ | ||
parse(properties: any): NCloudModel; | ||
canParse(type: string): boolean; | ||
} |
Oops, something went wrong.