├── .husky └── pre-commit ├── packages ├── terraform │ ├── outputs.tf │ ├── type │ │ └── Either.ts │ ├── parser │ │ ├── ParserMetrics.ts │ │ ├── cloudCanvasParser.ts │ │ ├── interface │ │ │ └── MySQLValidationRules.ts │ │ ├── VPCParser.ts │ │ └── BaseResourceParser.ts │ ├── util │ │ ├── ReferenceMetrics.ts │ │ ├── interface │ │ │ └── ResourceParsingStrategy.ts │ │ ├── resourceParser.ts │ │ ├── ValidationError.ts │ │ ├── provider.ts │ │ └── generator.ts │ ├── .gitignore │ ├── interface │ │ ├── FileOption.ts │ │ ├── NetworkACL.ts │ │ ├── ObjectStorageBucket.ts │ │ ├── LoginKey.ts │ │ ├── ACG.ts │ │ ├── RedisConfigGroup.ts │ │ ├── CloudCanvasNode.ts │ │ ├── Provider.ts │ │ ├── NetworkInterface.ts │ │ ├── PublicIp.ts │ │ ├── ACGRule.ts │ │ ├── Redis.ts │ │ ├── LoadBalancer.ts │ │ ├── NCloudModel.ts │ │ ├── Server.ts │ │ ├── VPC.ts │ │ ├── MySQL.ts │ │ ├── Subnet.ts │ │ ├── LaunchConfiguration.ts │ │ └── KsCluster.ts │ ├── enum │ │ └── ResourcePriority.ts │ └── model │ │ ├── NCloudObjectStorageBucket.ts │ │ ├── NCloudNetworkACL.ts │ │ ├── NCloudLoginKey.ts │ │ ├── NCloudPublicIP.ts │ │ └── NCloudRedisConfigGroup.ts ├── cloud-graph │ ├── src │ │ ├── vite-env.d.ts │ │ ├── components │ │ │ ├── Svg │ │ │ │ ├── Rect.tsx │ │ │ │ ├── Polygon.tsx │ │ │ │ └── Stroke.tsx │ │ │ └── Node │ │ │ │ └── cloud │ │ │ │ ├── Container │ │ │ │ └── Container2D.tsx │ │ │ │ └── Server │ │ │ │ └── Server3D.tsx │ │ ├── stories-example │ │ │ ├── assets │ │ │ │ ├── docs.png │ │ │ │ ├── assets.png │ │ │ │ ├── share.png │ │ │ │ ├── context.png │ │ │ │ ├── styling.png │ │ │ │ ├── testing.png │ │ │ │ ├── theming.png │ │ │ │ ├── accessibility.png │ │ │ │ ├── addon-library.png │ │ │ │ ├── figma-plugin.png │ │ │ │ ├── avif-test-image.avif │ │ │ │ └── youtube.svg │ │ │ ├── header.css │ │ │ ├── button.css │ │ │ └── Header.stories.ts │ │ ├── main.tsx │ │ ├── constants │ │ │ └── index.ts │ │ └── store │ │ │ └── useSvgStore.ts │ ├── tsconfig.json │ ├── vite.config.ts │ ├── .gitignore │ ├── index.html │ ├── .storybook │ │ ├── preview.tsx │ │ └── main.ts │ ├── tsconfig.node.json │ ├── tsconfig.app.json │ └── eslint.config.js ├── ncloud-sdk │ ├── src │ │ ├── services │ │ │ ├── vserver │ │ │ │ ├── models │ │ │ │ │ ├── acg │ │ │ │ │ │ ├── RemoveAccessControlGroupOutboundRuleRequest.ts │ │ │ │ │ │ ├── RemoveAccessControlGroupOutboundRuleResponse.ts │ │ │ │ │ │ └── GetAccessControlGroupDetailRequest.ts │ │ │ │ │ ├── common │ │ │ │ │ │ ├── getRegionListRequest.ts │ │ │ │ │ │ ├── getZoneListRequest.ts │ │ │ │ │ │ ├── getRaidListRequest.ts │ │ │ │ │ │ ├── getHypervisorTypeListRequest.ts │ │ │ │ │ │ ├── getRegionListResponse.ts │ │ │ │ │ │ ├── getServerSpecDetailRequest.ts │ │ │ │ │ │ ├── getHypervisorTypeListResponse.ts │ │ │ │ │ │ └── getZoneListResponse.ts │ │ │ │ │ ├── login-key │ │ │ │ │ │ ├── CreateLoginKeyRequest.ts │ │ │ │ │ │ ├── DeleteLoginKeysResponse.ts │ │ │ │ │ │ ├── DeleteLoginKeysRequest.ts │ │ │ │ │ │ ├── CreateLoginKeyResponse.ts │ │ │ │ │ │ ├── GetLoginKeyListRequest.ts │ │ │ │ │ │ ├── ImportLoginKeyRequest.ts │ │ │ │ │ │ ├── ImportLoginKeyResponse.ts │ │ │ │ │ │ └── GetLoginKeyListResponse.ts │ │ │ │ │ ├── server │ │ │ │ │ │ ├── GetRootPasswordResponse.ts │ │ │ │ │ │ ├── GetServerInstanceDetailRequest.ts │ │ │ │ │ │ ├── InterruptServerInstanceRequest.ts │ │ │ │ │ │ ├── SetProtectServerTerminationResponse.ts │ │ │ │ │ │ ├── GetRootPasswordServerInstanceListResponse.ts │ │ │ │ │ │ ├── StartServerInstancesRequest.ts │ │ │ │ │ │ ├── StopServerInstancesRequest.ts │ │ │ │ │ │ ├── RebootServerInstancesRequest.ts │ │ │ │ │ │ ├── TerminateServerInstancesRequest.ts │ │ │ │ │ │ ├── SetProtectServerTerminationRequest.ts │ │ │ │ │ │ ├── GetRootPasswordRequest.ts │ │ │ │ │ │ └── GetRootPasswordServerInstanceListRequest.ts │ │ │ │ │ ├── public-ip │ │ │ │ │ │ ├── GetPublicIpTargetServerInstanceListRequest.ts │ │ │ │ │ │ ├── DeletePublicIpInstanceRequest.ts │ │ │ │ │ │ └── GetPublicIpInstanceDetailRequest.ts │ │ │ │ │ ├── server-image │ │ │ │ │ │ ├── GetServerImageDetailRequest.ts │ │ │ │ │ │ ├── DeleteServerImageRequest.ts │ │ │ │ │ │ ├── GetMemberServerImageInstanceDetailRequest.ts │ │ │ │ │ │ ├── DeleteMemberServerImageInstancesRequest.ts │ │ │ │ │ │ ├── DeleteServerImageResponse.ts │ │ │ │ │ │ ├── RemoveServerImageSharingPermissionRequest.ts │ │ │ │ │ │ └── AddServerImageSharingPermissionRequest.ts │ │ │ │ │ ├── placement-group │ │ │ │ │ │ ├── DeletePlacementGroupRequest.ts │ │ │ │ │ │ ├── GetPlacementGroupDetailRequest.ts │ │ │ │ │ │ ├── CreatePlacementGroupRequest.ts │ │ │ │ │ │ ├── CreatePlacementGroupResponse.ts │ │ │ │ │ │ ├── DeletePlacementGroupResponse.ts │ │ │ │ │ │ ├── GetPlacementGroupListRequest.ts │ │ │ │ │ │ └── GetPlacementGroupListResponse.ts │ │ │ │ │ ├── init-script │ │ │ │ │ │ ├── DeleteInitScriptsRequest.ts │ │ │ │ │ │ └── GetInitScriptDetailRequest.ts │ │ │ │ │ ├── network-interface │ │ │ │ │ │ ├── DeleteNetworkInterfaceRequest.ts │ │ │ │ │ │ ├── DisableFlowLogRequest.ts │ │ │ │ │ │ └── GetNetworkInterfaceDetailRequest.ts │ │ │ │ │ ├── storage │ │ │ │ │ │ ├── GetBlockStorageInstanceDetailRequest.ts │ │ │ │ │ │ └── DeleteBlockStorageInstancesRequest.ts │ │ │ │ │ └── snapshot │ │ │ │ │ │ ├── DeleteBlockStorageSnapshotInstancesRequest.ts │ │ │ │ │ │ └── GetBlockStorageSnapshotInstanceDetailRequest.ts │ │ │ │ ├── types.ts │ │ │ │ └── signature.ts │ │ │ ├── price │ │ │ │ ├── index.ts │ │ │ │ ├── models │ │ │ │ │ ├── GetProductCategoryListRequest.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── GetPriceListRequest.ts │ │ │ │ │ ├── CommonCode.ts │ │ │ │ │ ├── GetProductListRequest.ts │ │ │ │ │ ├── NcloudResponse.ts │ │ │ │ │ └── GetProductPriceListRequest.ts │ │ │ │ └── types.ts │ │ │ ├── subnet │ │ │ │ ├── models │ │ │ │ │ ├── SubnetNoList.ts │ │ │ │ │ ├── CreateSubnetResponse.ts │ │ │ │ │ ├── DeleteSubnetResponse.ts │ │ │ │ │ ├── GetSubnetListResponse.ts │ │ │ │ │ ├── GetSubnetDetailResponse.ts │ │ │ │ │ ├── CommonCode.ts │ │ │ │ │ ├── SubnetList.ts │ │ │ │ │ ├── NcloudResponse.ts │ │ │ │ │ ├── DeleteSubnetRequest.ts │ │ │ │ │ └── GetSubnetDetailRequest.ts │ │ │ │ └── types.ts │ │ │ └── vpc │ │ │ │ ├── types.ts │ │ │ │ ├── models │ │ │ │ ├── CommonCode.ts │ │ │ │ ├── DeleteVpcRequest.ts │ │ │ │ ├── GetVpcDetailRequest.ts │ │ │ │ ├── CreateVpcRequest.ts │ │ │ │ ├── CommonResponse.ts │ │ │ │ ├── GetVpcListRequest.ts │ │ │ │ ├── Vpc.ts │ │ │ │ ├── VpcList.ts │ │ │ │ ├── CreateVpcResponse.ts │ │ │ │ ├── GetVpcListResponse.ts │ │ │ │ ├── DeleteVpcResponse.ts │ │ │ │ └── GetVpcDetailResponse.ts │ │ │ │ ├── signature.ts │ │ │ │ └── createVpc.ts │ │ ├── index.ts │ │ ├── types.ts │ │ ├── VpcApi.ts │ │ ├── signature.ts │ │ └── createVpc.ts │ ├── tsup.build.config.ts │ └── tsup.bundle.config.ts └── cli │ ├── tsup.config.ts │ ├── turbo.json │ ├── src │ └── index.ts │ └── package.json ├── .prettierignore ├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE │ ├── 버그-이슈-템플릿.md │ ├── 기능-이슈-템플릿.md │ └── 리팩토링-이슈-템플릿.md ├── pull_request_template.md └── workflows │ └── pr-build-test.yml ├── apps ├── hub │ ├── src │ │ ├── data │ │ │ └── constants.ts │ │ ├── app │ │ │ ├── canvas │ │ │ │ └── page.tsx │ │ │ ├── favicon.ico │ │ │ ├── login │ │ │ │ └── page.tsx │ │ │ ├── my │ │ │ │ ├── withdrawal │ │ │ │ │ └── page.tsx │ │ │ │ ├── shared │ │ │ │ │ └── page.tsx │ │ │ │ ├── starred │ │ │ │ │ └── page.tsx │ │ │ │ ├── architectures │ │ │ │ │ └── page.tsx │ │ │ │ └── layout.tsx │ │ │ ├── fonts.ts │ │ │ ├── page.tsx │ │ │ ├── globals.css │ │ │ └── layout.tsx │ │ ├── fonts │ │ │ └── GamjaFlower-Regular.ttf │ │ ├── utils │ │ │ ├── fetcher.ts │ │ │ └── pagination.ts │ │ ├── ui │ │ │ ├── Tag.tsx │ │ │ ├── LinkButton.tsx │ │ │ ├── ErrorMessage.tsx │ │ │ ├── ImportIcon.tsx │ │ │ ├── Button.tsx │ │ │ ├── DeleteIcon.tsx │ │ │ ├── EditIcon.tsx │ │ │ ├── StarIcon.tsx │ │ │ └── ArrowDownIcon.tsx │ │ ├── types │ │ │ └── index.ts │ │ └── components │ │ │ ├── MyPageSidebar │ │ │ └── item.tsx │ │ │ └── ArchitectureBoard │ │ │ └── ArchitectureList.tsx │ ├── .eslintrc.json │ ├── postcss.config.mjs │ ├── next.config.ts │ ├── .gitignore │ ├── Dockerfile │ ├── tailwind.config.ts │ ├── package.json │ ├── tsconfig.json │ └── public │ │ └── JP.svg ├── server │ ├── src │ │ ├── user │ │ │ ├── dto │ │ │ │ ├── create-user.dto.ts │ │ │ │ └── update-user.dto.ts │ │ │ ├── user.module.ts │ │ │ ├── test │ │ │ │ ├── user.service.spec.ts │ │ │ │ └── user.controller.spec.ts │ │ │ └── user.service.ts │ │ ├── public-architecture │ │ │ ├── dto │ │ │ │ ├── star.dto.ts │ │ │ │ ├── import.dto.ts │ │ │ │ ├── unstar.dto.ts │ │ │ │ ├── find-architecture.dto.ts │ │ │ │ ├── remove-architecture.dto.ts │ │ │ │ ├── modify-architecture.dto.ts │ │ │ │ ├── find-architectures.dto.ts │ │ │ │ ├── save-architecture.dto.ts │ │ │ │ ├── update-public-architecture.dto.ts │ │ │ │ └── create-public-architecture.dto.ts │ │ │ └── public-architecture.module.ts │ │ ├── types │ │ │ ├── authenticated-user.interface.ts │ │ │ └── query-params.dto.ts │ │ ├── private-architecture │ │ │ ├── dto │ │ │ │ ├── find-versions.dto.ts │ │ │ │ ├── find-architecture.dto.ts │ │ │ │ ├── remove-architecture.dto.ts │ │ │ │ ├── find-version.dto.ts │ │ │ │ ├── remove-version.dto.ts │ │ │ │ ├── save-architecture.dto.ts │ │ │ │ ├── save-version.dto.ts │ │ │ │ ├── modify-architecture.dto.ts │ │ │ │ ├── update-private-architecture.dto.ts │ │ │ │ ├── create-version.dto.ts │ │ │ │ └── create-private-architecture.dto.ts │ │ │ └── private-architecture.module.ts │ │ ├── app.service.ts │ │ ├── swagger │ │ │ ├── swagger.readme.ts │ │ │ └── swagger.config.ts │ │ ├── guards │ │ │ ├── jwt-auth.guard.ts │ │ │ └── optional-auth.guard.ts │ │ ├── my │ │ │ ├── dto │ │ │ │ └── find-my-architectures.dto.ts │ │ │ ├── my.module.ts │ │ │ └── test │ │ │ │ ├── my.service.spec.ts │ │ │ │ └── my.controller.spec.ts │ │ ├── prisma │ │ │ ├── prisma.module.ts │ │ │ └── prisma.service.ts │ │ ├── filters │ │ │ └── prisma-exception.filter.spec.ts │ │ ├── app.controller.ts │ │ ├── cloud │ │ │ ├── cloud.module.ts │ │ │ ├── cloud.controller.ts │ │ │ ├── cloud.service.spec.ts │ │ │ └── cloud.controller.spec.ts │ │ ├── decorators │ │ │ └── user.decorator.ts │ │ ├── ncloud-resource │ │ │ └── ncloud-resource.service.spec.ts │ │ ├── auth │ │ │ ├── auth.service.ts │ │ │ ├── auth.module.ts │ │ │ └── strategies │ │ │ │ └── jwt.strategy.ts │ │ └── app.controller.spec.ts │ ├── tsconfig.build.json │ ├── prisma │ │ ├── migrations │ │ │ └── migration_lock.toml │ │ └── schema │ │ │ ├── ncloud-server-resource-type.prisma │ │ │ ├── schema.prisma │ │ │ ├── tag.prisma │ │ │ ├── user.prisma │ │ │ ├── import.prisma │ │ │ ├── version.prisma │ │ │ ├── public-architecture-tag.prisma │ │ │ ├── public-architecture.prisma │ │ │ ├── private-architecture.prisma │ │ │ ├── star.prisma │ │ │ └── ncloud-server-resoruce.prisma │ ├── nest-cli.json │ ├── vitest.config.ts │ ├── vitest.config.e2e.ts │ ├── tsconfig.json │ ├── .eslintrc.js │ ├── start.sh │ ├── test │ │ └── app.e2e-spec.ts │ └── .gitignore ├── client │ ├── src │ │ ├── vite-env.d.ts │ │ ├── App.tsx │ │ ├── models │ │ │ └── ncloud │ │ │ │ ├── User.ts │ │ │ │ ├── ImageBlock.ts │ │ │ │ ├── NatGateway.ts │ │ │ │ ├── CloudFunction.ts │ │ │ │ ├── ContainerRegistry.ts │ │ │ │ ├── ObjectStorage.ts │ │ │ │ ├── LoadBalancer.ts │ │ │ │ ├── Server.ts │ │ │ │ └── utils.ts │ │ ├── Root.tsx │ │ ├── apis │ │ │ └── index.ts │ │ ├── components │ │ │ └── Connectors │ │ │ │ ├── index.tsx │ │ │ │ └── Connector.tsx │ │ └── contexts │ │ │ ├── SvgContext.tsx │ │ │ └── GraphConetxt │ │ │ └── reducer.ts │ ├── .env.development │ ├── .env.production │ ├── vite.config.ts │ ├── index.html │ └── assets │ │ └── JP.svg └── nginx │ └── nginx.conf ├── pnpm-workspace.yaml ├── .prettierrc ├── infra ├── .gitignore ├── dev │ └── variables.tf ├── prod │ └── main.tf ├── modules │ ├── server │ │ ├── outputs.tf │ │ └── variables.tf │ └── vpc_subnet │ │ ├── outputs.tf │ │ └── variables.tf ├── variables.tf └── init.tf ├── config ├── mysql │ ├── init.sql │ └── log.cnf ├── prometheus │ └── prometheus.yml ├── tsconfig.base.json └── cz.js ├── docker-composes ├── monitoring │ └── logging │ │ └── fluentd │ │ ├── Dockerfile │ │ └── conf │ │ └── fluent.conf ├── cloud-canvas-front.yml ├── cloud-canvas-front-hub.yml └── cloud-canvas-back.yml ├── .dockerignore ├── .changeset └── config.json ├── .gitignore └── turbo.json /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | pnpm format 2 | -------------------------------------------------------------------------------- /packages/terraform/outputs.tf: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/terraform/type/Either.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | pnpm-lock.yaml 2 | infra/ -------------------------------------------------------------------------------- /packages/terraform/parser/ParserMetrics.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/terraform/util/ReferenceMetrics.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/terraform/parser/cloudCanvasParser.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @paulcjy @SeoGeonhyuk @Gdm0714 @p1n9d3v -------------------------------------------------------------------------------- /packages/terraform/.gitignore: -------------------------------------------------------------------------------- 1 | terraform.tfvars 2 | variables.tf -------------------------------------------------------------------------------- /apps/hub/src/data/constants.ts: -------------------------------------------------------------------------------- 1 | export const ITEMS_PER_PAGE = 10; 2 | -------------------------------------------------------------------------------- /apps/server/src/user/dto/create-user.dto.ts: -------------------------------------------------------------------------------- 1 | export class CreateUserDto {} 2 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - 'packages/*' 3 | - 'apps/*' 4 | -------------------------------------------------------------------------------- /packages/cloud-graph/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /apps/client/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/acg/RemoveAccessControlGroupOutboundRuleRequest.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "tabWidth": 4, 3 | "useTabs": false, 4 | "singleQuote": true 5 | } 6 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Ncloud'; 2 | export * from './services/price'; 3 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/acg/RemoveAccessControlGroupOutboundRuleResponse.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/client/.env.development: -------------------------------------------------------------------------------- 1 | VITE_API_URL=http://localhost:3000 2 | VITE_MODE=dev 3 | VITE_PORT=3001 4 | -------------------------------------------------------------------------------- /apps/client/.env.production: -------------------------------------------------------------------------------- 1 | VITE_API_URL=https://api.cloudcanvas.kro.kr 2 | VITE_MODE=prod 3 | VITE_PORT=5000 -------------------------------------------------------------------------------- /packages/terraform/interface/FileOption.ts: -------------------------------------------------------------------------------- 1 | export interface FileOption { 2 | log?: boolean; 3 | } 4 | -------------------------------------------------------------------------------- /infra/.gitignore: -------------------------------------------------------------------------------- 1 | *.tfstate 2 | *.tfstate.backup 3 | .terraform/ 4 | .terraform.lock.hcl 5 | *.tfvars 6 | *.tfbackend -------------------------------------------------------------------------------- /apps/hub/src/app/canvas/page.tsx: -------------------------------------------------------------------------------- 1 | export default function CanvasPage() { 2 | return
this is canvas page
; 3 | } 4 | -------------------------------------------------------------------------------- /apps/hub/src/app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2024/web37-cloud-canvas/HEAD/apps/hub/src/app/favicon.ico -------------------------------------------------------------------------------- /apps/hub/src/app/login/page.tsx: -------------------------------------------------------------------------------- 1 | export default function LoginPage() { 2 | return
this is login page
; 3 | } 4 | -------------------------------------------------------------------------------- /packages/terraform/interface/NetworkACL.ts: -------------------------------------------------------------------------------- 1 | export interface NetworkACL { 2 | id: string; 3 | vpcNo: string; 4 | } 5 | -------------------------------------------------------------------------------- /packages/terraform/interface/ObjectStorageBucket.ts: -------------------------------------------------------------------------------- 1 | export interface ObjectStorageBucket { 2 | bucketName: string; 3 | } 4 | -------------------------------------------------------------------------------- /apps/hub/src/app/my/withdrawal/page.tsx: -------------------------------------------------------------------------------- 1 | export default function MyWithdrawalPage() { 2 | return
회원 탈퇴 페이지
; 3 | } 4 | -------------------------------------------------------------------------------- /apps/server/src/public-architecture/dto/star.dto.ts: -------------------------------------------------------------------------------- 1 | export interface StarDto { 2 | id: number; 3 | userId: number; 4 | } 5 | -------------------------------------------------------------------------------- /apps/server/src/public-architecture/dto/import.dto.ts: -------------------------------------------------------------------------------- 1 | export interface ImportDto { 2 | id: number; 3 | userId: number; 4 | } 5 | -------------------------------------------------------------------------------- /apps/server/src/public-architecture/dto/unstar.dto.ts: -------------------------------------------------------------------------------- 1 | export interface UnstarDto { 2 | id: number; 3 | userId: number; 4 | } 5 | -------------------------------------------------------------------------------- /packages/terraform/interface/LoginKey.ts: -------------------------------------------------------------------------------- 1 | export interface LoginKey { 2 | privateKey?: string; 3 | fingerprint?: string; 4 | } 5 | -------------------------------------------------------------------------------- /apps/server/src/types/authenticated-user.interface.ts: -------------------------------------------------------------------------------- 1 | export interface AuthenticatedUser { 2 | id: number; 3 | name: string; 4 | } 5 | -------------------------------------------------------------------------------- /packages/terraform/interface/ACG.ts: -------------------------------------------------------------------------------- 1 | export interface ACG { 2 | id: string; 3 | vpcNo: string; 4 | isDefault?: boolean; 5 | } 6 | -------------------------------------------------------------------------------- /apps/server/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "exclude": ["node_modules", "test", "dist", "**/*spec.ts"] 4 | } 5 | -------------------------------------------------------------------------------- /apps/server/src/private-architecture/dto/find-versions.dto.ts: -------------------------------------------------------------------------------- 1 | export interface FindVersionsDto { 2 | userId: number; 3 | id: number; 4 | } 5 | -------------------------------------------------------------------------------- /apps/hub/src/fonts/GamjaFlower-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2024/web37-cloud-canvas/HEAD/apps/hub/src/fonts/GamjaFlower-Regular.ttf -------------------------------------------------------------------------------- /apps/server/src/private-architecture/dto/find-architecture.dto.ts: -------------------------------------------------------------------------------- 1 | export interface FindArchitectureDto { 2 | userId: number; 3 | id: number; 4 | } 5 | -------------------------------------------------------------------------------- /apps/server/src/public-architecture/dto/find-architecture.dto.ts: -------------------------------------------------------------------------------- 1 | export interface FindArchitectureDto { 2 | id: number; 3 | userId?: number; 4 | } 5 | -------------------------------------------------------------------------------- /infra/dev/variables.tf: -------------------------------------------------------------------------------- 1 | variable "cc_member_server_image_no" { 2 | description = "ncloud member server image" 3 | type = string 4 | sensitive = true 5 | } -------------------------------------------------------------------------------- /packages/terraform/interface/RedisConfigGroup.ts: -------------------------------------------------------------------------------- 1 | export interface RedisConfigGroup { 2 | redisVersion: string; 3 | description?: string; 4 | } 5 | -------------------------------------------------------------------------------- /apps/server/src/private-architecture/dto/remove-architecture.dto.ts: -------------------------------------------------------------------------------- 1 | export interface RemoveArchitectureDto { 2 | userId: number; 3 | id: number; 4 | } 5 | -------------------------------------------------------------------------------- /apps/server/src/public-architecture/dto/remove-architecture.dto.ts: -------------------------------------------------------------------------------- 1 | export interface RemoveArchitectureDto { 2 | id: number; 3 | userId: number; 4 | } 5 | -------------------------------------------------------------------------------- /apps/server/prisma/migrations/migration_lock.toml: -------------------------------------------------------------------------------- 1 | # Please do not edit this file manually 2 | # It should be added in your version-control system (i.e. Git) 3 | provider = "mysql" -------------------------------------------------------------------------------- /apps/server/src/private-architecture/dto/find-version.dto.ts: -------------------------------------------------------------------------------- 1 | export interface FindVersionDto { 2 | userId: number; 3 | id: number; 4 | versionId: number; 5 | } 6 | -------------------------------------------------------------------------------- /packages/cloud-graph/src/components/Svg/Rect.tsx: -------------------------------------------------------------------------------- 1 | function Rect(props: React.ComponentProps<'rect'>) { 2 | return ; 3 | } 4 | 5 | export default Rect; 6 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/price/index.ts: -------------------------------------------------------------------------------- 1 | export * from './PriceApi'; 2 | export * from './PriceApiClient'; 3 | export * from './types'; 4 | export * from './models'; 5 | -------------------------------------------------------------------------------- /packages/terraform/interface/CloudCanvasNode.ts: -------------------------------------------------------------------------------- 1 | export interface CloudCanvasNode { 2 | id: string; 3 | type: string; 4 | properties: { [key: string]: any }; 5 | } 6 | -------------------------------------------------------------------------------- /packages/terraform/interface/Provider.ts: -------------------------------------------------------------------------------- 1 | export interface Provider { 2 | accessKey: string; 3 | secretKey: string; 4 | region: string; 5 | site: string; 6 | } 7 | -------------------------------------------------------------------------------- /apps/server/src/private-architecture/dto/remove-version.dto.ts: -------------------------------------------------------------------------------- 1 | export interface RemoveVersionDto { 2 | userId: number; 3 | id: number; 4 | versionId: number; 5 | } 6 | -------------------------------------------------------------------------------- /infra/prod/main.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | ncloud = { 4 | source = "NaverCloudPlatform/ncloud" 5 | } 6 | } 7 | required_version = ">= 0.13" 8 | } -------------------------------------------------------------------------------- /packages/cloud-graph/src/stories-example/assets/docs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2024/web37-cloud-canvas/HEAD/packages/cloud-graph/src/stories-example/assets/docs.png -------------------------------------------------------------------------------- /packages/terraform/interface/NetworkInterface.ts: -------------------------------------------------------------------------------- 1 | export interface NetworkInterface { 2 | id: string; 3 | subnetNo: string; 4 | accessControlGroups: string[]; 5 | } 6 | -------------------------------------------------------------------------------- /apps/hub/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["next/core-web-vitals", "next/typescript"], 3 | "rules": { 4 | "@typescript-eslint/no-explicit-any": "off" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /apps/server/src/public-architecture/dto/modify-architecture.dto.ts: -------------------------------------------------------------------------------- 1 | export interface ModifyArchitectureDto { 2 | id: number; 3 | userId: number; 4 | title: string; 5 | } 6 | -------------------------------------------------------------------------------- /packages/cloud-graph/src/stories-example/assets/assets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2024/web37-cloud-canvas/HEAD/packages/cloud-graph/src/stories-example/assets/assets.png -------------------------------------------------------------------------------- /packages/cloud-graph/src/stories-example/assets/share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2024/web37-cloud-canvas/HEAD/packages/cloud-graph/src/stories-example/assets/share.png -------------------------------------------------------------------------------- /packages/terraform/interface/PublicIp.ts: -------------------------------------------------------------------------------- 1 | export interface PublicIp { 2 | id: string; 3 | serverInstanceNo?: string; 4 | publicIp?: string; 5 | kindType?: string; 6 | } 7 | -------------------------------------------------------------------------------- /packages/cloud-graph/src/stories-example/assets/context.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2024/web37-cloud-canvas/HEAD/packages/cloud-graph/src/stories-example/assets/context.png -------------------------------------------------------------------------------- /packages/cloud-graph/src/stories-example/assets/styling.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2024/web37-cloud-canvas/HEAD/packages/cloud-graph/src/stories-example/assets/styling.png -------------------------------------------------------------------------------- /packages/cloud-graph/src/stories-example/assets/testing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2024/web37-cloud-canvas/HEAD/packages/cloud-graph/src/stories-example/assets/testing.png -------------------------------------------------------------------------------- /packages/cloud-graph/src/stories-example/assets/theming.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2024/web37-cloud-canvas/HEAD/packages/cloud-graph/src/stories-example/assets/theming.png -------------------------------------------------------------------------------- /packages/terraform/interface/ACGRule.ts: -------------------------------------------------------------------------------- 1 | export interface ACGRule { 2 | protocol: string; 3 | ipBlock: string; 4 | portRange: string; 5 | accessControlGroupNo: string; 6 | } 7 | -------------------------------------------------------------------------------- /packages/cloud-graph/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { "path": "./tsconfig.app.json" }, 5 | { "path": "./tsconfig.node.json" } 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /apps/hub/postcss.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('postcss-load-config').Config} */ 2 | const config = { 3 | plugins: { 4 | tailwindcss: {}, 5 | }, 6 | }; 7 | 8 | export default config; 9 | -------------------------------------------------------------------------------- /apps/nginx/nginx.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 5000; 3 | root /usr/share/nginx/html; 4 | index index.html; 5 | 6 | location / { 7 | try_files $uri $uri/ /index.html; 8 | } 9 | } -------------------------------------------------------------------------------- /packages/cloud-graph/src/stories-example/assets/accessibility.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2024/web37-cloud-canvas/HEAD/packages/cloud-graph/src/stories-example/assets/accessibility.png -------------------------------------------------------------------------------- /packages/cloud-graph/src/stories-example/assets/addon-library.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2024/web37-cloud-canvas/HEAD/packages/cloud-graph/src/stories-example/assets/addon-library.png -------------------------------------------------------------------------------- /packages/cloud-graph/src/stories-example/assets/figma-plugin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2024/web37-cloud-canvas/HEAD/packages/cloud-graph/src/stories-example/assets/figma-plugin.png -------------------------------------------------------------------------------- /packages/cloud-graph/src/stories-example/assets/avif-test-image.avif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2024/web37-cloud-canvas/HEAD/packages/cloud-graph/src/stories-example/assets/avif-test-image.avif -------------------------------------------------------------------------------- /packages/terraform/parser/interface/MySQLValidationRules.ts: -------------------------------------------------------------------------------- 1 | interface MySQLValidationRules { 2 | fieldName: string, 3 | minLength?: number, 4 | maxLength?: number, 5 | required: boolean; 6 | } -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/버그-이슈-템플릿.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 버그 이슈 템플릿 3 | about: 버그에 관련된 이슈를 추가할 때 사용하는 템플릿입니다. 4 | title: '[BUG] - ' 5 | labels: '' 6 | assignees: '' 7 | --- 8 | 9 | ## 상황 10 | 11 | ## 해결 방법 12 | -------------------------------------------------------------------------------- /apps/server/src/app.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@nestjs/common'; 2 | 3 | @Injectable() 4 | export class AppService { 5 | getHello(): string { 6 | return 'Hello World!'; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /apps/server/src/swagger/swagger.readme.ts: -------------------------------------------------------------------------------- 1 | export const SWAGGER_README = ` 2 | ## Swagger README 3 | 4 | This is the Swagger documentation for the Cloud Canvas API. 5 | 6 | API 사용에 대한 README 문서입니다. 7 | `; 8 | -------------------------------------------------------------------------------- /apps/hub/src/app/fonts.ts: -------------------------------------------------------------------------------- 1 | import localFont from 'next/font/local'; 2 | 3 | export const gamjaFlower = localFont({ 4 | src: '../fonts/GamjaFlower-Regular.ttf', 5 | variable: '--font-gamja-flower', 6 | }); 7 | -------------------------------------------------------------------------------- /apps/server/src/guards/jwt-auth.guard.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@nestjs/common'; 2 | import { AuthGuard } from '@nestjs/passport'; 3 | 4 | @Injectable() 5 | export class JwtAuthGuard extends AuthGuard('jwt') {} 6 | -------------------------------------------------------------------------------- /apps/server/src/private-architecture/dto/save-architecture.dto.ts: -------------------------------------------------------------------------------- 1 | export interface SaveArchitectureDto { 2 | userId: number; 3 | title: string; 4 | cost: number; 5 | architecture: Record; 6 | } 7 | -------------------------------------------------------------------------------- /apps/server/src/user/dto/update-user.dto.ts: -------------------------------------------------------------------------------- 1 | import { PartialType } from '@nestjs/mapped-types'; 2 | import { CreateUserDto } from './create-user.dto'; 3 | 4 | export class UpdateUserDto extends PartialType(CreateUserDto) {} 5 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/subnet/models/SubnetNoList.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 서브넷 번호 목록 객체 3 | * @see {@link https://api.ncloud-docs.com/docs/common-vapidatatype-subnetnolist} 4 | */ 5 | export type SubnetNoList = string[]; 6 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/기능-이슈-템플릿.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 기능 이슈 템플릿 3 | about: 기능에 관련된 이슈를 추가할 때 사용하는 템플릿입니다. 4 | title: '[FEAT] - ' 5 | labels: '' 6 | assignees: '' 7 | --- 8 | 9 | ## 목적 10 | 11 | ## 구현 12 | 13 | ## 설명(Optional) 14 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/리팩토링-이슈-템플릿.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 리팩토링 이슈 템플릿 3 | about: "\b리팩토링에 관련된 이슈를 추가할 때 사용하는 템플릿입니다." 4 | title: '[REFACTORING] - ' 5 | labels: '' 6 | assignees: '' 7 | --- 8 | 9 | ## 리팩토링 이유 10 | 11 | ## 리팩토링 계획 12 | -------------------------------------------------------------------------------- /apps/server/src/private-architecture/dto/save-version.dto.ts: -------------------------------------------------------------------------------- 1 | export interface SaveVersionDto { 2 | userId: number; 3 | id: number; 4 | title: string; 5 | architecture: Record; 6 | cost: number; 7 | } 8 | -------------------------------------------------------------------------------- /apps/server/src/public-architecture/dto/find-architectures.dto.ts: -------------------------------------------------------------------------------- 1 | export interface FindArchitecturesDto { 2 | page?: number; 3 | limit?: number; 4 | search?: string; 5 | sort?: string; 6 | order?: string; 7 | } 8 | -------------------------------------------------------------------------------- /packages/terraform/interface/Redis.ts: -------------------------------------------------------------------------------- 1 | export interface Redis { 2 | serviceName: string; 3 | serverNamePrefix: string; 4 | vpcNo: string; 5 | subnetNo: string; 6 | configGroupNo: string; 7 | mode: string; 8 | } 9 | -------------------------------------------------------------------------------- /apps/server/nest-cli.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/nest-cli", 3 | "collection": "@nestjs/schematics", 4 | "sourceRoot": "src", 5 | "compilerOptions": { 6 | "deleteOutDir": true 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /apps/server/src/my/dto/find-my-architectures.dto.ts: -------------------------------------------------------------------------------- 1 | export interface FindMyArchitecturesDto { 2 | page?: number; 3 | limit?: number; 4 | search?: string; 5 | sort?: string; 6 | order?: string; 7 | userId: number; 8 | } 9 | -------------------------------------------------------------------------------- /apps/server/src/private-architecture/dto/modify-architecture.dto.ts: -------------------------------------------------------------------------------- 1 | export interface ModifyArchitectureDto { 2 | userId: number; 3 | id: number; 4 | title?: string; 5 | architecture?: Record; 6 | cost?: number; 7 | } 8 | -------------------------------------------------------------------------------- /apps/server/src/public-architecture/dto/save-architecture.dto.ts: -------------------------------------------------------------------------------- 1 | export interface SaveArchitectureDto { 2 | title: string; 3 | architecture: Record; 4 | cost: number; 5 | tags?: string[]; 6 | userId: number; 7 | } 8 | -------------------------------------------------------------------------------- /apps/server/src/public-architecture/dto/update-public-architecture.dto.ts: -------------------------------------------------------------------------------- 1 | import { IsNotEmpty, IsString } from 'class-validator'; 2 | 3 | export class UpdatePublicArchitectureDto { 4 | @IsString() 5 | @IsNotEmpty() 6 | title: string; 7 | } 8 | -------------------------------------------------------------------------------- /config/mysql/init.sql: -------------------------------------------------------------------------------- 1 | CREATE USER 'exporter'@'%' IDENTIFIED BY 'boostcamp37' WITH MAX_USER_CONNECTIONS 3; 2 | GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'%'; 3 | GRANT ALL PRIVILEGES ON *.* TO 'cloud_canvas_user'@'%'; 4 | FLUSH PRIVILEGES; -------------------------------------------------------------------------------- /packages/ncloud-sdk/tsup.build.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig, type Options } from 'tsup'; 2 | 3 | export default defineConfig((options: Options) => ({ 4 | entryPoints: ['src/index.ts'], 5 | format: ['cjs', 'esm'], 6 | ...options, 7 | })); 8 | -------------------------------------------------------------------------------- /packages/cli/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup'; 2 | 3 | export default defineConfig({ 4 | entryPoints: ['src/index.ts'], 5 | minify: true, 6 | format: ['cjs', 'esm'], // Changed from 'esm' to 'cjs' 7 | noExternal: [], 8 | }); 9 | -------------------------------------------------------------------------------- /packages/terraform/util/interface/ResourceParsingStrategy.ts: -------------------------------------------------------------------------------- 1 | import { NCloudModel } from '../../interface/NCloudModel'; 2 | 3 | export interface ResourceParsingStrategy{ 4 | parse(properties: any): NCloudModel; 5 | canParse(type: string): boolean; 6 | } -------------------------------------------------------------------------------- /apps/server/src/prisma/prisma.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { PrismaService } from './prisma.service'; 3 | 4 | @Module({ 5 | providers: [PrismaService], 6 | exports: [PrismaService], 7 | }) 8 | export class PrismaModule {} 9 | -------------------------------------------------------------------------------- /docker-composes/monitoring/logging/fluentd/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM fluentd:v1.16-1 2 | USER root 3 | RUN gem uninstall -I elasticsearch && gem install elasticsearch -v 7.17.0 4 | RUN ["gem", "install", "fluent-plugin-elasticsearch", "--no-document", "--version", "5.2.0"] 5 | USER fluent -------------------------------------------------------------------------------- /infra/modules/server/outputs.tf: -------------------------------------------------------------------------------- 1 | output "server_publics" { 2 | value = ncloud_server.public_servers[*] 3 | description = "public server infos" 4 | } 5 | 6 | output "server_privates" { 7 | value = ncloud_server.private_servers[*] 8 | description = "private server infos" 9 | } -------------------------------------------------------------------------------- /packages/ncloud-sdk/tsup.bundle.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig, type Options } from 'tsup'; 2 | 3 | export default defineConfig((options: Options) => ({ 4 | entryPoints: ['src/index.ts'], 5 | minify: true, 6 | format: ['cjs', 'esm'], 7 | ...options, 8 | })); 9 | -------------------------------------------------------------------------------- /config/mysql/log.cnf: -------------------------------------------------------------------------------- 1 | [mysqld] 2 | general_log=ON 3 | log_output=FILE 4 | general_log_file=/var/log/mysql/general.log 5 | log_error=/var/log/mysql/error.err 6 | slow_query_log=ON 7 | slow_query_log_file=/var/log/mysql/slow/slow.log 8 | long_query_time=2 9 | log-queries-not-using-indexes -------------------------------------------------------------------------------- /packages/terraform/interface/LoadBalancer.ts: -------------------------------------------------------------------------------- 1 | export interface LoadBalancer { 2 | id: string; 3 | networkType: string; 4 | type: string; 5 | subnetNoList: string[]; 6 | idleTimeout?: number; 7 | throughputType?: string; 8 | description?: string; 9 | } 10 | -------------------------------------------------------------------------------- /packages/terraform/interface/NCloudModel.ts: -------------------------------------------------------------------------------- 1 | import { ResourcePriority } from '../enum/ResourcePriority'; 2 | 3 | export interface NCloudModel { 4 | name?: string; 5 | serviceType: string; 6 | priority: ResourcePriority; 7 | getProperties(): { [key: string]: any }; 8 | } 9 | -------------------------------------------------------------------------------- /packages/terraform/interface/Server.ts: -------------------------------------------------------------------------------- 1 | export interface Server { 2 | id: string; 3 | subnetNo: string; 4 | serverImageNumber: string; 5 | serverSpecCode: string; 6 | loginKeyName?: string; 7 | networkInterfaceNo?: string; 8 | acgName?: string; 9 | } 10 | -------------------------------------------------------------------------------- /packages/terraform/interface/VPC.ts: -------------------------------------------------------------------------------- 1 | export interface VPC { 2 | id: string; 3 | ipv4CidrBlock: string; 4 | defaultNetworkAclNo?: string; 5 | defaultAccessControlGroupNo?: string; 6 | defaultPublicRouteTableNo?: string; 7 | defaultPrivateRouteTableNo?: string; 8 | } 9 | -------------------------------------------------------------------------------- /apps/hub/src/utils/fetcher.ts: -------------------------------------------------------------------------------- 1 | export const fetcher = async (url: string) => { 2 | const res = await fetch(url, { 3 | credentials: 'include', 4 | }); 5 | if (!res.ok) throw new Error('Failed to fetch data'); 6 | const data = await res.json(); 7 | return data; 8 | }; 9 | -------------------------------------------------------------------------------- /apps/server/prisma/schema/ncloud-server-resource-type.prisma: -------------------------------------------------------------------------------- 1 | model NcloudServerResourceType { 2 | id Int @id @default(autoincrement()) 3 | type String @db.Char(50) 4 | 5 | NcloudServerResources NcloudServerResource[] 6 | 7 | @@map("ncloud_server_resource_type") 8 | } 9 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/subnet/models/CreateSubnetResponse.ts: -------------------------------------------------------------------------------- 1 | import { NcloudResponse } from './NcloudResponse'; 2 | import { SubnetList } from './SubnetList'; 3 | 4 | /** 5 | * 서브넷 생성을 위한 응답 객체 6 | */ 7 | export interface CreateSubnetResponse extends NcloudResponse, SubnetList {} 8 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/subnet/models/DeleteSubnetResponse.ts: -------------------------------------------------------------------------------- 1 | import { NcloudResponse } from './NcloudResponse'; 2 | import { SubnetList } from './SubnetList'; 3 | 4 | /** 5 | * 서브넷 삭제를 위한 응답 객체 6 | */ 7 | export interface DeleteSubnetResponse extends NcloudResponse, SubnetList {} 8 | -------------------------------------------------------------------------------- /apps/server/src/filters/prisma-exception.filter.spec.ts: -------------------------------------------------------------------------------- 1 | import { PrismaExceptionFilter } from './prisma-exception.filter'; 2 | 3 | describe('PrismaExceptionFilter', () => { 4 | it('should be defined', () => { 5 | expect(new PrismaExceptionFilter()).toBeDefined(); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /packages/cloud-graph/src/main.tsx: -------------------------------------------------------------------------------- 1 | import { StrictMode } from 'react'; 2 | import { createRoot } from 'react-dom/client'; 3 | import App from './App.tsx'; 4 | 5 | createRoot(document.getElementById('root')!).render( 6 | 7 | 8 | , 9 | ); 10 | -------------------------------------------------------------------------------- /packages/cloud-graph/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import react from '@vitejs/plugin-react'; 3 | import tsconfigPaths from 'vite-tsconfig-paths'; 4 | 5 | // https://vite.dev/config/ 6 | export default defineConfig({ 7 | plugins: [react(), tsconfigPaths()], 8 | }); 9 | -------------------------------------------------------------------------------- /packages/terraform/interface/MySQL.ts: -------------------------------------------------------------------------------- 1 | export interface MySQL { 2 | id: string; 3 | serviceName: string; 4 | serverNamePrefix: string; 5 | userName: string; 6 | userPassword: string; 7 | hostIp: string; 8 | databaseName: string; 9 | subnetNo: string; 10 | } 11 | -------------------------------------------------------------------------------- /packages/terraform/interface/Subnet.ts: -------------------------------------------------------------------------------- 1 | export interface Subnet { 2 | id: string; 3 | vpcNo: string; 4 | subnet: string; 5 | zone: string; 6 | networkAclNo: string; 7 | subnetType: 'PUBLIC' | 'PRIVATE'; 8 | usageType?: 'GEN' | 'LOADB' | 'BM' | 'NATGW'; 9 | } 10 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/types.ts: -------------------------------------------------------------------------------- 1 | export interface ApiKeyCredentials { 2 | accessKey?: string; 3 | secretKey?: string; 4 | } 5 | 6 | export interface RequestConfig { 7 | method: string; 8 | url: string; 9 | timestamp: number; 10 | params?: Record; 11 | } 12 | -------------------------------------------------------------------------------- /apps/hub/next.config.ts: -------------------------------------------------------------------------------- 1 | import type { NextConfig } from 'next'; 2 | 3 | const nextConfig: NextConfig = { 4 | /* config options here */ 5 | output: 'standalone', 6 | env: { 7 | BACK_URL: 'https://api.cloudcanvas.kro.kr', 8 | }, 9 | }; 10 | 11 | export default nextConfig; 12 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/price/models/GetProductCategoryListRequest.ts: -------------------------------------------------------------------------------- 1 | export interface GetProductCategoryListRequest { 2 | /** 3 | * 상품 카테고리 코드 4 | */ 5 | productCategoryCode?: string; 6 | /** 7 | * 응답 결과의 형식 8 | */ 9 | responseFormatType?: string; 10 | } 11 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/price/models/index.ts: -------------------------------------------------------------------------------- 1 | export * from './CommonCode'; 2 | export * from './NcloudResponse'; 3 | export * from './GetPriceListRequest'; 4 | export * from './GetProductCategoryListRequest'; 5 | export * from './GetProductListRequest'; 6 | export * from './GetProductPriceListRequest'; 7 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/price/types.ts: -------------------------------------------------------------------------------- 1 | export interface ApiKeyCredentials { 2 | accessKey: string; 3 | secretKey: string; 4 | } 5 | 6 | export interface RequestConfig { 7 | method: string; 8 | url: string; 9 | timestamp: number; 10 | params?: Record; 11 | } 12 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vpc/types.ts: -------------------------------------------------------------------------------- 1 | export interface ApiKeyCredentials { 2 | accessKey: string; 3 | secretKey: string; 4 | } 5 | 6 | export interface RequestConfig { 7 | method: string; 8 | url: string; 9 | timestamp: number; 10 | params?: Record; 11 | } 12 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/subnet/types.ts: -------------------------------------------------------------------------------- 1 | export interface ApiKeyCredentials { 2 | accessKey: string; 3 | secretKey: string; 4 | } 5 | 6 | export interface RequestConfig { 7 | method: string; 8 | url: string; 9 | timestamp: number; 10 | params?: Record; 11 | } 12 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/types.ts: -------------------------------------------------------------------------------- 1 | export interface ApiKeyCredentials { 2 | accessKey: string; 3 | secretKey: string; 4 | } 5 | 6 | export interface RequestConfig { 7 | method: string; 8 | url: string; 9 | timestamp: number; 10 | params?: Record; 11 | } 12 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | apps/server/Dockerfile 2 | apps/server/node_modules 3 | apps/server/test 4 | apps/server/.gitignore 5 | 6 | apps/client/Dockerfile 7 | apps/client/node_modules 8 | apps/client/test 9 | apps/client/mocks 10 | 11 | apps/hub/Dockerfile 12 | apps/hub/node_modules 13 | apps/hub/.env 14 | 15 | node_modules -------------------------------------------------------------------------------- /apps/server/src/private-architecture/dto/update-private-architecture.dto.ts: -------------------------------------------------------------------------------- 1 | import { PartialType } from '@nestjs/mapped-types'; 2 | import { CreatePrivateArchiectureDto } from './create-private-architecture.dto'; 3 | 4 | export class UpdatePrivateArchiectureDto extends PartialType( 5 | CreatePrivateArchiectureDto, 6 | ) {} 7 | -------------------------------------------------------------------------------- /apps/server/prisma/schema/schema.prisma: -------------------------------------------------------------------------------- 1 | generator client { 2 | provider = "prisma-client-js" 3 | previewFeatures = ["prismaSchemaFolder"] 4 | binaryTargets = ["native", "linux-musl-arm64-openssl-3.0.x"] 5 | } 6 | 7 | datasource db { 8 | provider = "mysql" 9 | url = env("DATABASE_URL") 10 | } 11 | -------------------------------------------------------------------------------- /apps/server/src/prisma/prisma.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable, OnModuleInit } from '@nestjs/common'; 2 | import { PrismaClient } from '@prisma/client'; 3 | 4 | @Injectable() 5 | export class PrismaService extends PrismaClient implements OnModuleInit { 6 | async onModuleInit() { 7 | await this.$connect(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/terraform/interface/LaunchConfiguration.ts: -------------------------------------------------------------------------------- 1 | export interface LaunchConfiguration { 2 | id: string; 3 | serverImageProductCode?: string; 4 | serverProductCode?: string; 5 | memberServerImageNo?: string; 6 | loginKeyName?: string; 7 | initScriptNo?: string; 8 | isEncryptedVolume?: boolean; 9 | } 10 | -------------------------------------------------------------------------------- /apps/server/src/user/user.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { UserService } from './user.service'; 3 | import { UserController } from './user.controller'; 4 | 5 | @Module({ 6 | controllers: [UserController], 7 | providers: [UserService], 8 | exports: [UserService], 9 | }) 10 | export class UserModule {} 11 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/common/getRegionListRequest.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * getRegionList 요청 파라미터 3 | * @see {@link } 4 | */ 5 | export type GetRegionListRequest = { 6 | /** 7 | * 응답 결과의 포맷 타입 8 | * - Options : xml | json 9 | * - Default : xml 10 | */ 11 | responseFormatType?: 'xml' | 'json'; 12 | }; 13 | -------------------------------------------------------------------------------- /.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@3.0.3/schema.json", 3 | "changelog": "@changesets/cli/changelog", 4 | "commit": false, 5 | "fixed": [], 6 | "linked": [], 7 | "access": "public", 8 | "baseBranch": "main", 9 | "updateInternalDependencies": "patch", 10 | "ignore": [] 11 | } 12 | -------------------------------------------------------------------------------- /apps/hub/src/utils/pagination.ts: -------------------------------------------------------------------------------- 1 | import { ITEMS_PER_PAGE } from '@/data/constants'; 2 | 3 | export const calculateTotalPages = (totalItems: number) => 4 | Math.ceil(totalItems / ITEMS_PER_PAGE); 5 | 6 | export const calculatePageRange = (page: number) => ({ 7 | start: (page - 1) * ITEMS_PER_PAGE, 8 | end: page * ITEMS_PER_PAGE, 9 | }); 10 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/subnet/models/GetSubnetListResponse.ts: -------------------------------------------------------------------------------- 1 | import { NcloudResponse } from './NcloudResponse'; 2 | import { SubnetList } from './SubnetList'; 3 | 4 | /** 5 | * 서브넷 목록을 조회하기 위한 응답 객체 6 | * @extends NcloudResponse 7 | * @extends SubnetList 8 | */ 9 | export interface GetSubnetListResponse extends NcloudResponse, SubnetList {} 10 | -------------------------------------------------------------------------------- /packages/terraform/util/resourceParser.ts: -------------------------------------------------------------------------------- 1 | import { ResourceParserFactory } from '../parser/ResourceParserFactory'; 2 | import { NCloudModel } from '../interface/NCloudModel'; 3 | 4 | export function parseToNCloudModel(resource: any): NCloudModel { 5 | const { type, properties } = resource; 6 | return ResourceParserFactory.parseResource(type, properties); 7 | } -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/subnet/models/GetSubnetDetailResponse.ts: -------------------------------------------------------------------------------- 1 | import { NcloudResponse } from './NcloudResponse'; 2 | import { SubnetList } from './SubnetList'; 3 | 4 | /** 5 | * 서브넷 상세 정보 조회를 위한 응답 객체 6 | * @extends NcloudResponse 7 | * @extends SubnetList 8 | */ 9 | export interface GetSubnetDetailResponse extends NcloudResponse, SubnetList {} 10 | -------------------------------------------------------------------------------- /apps/hub/src/ui/Tag.tsx: -------------------------------------------------------------------------------- 1 | import Link from 'next/link'; 2 | 3 | export const Tag = ({ tag }: { tag: string }) => ( 4 | 9 | {tag} 10 | 11 | ); 12 | -------------------------------------------------------------------------------- /apps/server/src/app.controller.ts: -------------------------------------------------------------------------------- 1 | import { Controller, Get } from '@nestjs/common'; 2 | import { AppService } from './app.service'; 3 | 4 | @Controller() 5 | export class AppController { 6 | constructor(private readonly appService: AppService) {} 7 | 8 | @Get() 9 | getHello(): string { 10 | return this.appService.getHello(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vpc/models/CommonCode.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * VPC 상태를 나타내는 공통 코드 3 | * @typedef {Object} CommonCode 4 | * @property {string} code - 5자리 이내의 코드 (INIT | CREAT | RUN | NSTOP) 5 | * @property {string} codeName - 코드에 해당하는 코드 이름 (INIT 상태 | 생성 | 운영 | 정상 정지) 6 | */ 7 | export interface CommonCode { 8 | code: string; 9 | codeName: string; 10 | } 11 | -------------------------------------------------------------------------------- /apps/server/prisma/schema/tag.prisma: -------------------------------------------------------------------------------- 1 | model Tag { 2 | id Int @id @default(autoincrement()) 3 | name String @unique @db.VarChar(15) 4 | createdAt DateTime @default(now()) @map("created_at") @db.Timestamp(0) 5 | publicArchitectures PublicArchitectureTag[] 6 | 7 | @@map("tag") 8 | } 9 | -------------------------------------------------------------------------------- /packages/terraform/util/ValidationError.ts: -------------------------------------------------------------------------------- 1 | export class ValidationError extends Error{ 2 | constructor( 3 | public readonly resource: string, 4 | public readonly field: string, 5 | message: string 6 | ) { 7 | super(`${resource} 에서 ${field}속성이 필요합니다`); 8 | this.name = `ValidationError`; 9 | this.message = message; 10 | } 11 | } -------------------------------------------------------------------------------- /config/prometheus/prometheus.yml: -------------------------------------------------------------------------------- 1 | global: 2 | scrape_interval: 15s 3 | evaluation_interval: 15s 4 | scrape_configs: 5 | - job_name: mysql 6 | scrape_interval: 5s 7 | static_configs: 8 | - targets: ['mysqld_exporter:9104'] 9 | - job_name: redis 10 | scrape_interval: 5s 11 | static_configs: 12 | - targets: ['redis_exporter:9121'] 13 | -------------------------------------------------------------------------------- /apps/server/src/my/my.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { MyService } from './my.service'; 3 | import { MyController } from './my.controller'; 4 | import { PrismaModule } from 'src/prisma/prisma.module'; 5 | 6 | @Module({ 7 | imports: [PrismaModule], 8 | controllers: [MyController], 9 | providers: [MyService], 10 | }) 11 | export class MyModule {} 12 | -------------------------------------------------------------------------------- /infra/modules/vpc_subnet/outputs.tf: -------------------------------------------------------------------------------- 1 | output "vpc_id" { 2 | description = "vpc id" 3 | value = ncloud_vpc.vpc.id 4 | } 5 | 6 | output "public_subnets" { 7 | description = "public subnets infos" 8 | value = ncloud_subnet.public_subnets[*] 9 | } 10 | 11 | output "private_subnets" { 12 | description = "public subnets infos" 13 | value = ncloud_subnet.private_subnets[*] 14 | } -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vpc/models/DeleteVpcRequest.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * VPC 삭제 요청 파라미터 3 | * @typedef {Object} DeleteVpcRequest 4 | * @property {string} [regionCode] - 삭제할 VPC의 리전 코드 (Optional) 5 | * @property {string} vpcNo - 삭제할 VPC 번호 (Required) 6 | */ 7 | export interface DeleteVpcRequest { 8 | regionCode: string; 9 | vpcNo: string; 10 | responseFormatType: string; 11 | } 12 | -------------------------------------------------------------------------------- /apps/client/src/App.tsx: -------------------------------------------------------------------------------- 1 | import CloudGraph from '@/src/CloudGraph'; 2 | import NetworksBar from '@components/NCloud/NetworksBar/index'; 3 | import PropertiesBar from '@components/NCloud/PropertiesBar'; 4 | 5 | export const App = () => { 6 | return ( 7 | <> 8 | 9 | 10 | 11 | 12 | ); 13 | }; 14 | -------------------------------------------------------------------------------- /packages/cloud-graph/src/constants/index.ts: -------------------------------------------------------------------------------- 1 | export const TRANSFORM_MATRIX = 'matrix(0.707 0.409 -0.707 0.409 0 0)'; 2 | 3 | export const SCALE_STEP = 0.1; 4 | export const MIN_SCALE = 0.5; 5 | export const MAX_SCALE = 3; 6 | 7 | export const GRID_SIZE_2D = 90; 8 | export const GRID_WIDTH_3D = 128; 9 | export const GRID_HEIGHT_3D = 74; 10 | export const GRID_RATIO_3D = GRID_WIDTH_3D / GRID_HEIGHT_3D; 11 | -------------------------------------------------------------------------------- /apps/hub/src/app/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | import { ArchitectureBoard } from '@/components/ArchitectureBoard'; 3 | import { Suspense } from 'react'; 4 | 5 | export default function Home() { 6 | return ( 7 | 8 | 11 | 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /apps/hub/src/ui/LinkButton.tsx: -------------------------------------------------------------------------------- 1 | import Link from 'next/link'; 2 | 3 | export const LinkButton = ({ text, href }: { text: string; href: string }) => { 4 | return ( 5 | 9 | {text} 10 | 11 | ); 12 | }; 13 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vpc/models/GetVpcDetailRequest.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * VPC 상세 정보 조회 요청 파라미터 3 | * @typedef {Object} GetVpcDetailRequest 4 | * @property {string} [regionCode] - 조회할 리전 코드 (Optional) 5 | * @property {string} vpcNo - 조회할 VPC 번호 (Required) 6 | */ 7 | export interface GetVpcDetailRequest { 8 | regionCode: string; 9 | vpcNo: string; 10 | responseFormatType?: string; 11 | } 12 | -------------------------------------------------------------------------------- /docker-composes/cloud-canvas-front.yml: -------------------------------------------------------------------------------- 1 | services: 2 | front: 3 | image: t84ar7xr.kr.private-ncr.ntruss.com/front:dev 4 | container_name: front 5 | ports: 6 | - '5001:5000' 7 | networks: 8 | - cloud-canvas-network 9 | restart: unless-stopped 10 | pull_policy: always 11 | networks: 12 | cloud-canvas-network: 13 | driver: bridge 14 | -------------------------------------------------------------------------------- /apps/server/src/private-architecture/dto/create-version.dto.ts: -------------------------------------------------------------------------------- 1 | import { IsString, IsNotEmpty, IsNumber, IsObject } from 'class-validator'; 2 | 3 | export class CreateVersionDto { 4 | @IsString() 5 | @IsNotEmpty() 6 | title: string; 7 | 8 | @IsObject() 9 | @IsNotEmpty() 10 | architecture: Record; 11 | 12 | @IsNumber() 13 | @IsNotEmpty() 14 | cost: number; 15 | } 16 | -------------------------------------------------------------------------------- /packages/cloud-graph/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | 26 | *storybook.log 27 | -------------------------------------------------------------------------------- /packages/terraform/interface/KsCluster.ts: -------------------------------------------------------------------------------- 1 | export interface KsCluster { 2 | hypervisorType?: string; 3 | clusterType: string; 4 | k8sVersion?: string; 5 | loginKeyName: string; 6 | lbPrivateSubnetNo?: string; 7 | lbPublicSubnetNo?: string; 8 | kubeNetworkPlugin?: string; 9 | subnetNoList: string[]; 10 | vpcNo: string; 11 | publicNetwork?: boolean; 12 | zone: string; 13 | } 14 | -------------------------------------------------------------------------------- /apps/hub/src/ui/ErrorMessage.tsx: -------------------------------------------------------------------------------- 1 | import { Button } from './Button'; 2 | 3 | interface ErrorMessageProps { 4 | message: string; 5 | } 6 | 7 | export const ErrorMessage = ({ message }: ErrorMessageProps) => ( 8 |
9 |

Error: {message}

10 | 11 |
12 | ); 13 | -------------------------------------------------------------------------------- /apps/hub/src/app/my/shared/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | import { ArchitectureBoard } from '@/components/ArchitectureBoard'; 3 | import { Suspense } from 'react'; 4 | 5 | export default function MySharedPage() { 6 | return ( 7 | 8 | 11 | 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /infra/variables.tf: -------------------------------------------------------------------------------- 1 | variable "access_key" { 2 | description = "ncloud access key" 3 | type = string 4 | sensitive = true 5 | } 6 | 7 | variable "secret_key" { 8 | description = "ncloud secret key" 9 | type = string 10 | sensitive = true 11 | } 12 | 13 | variable "cc_member_server_image_no" { 14 | description = "ncloud member server image" 15 | type = string 16 | sensitive = true 17 | } -------------------------------------------------------------------------------- /apps/hub/src/app/my/starred/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | import { ArchitectureBoard } from '@/components/ArchitectureBoard'; 3 | import { Suspense } from 'react'; 4 | 5 | export default function MyStarredPage() { 6 | return ( 7 | 8 | 11 | 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /apps/server/src/private-architecture/dto/create-private-architecture.dto.ts: -------------------------------------------------------------------------------- 1 | import { IsNotEmpty, IsNumber, IsObject, IsString } from 'class-validator'; 2 | 3 | export class CreatePrivateArchiectureDto { 4 | @IsString() 5 | @IsNotEmpty() 6 | title: string; 7 | 8 | @IsObject() 9 | @IsNotEmpty() 10 | architecture: Record; 11 | 12 | @IsNumber() 13 | @IsNotEmpty() 14 | cost: number; 15 | } 16 | -------------------------------------------------------------------------------- /apps/client/src/models/ncloud/User.ts: -------------------------------------------------------------------------------- 1 | import { GraphNode } from '@helpers/node'; 2 | import { Node } from '@types'; 3 | import { Networks } from './Networks'; 4 | 5 | export const User: Node = { 6 | ...GraphNode, 7 | type: 'user', 8 | size: { 9 | '2d': { width: 90, height: 90 }, 10 | '3d': { width: 64, height: 95.068, offset: 0 }, 11 | }, 12 | properties: { 13 | ...Networks, 14 | }, 15 | }; 16 | -------------------------------------------------------------------------------- /apps/server/prisma/schema/user.prisma: -------------------------------------------------------------------------------- 1 | model User { 2 | id Int @id @default(autoincrement()) 3 | name String @db.VarChar(30) 4 | createdAt DateTime @default(now()) @map("created_at") @db.Timestamp(0) 5 | 6 | privateArchitectures PrivateArchitecture[] 7 | publicArchitectures PublicArchitecture[] 8 | stars Star[] 9 | imports Import[] 10 | 11 | @@map("user") 12 | } 13 | -------------------------------------------------------------------------------- /apps/client/src/Root.tsx: -------------------------------------------------------------------------------- 1 | import { useLoaderData } from 'react-router-dom'; 2 | import CloudGraphProvider from '@components/CloudGraphProvider'; 3 | import Layout from '@components/Layout'; 4 | 5 | function Root() { 6 | const loader = useLoaderData(); 7 | 8 | return ( 9 | 10 | 11 | 12 | ); 13 | } 14 | 15 | export default Root; 16 | -------------------------------------------------------------------------------- /apps/server/src/cloud/cloud.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { CloudController } from './cloud.controller'; 3 | import { CloudService } from './cloud.service'; 4 | import { PrismaModule } from 'src/prisma/prisma.module'; 5 | 6 | @Module({ 7 | imports: [PrismaModule], 8 | controllers: [CloudController], 9 | providers: [CloudService], 10 | exports: [CloudService], 11 | }) 12 | export class CloudModule {} 13 | -------------------------------------------------------------------------------- /config/tsconfig.base.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", // 컴파일된 javascript 코드 버전을 최신 ECMAScript를 사용 4 | "strict": true, // 엄격한 타입 체크 5 | "esModuleInterop": true, // commonjs, es module 간의 호환성을 유지 6 | "moduleResolution": "Node", // 모듈 해석 방식을 Node로 사용 7 | "resolveJsonModule": true, // json 파일을 모듈처럼 import 가능 8 | "skipLibCheck": true // 라이브러리 체크를 건너뛰어 빌드 속도를 높임 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /apps/client/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig, loadEnv } from 'vite'; 2 | import react from '@vitejs/plugin-react'; 3 | import tsconfigPaths from 'vite-tsconfig-paths'; 4 | 5 | export default ({ mode }) => { 6 | const env = loadEnv(mode, process.cwd()); 7 | return defineConfig({ 8 | plugins: [react(), tsconfigPaths()], 9 | server: { 10 | port: parseInt(env.VITE_PORT as string), 11 | }, 12 | }); 13 | }; 14 | -------------------------------------------------------------------------------- /apps/hub/src/ui/ImportIcon.tsx: -------------------------------------------------------------------------------- 1 | export const ImportIcon = ({ size = 28 }: { size?: number }) => ( 2 | 8 | 9 | 10 | ); 11 | -------------------------------------------------------------------------------- /apps/server/src/decorators/user.decorator.ts: -------------------------------------------------------------------------------- 1 | import { createParamDecorator, ExecutionContext } from '@nestjs/common'; 2 | import { User as UserEntity } from '@prisma/client'; 3 | 4 | export const User = createParamDecorator( 5 | (data: string, ctx: ExecutionContext): UserEntity => { 6 | const request = ctx.switchToHttp().getRequest(); 7 | const user = request.user; 8 | 9 | return data ? user?.[data] : user; 10 | }, 11 | ); 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | logs 2 | *.log 3 | npm-debug.log* 4 | yarn-debug.log* 5 | yarn-error.log* 6 | pnpm-debug.log* 7 | lerna-debug.log* 8 | 9 | node_modules 10 | dist 11 | dist-ssr 12 | *.local 13 | .env 14 | .turbo 15 | .verdaccio 16 | .wiki 17 | 18 | # Editor directories and files 19 | .vscode/* 20 | !.vscode/extensions.json 21 | .idea 22 | .DS_Store 23 | *.suo 24 | *.ntvs* 25 | *.njsproj 26 | *.sln 27 | *.sw? 28 | 29 | tsconfig.tsbuildinfo 30 | 31 | node.json 32 | test.json -------------------------------------------------------------------------------- /apps/client/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Cloud Canvas 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /apps/hub/src/app/my/architectures/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | import { PrivateArchitectureBoard } from '@/components/PrivateArchitectureBoard'; 3 | 4 | import { Suspense } from 'react'; 5 | 6 | export default function MyArchitecturesPage() { 7 | return ( 8 | 9 | 12 | 13 | ); 14 | } 15 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/price/models/GetPriceListRequest.ts: -------------------------------------------------------------------------------- 1 | export interface GetPriceListRequest { 2 | /** 3 | * 조회할 가격 번호 리스트 4 | */ 5 | priceNoList: string[]; 6 | /** 7 | * 조회할 약정 번호 리스트 8 | */ 9 | promiseNoList: string[]; 10 | /** 11 | * 결제 통화 코드 12 | */ 13 | payCurrencyCode: 'KRW' | 'USD' | 'JPY'; 14 | /** 15 | * 응답 결과의 형식 16 | */ 17 | responseFormatType?: 'xml' | 'json'; 18 | } 19 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/login-key/CreateLoginKeyRequest.ts: -------------------------------------------------------------------------------- 1 | type CreateLoginKeyRequest = { 2 | /** 3 | * 생성할 키 이름 4 | * Default : NAVER Cloud Platform가 자동으로 부여 5 | * Min : 3, Max : 30 6 | * 영어, 숫자, "-"의 특수문자만 허용하며 영어로 시작함 7 | * 영어 또는 숫자로 끝남 8 | */ 9 | keyName?: string; 10 | 11 | /** 12 | * 응답 결과의 포맷 타입 13 | * @default xml 14 | */ 15 | responseFormatType?: 'xml' | 'json'; 16 | }; 17 | -------------------------------------------------------------------------------- /apps/hub/src/app/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | /* :root { 6 | --background: #ffffff; 7 | --foreground: #171717; 8 | } 9 | 10 | @media (prefers-color-scheme: dark) { 11 | :root { 12 | --background: #0a0a0a; 13 | --foreground: #ededed; 14 | } 15 | } 16 | 17 | body { 18 | color: var(--foreground); 19 | background: var(--background); 20 | font-family: Arial, Helvetica, sans-serif; 21 | } */ 22 | -------------------------------------------------------------------------------- /apps/server/src/guards/optional-auth.guard.ts: -------------------------------------------------------------------------------- 1 | import { ExecutionContext, Injectable } from '@nestjs/common'; 2 | import { AuthGuard } from '@nestjs/passport'; 3 | 4 | @Injectable() 5 | export class OptionalAuthGuard extends AuthGuard('jwt') { 6 | handleRequest( 7 | err: any, 8 | user: any, 9 | info: any, 10 | context: ExecutionContext, 11 | status?: any, 12 | ): TUser { 13 | return user; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /apps/hub/src/ui/Button.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export const Button = ({ 4 | children, 5 | ...props 6 | }: { 7 | children: React.ReactNode; 8 | [key: string]: unknown; 9 | }) => { 10 | return ( 11 | 17 | ); 18 | }; 19 | -------------------------------------------------------------------------------- /packages/cloud-graph/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + React + TS 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /packages/terraform/enum/ResourcePriority.ts: -------------------------------------------------------------------------------- 1 | export enum ResourcePriority { 2 | VPC = 1, 3 | NETWORK_ACL = 2, 4 | SUBNET = 3, 5 | ACG = 4, 6 | ACG_RULE = 5, 7 | LOGIN_KEY = 6, 8 | NETWORK_INTERFACE = 7, 9 | SERVER = 8, 10 | PUBLIC_IP = 9, 11 | LOAD_BALANCER = 10, 12 | LAUNCH_CONFIGURATION = 11, 13 | MYSQL = 12, 14 | OBJECT_STORAGE_BUCKET = 13, 15 | REDIS = 14, 16 | REDIS_CONFIG_GROUP = 15, 17 | NKS_CLUSTER = 16, 18 | } 19 | -------------------------------------------------------------------------------- /docker-composes/cloud-canvas-front-hub.yml: -------------------------------------------------------------------------------- 1 | services: 2 | front-hub: 3 | image: cloud-canvas.kr.ncr.ntruss.com/front-hub:dev 4 | container_name: front-hub 5 | environment: 6 | BACK_URL: ${BACK_URL} 7 | ports: 8 | - '3000:3000' 9 | networks: 10 | - cloud-canvas-network 11 | restart: unless-stopped 12 | pull_policy: always 13 | networks: 14 | cloud-canvas-network: 15 | driver: bridge 16 | -------------------------------------------------------------------------------- /packages/cli/turbo.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["//"], 3 | "tasks": { 4 | "dev": { 5 | "dependsOn": [ 6 | "@cloud-canvas/client#bundle", 7 | "@cloud-canvas/server#bundle" 8 | ], 9 | "cache": false, 10 | "persistent": true 11 | }, 12 | "build": { 13 | "inputs": ["$TURBO_DEFAULT$", "!README.md", "!CHANGELOG.md"], 14 | "outputs": ["dist/**"] 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /apps/client/src/models/ncloud/ImageBlock.ts: -------------------------------------------------------------------------------- 1 | import { GraphNode } from '@helpers/node'; 2 | import { Node } from '@types'; 3 | import { Networks, NetworksProp } from './Networks'; 4 | 5 | export const ImageBlock: Node = { 6 | ...GraphNode, 7 | type: 'image-block', 8 | size: { 9 | '2d': { width: 90, height: 90 }, 10 | '3d': { width: 128, height: 111, offset: 0 }, 11 | }, 12 | properties: { 13 | ...Networks, 14 | imgSrc: '/upload.svg', 15 | }, 16 | }; 17 | -------------------------------------------------------------------------------- /infra/init.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | ncloud = { 4 | source = "NaverCloudPlatform/ncloud" 5 | } 6 | } 7 | backend "remote" {} 8 | 9 | required_version = ">= 0.13" 10 | } 11 | 12 | provider "ncloud" { 13 | access_key = var.access_key 14 | secret_key = var.secret_key 15 | support_vpc = true 16 | region = "KR" 17 | } 18 | 19 | module "dev" { 20 | source = "./dev" 21 | cc_member_server_image_no = var.cc_member_server_image_no 22 | } -------------------------------------------------------------------------------- /packages/cloud-graph/src/components/Svg/Polygon.tsx: -------------------------------------------------------------------------------- 1 | import { ScreenPoint } from '@/types'; 2 | 3 | interface PolygonProps extends Omit, 'points'> { 4 | points: ScreenPoint[]; 5 | } 6 | 7 | function Polygon(props: PolygonProps) { 8 | const { points, ...restProps } = props; 9 | const pointsStr = points.map((p) => `${p.x},${p.y}`).join(' '); 10 | 11 | return ; 12 | } 13 | 14 | export default Polygon; 15 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/login-key/DeleteLoginKeysResponse.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 로그인키 삭제 응답 3 | * @see {@link https://api.ncloud-docs.com/docs/compute-vserver-server-loginkey-deleteloginkeys} 4 | * @example 5 | * { 6 | * "requestId": "a4cc5d5d-9add-4c4a-ac40-450d19bcd3a8", 7 | * "returnCode": 0, 8 | * "returnMessage": "success" 9 | * } 10 | */ 11 | type DeleteLoginKeysResponse = { 12 | requestId: string; 13 | returnCode: number; 14 | returnMessage: string; 15 | }; 16 | -------------------------------------------------------------------------------- /apps/hub/src/types/index.ts: -------------------------------------------------------------------------------- 1 | export interface Architecture { 2 | id: number; 3 | title: string; 4 | author: string; 5 | cost: number; 6 | createdAt: string; 7 | stars: number; 8 | imports: number; 9 | tags: string[]; 10 | } 11 | 12 | export interface ArchitectureResponse { 13 | total: number; 14 | data: Architecture[]; 15 | } 16 | 17 | export interface SearchParams { 18 | search: string; 19 | page: number; 20 | sort: string; 21 | order: string; 22 | } 23 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | 17 | 18 | ## 연관 이슈 19 | 20 | ## 주요 작업 21 | 22 | ## 구현 결과 23 | 24 | ## 비고(Optional) 25 | -------------------------------------------------------------------------------- /apps/client/src/apis/index.ts: -------------------------------------------------------------------------------- 1 | const BASE_URL = import.meta.env.VITE_API_URL; 2 | export const URLS = { 3 | login: 'auth/login', 4 | share: 'public-architectures', // POST 5 | privateArchi: (id: string) => `private-architectures/${id}`, 6 | }; 7 | 8 | export const urls = (path: keyof typeof URLS, slug?: any) => { 9 | const urls = URLS[path]; 10 | if (typeof urls === 'function') { 11 | return `${BASE_URL}/${urls(slug)}`; 12 | } 13 | 14 | return `${BASE_URL}/${urls}`; 15 | }; 16 | -------------------------------------------------------------------------------- /apps/hub/src/ui/DeleteIcon.tsx: -------------------------------------------------------------------------------- 1 | export const DeleteIcon = ({ size = 28 }: { size?: number }) => ( 2 | 8 | 9 | 10 | ); 11 | -------------------------------------------------------------------------------- /apps/server/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import swc from 'unplugin-swc'; 2 | import { defineConfig } from 'vitest/config'; 3 | 4 | export default defineConfig({ 5 | test: { 6 | globals: true, 7 | root: './', 8 | }, 9 | plugins: [ 10 | // This is required to build the test files with SWC 11 | swc.vite({ 12 | // Explicitly set the module type to avoid inheriting this value from a `.swcrc` config file 13 | module: { type: 'es6' }, 14 | }), 15 | ], 16 | }); 17 | -------------------------------------------------------------------------------- /packages/cli/src/index.ts: -------------------------------------------------------------------------------- 1 | // 현재 사용하지는 않지만 기존 npm 배포 기획에 사용될 수 있어서 남겨둠 2 | 3 | import chalk from 'chalk'; 4 | 5 | const serverPath = 6 | process.env.NODE_ENV === 'development' 7 | ? '../dist/server/index.js' 8 | : './server/index.js'; 9 | 10 | async function main() { 11 | console.log(chalk.blueBright(' Starting Cloud Canvas server...')); 12 | await import(serverPath); 13 | const open = await import('open'); 14 | await open.default('http://localhost:3000'); 15 | } 16 | 17 | main(); 18 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vpc/models/CreateVpcRequest.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * VPC 생성 요청 파라미터 3 | * @typedef {Object} CreateVpcRequest 4 | * @property {string} [regionCode] - VPC를 생성할 리전 코드 (Optional) 5 | * @property {string} [vpcName] - VPC 이름 (Optional, 3~30자 영문 소문자/숫자/'-') 6 | * @property {string} ipv4CidrBlock - VPC의 사설 IPv4 주소 범위 (Required) 7 | */ 8 | export interface CreateVpcRequest { 9 | regionCode: string; 10 | vpcName: string; 11 | ipv4CidrBlock: string; 12 | responseFormatType?: string; 13 | } 14 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/login-key/DeleteLoginKeysRequest.ts: -------------------------------------------------------------------------------- 1 | type DeleteLoginKeysRequest = { 2 | /** 3 | * 삭제할 키 이름 리스트 4 | * keyName은 getLoginKeyList 액션을 통해 획득 가능 5 | * ex) keyNameList.1=key1&keyNameList.2=key2 6 | * @link https://api.ncloud-docs.com/docs/compute-vserver-server-loginkey-getloginkeylist 7 | */ 8 | keyNameList: string[]; 9 | 10 | /** 11 | * 응답 결과의 포맷 타입 12 | * @default xml 13 | */ 14 | responseFormatType?: 'xml' | 'json'; 15 | }; 16 | -------------------------------------------------------------------------------- /apps/hub/src/ui/EditIcon.tsx: -------------------------------------------------------------------------------- 1 | export const EditIcon = ({ size = 28 }: { size?: number }) => ( 2 | 8 | 9 | 10 | ); 11 | -------------------------------------------------------------------------------- /packages/cloud-graph/.storybook/preview.tsx: -------------------------------------------------------------------------------- 1 | import type { Preview } from '@storybook/react'; 2 | import React from 'react'; 3 | import Graph from '../src/components/Graph'; 4 | import GridBackground from '../src/components/GridBackground'; 5 | 6 | const preview: Preview = { 7 | parameters: {}, 8 | decorators: [ 9 | (Story) => ( 10 | 11 | 12 | 13 | 14 | ), 15 | ], 16 | }; 17 | 18 | export default preview; 19 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vpc/models/CommonResponse.ts: -------------------------------------------------------------------------------- 1 | import { VpcList } from './VpcList'; 2 | /** 3 | * API 응답의 기본 구조 4 | * @typedef {Object} CommonResponse 5 | * @property {string} requestId - 요청 ID 6 | * @property {string} returnCode - 응답 코드 7 | * @property {string} returnMessage - 응답 메시지 8 | * @property {number} totalRows - 전체 행 수 9 | */ 10 | export interface CommonResponse extends VpcList { 11 | requestId: string; 12 | returnCode: string; 13 | returnMessage: string; 14 | totalRows: number; 15 | } 16 | -------------------------------------------------------------------------------- /apps/server/src/cloud/cloud.controller.ts: -------------------------------------------------------------------------------- 1 | import { Controller, Get } from '@nestjs/common'; 2 | import { CloudService } from './cloud.service'; 3 | 4 | @Controller('cloud') 5 | export class CloudController { 6 | constructor(private readonly service: CloudService) {} 7 | 8 | @Get('/prices') 9 | getCloudResorucePrices() { 10 | return this.service.findCloudResourcePrices(); 11 | } 12 | 13 | // @Get('/test') 14 | // getTestPrices() { 15 | // return this.service.calculatePrice(); 16 | // } 17 | } 18 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/server/GetRootPasswordResponse.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * root 계정 비밀번호 조회 응답 3 | * @see {@link https://api.ncloud-docs.com/docs/compute-vserver-server-getrootpassword} 4 | * @example 5 | * { 6 | * "requestId": "", 7 | * "returnCode": 0, 8 | * "returnMessage": "success", 9 | * "rootPassword": "P3e7fLnd6=***" 10 | * } 11 | */ 12 | type GetRootPasswordResponse = { 13 | requestId: string; 14 | returnCode: number; 15 | returnMessage: string; 16 | rootPassword: string; 17 | }; 18 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/price/models/CommonCode.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * CommonCode 객체 3 | * @see {@link https://api.ncloud-docs.com/docs/common-vapidatatype-commoncode} 4 | * 추후 통합할 때 Common 폴더로 뺄 예정 5 | */ 6 | export interface CommonCode { 7 | /** 8 | * 5자리 이내의 코드 9 | * 10 | * Required 11 | * @example INIT, CREAT, RUN, NSTOP 12 | */ 13 | code: string; 14 | 15 | /** 16 | * 코드에 해당하는 코드 이름 17 | * 18 | * Required 19 | * @example INIT 상태, 생성, 운영, 정상 정지 20 | */ 21 | codeName: string; 22 | } 23 | -------------------------------------------------------------------------------- /apps/server/vitest.config.e2e.ts: -------------------------------------------------------------------------------- 1 | import swc from 'unplugin-swc'; 2 | import { defineConfig } from 'vitest/config'; 3 | 4 | export default defineConfig({ 5 | test: { 6 | include: ['**/*.e2e-spec.ts'], 7 | globals: true, 8 | alias: { 9 | '@src': './src', 10 | '@test': './test', 11 | }, 12 | root: './', 13 | }, 14 | resolve: { 15 | alias: { 16 | '@src': './src', 17 | '@test': './test', 18 | }, 19 | }, 20 | plugins: [swc.vite()], 21 | }); 22 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/subnet/models/CommonCode.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * CommonCode 객체 3 | * @see {@link https://api.ncloud-docs.com/docs/common-vapidatatype-commoncode} 4 | * 추후 통합할 때 Common 폴더로 뺄 예정 5 | */ 6 | export interface CommonCode { 7 | /** 8 | * 5자리 이내의 코드 9 | * 10 | * Required 11 | * @example INIT, CREAT, RUN, NSTOP 12 | */ 13 | code: string; 14 | 15 | /** 16 | * 코드에 해당하는 코드 이름 17 | * 18 | * Required 19 | * @example INIT 상태, 생성, 운영, 정상 정지 20 | */ 21 | codeName: string; 22 | } 23 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/subnet/models/SubnetList.ts: -------------------------------------------------------------------------------- 1 | import { Subnet } from './Subnet'; 2 | 3 | /** 4 | * 서브넷 리스트 객체 5 | * @see {@link https://api.ncloud-docs.com/docs/common-vapidatatype-subnetlist} 6 | */ 7 | export interface SubnetList { 8 | /** 9 | * 조회된 목록의 총 개수. 10 | * 페이징 처리 요청의 경우 전체 개수. 11 | * 12 | * Required 13 | */ 14 | totalRows: number; 15 | 16 | /** 17 | * List 데이터 타입. 18 | * @see {@link Subnet}
19 | * 20 | * Required 21 | */ 22 | subnetList: Subnet[]; 23 | } 24 | -------------------------------------------------------------------------------- /apps/hub/src/ui/StarIcon.tsx: -------------------------------------------------------------------------------- 1 | export const StarIcon = ({ size = 20 }: { size?: number }) => ( 2 | 8 | 9 | 10 | ); 11 | -------------------------------------------------------------------------------- /apps/server/prisma/schema/import.prisma: -------------------------------------------------------------------------------- 1 | model Import { 2 | id Int @id @default(autoincrement()) 3 | publicArchitectureId Int @map("public_architecture_id") 4 | userId Int @map("user_id") 5 | createdAt DateTime @default(now()) @map("created_at") @db.Timestamp(0) 6 | 7 | publicArchitecture PublicArchitecture @relation(fields: [publicArchitectureId], references: [id]) 8 | user User @relation(fields: [userId], references: [id]) 9 | 10 | @@map("import") 11 | } 12 | -------------------------------------------------------------------------------- /apps/server/prisma/schema/version.prisma: -------------------------------------------------------------------------------- 1 | model Version { 2 | id Int @id @default(autoincrement()) 3 | privateArchitectureId Int @map("private_architecture_id") 4 | title String @db.Char(50) 5 | createdAt DateTime @default(now()) @map("created_at") @db.Timestamp(0) 6 | architecture Json 7 | cost Float @default(0) 8 | 9 | privateArchitecture PrivateArchitecture @relation(fields: [privateArchitectureId], references: [id]) 10 | 11 | @@map("version") 12 | } 13 | -------------------------------------------------------------------------------- /turbo.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://turbo.build/schema.json", 3 | "ui": "tui", 4 | "tasks": { 5 | "start": { 6 | "dependsOn": ["build"] 7 | }, 8 | "dev": { 9 | "cache": false, 10 | "persistent": true 11 | }, 12 | "build": { 13 | "dependsOn": ["clean"], 14 | "inputs": ["$TURBO_DEFAULT$", "!README.md", "!CHANGELOG.md"], 15 | "outputs": ["dist/**"] 16 | }, 17 | "clean": { 18 | "cache": false 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /apps/server/src/my/test/my.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { Test, TestingModule } from '@nestjs/testing'; 2 | import { MyService } from '../my.service'; 3 | 4 | describe('MyService', () => { 5 | let service: MyService; 6 | 7 | beforeEach(async () => { 8 | const module: TestingModule = await Test.createTestingModule({ 9 | providers: [MyService], 10 | }).compile(); 11 | 12 | service = module.get(MyService); 13 | }); 14 | 15 | it('should be defined', () => { 16 | expect(service).toBeDefined(); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /apps/server/src/swagger/swagger.config.ts: -------------------------------------------------------------------------------- 1 | import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger'; 2 | import { SWAGGER_README } from './swagger.readme'; 3 | 4 | export const swaggerConfig = (app) => { 5 | const config = new DocumentBuilder() 6 | .setTitle('Cloud Canvas API') 7 | .setDescription(SWAGGER_README) 8 | .setVersion('1.0') 9 | .addTag('API') 10 | .build(); 11 | 12 | const documentFactory = () => SwaggerModule.createDocument(app, config); 13 | SwaggerModule.setup('api-docs', app, documentFactory); 14 | }; 15 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/common/getZoneListRequest.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * getZoneList 요청 파라미터 3 | * @see {@link } 4 | */ 5 | export type GetZoneListRequest = { 6 | /** 7 | * 리전 코드 8 | * - ZONE 리스트가 조회될 리전(Region) 결정 가능 9 | * - regionCode는 {@link } getRegionList 액션을 통해서 획득 가능 10 | * - Default : getRegionList 조회 결과의 첫 번째 리전을 선택 11 | */ 12 | regionCode?: string; 13 | 14 | /** 15 | * 응답 결과의 포맷 타입 16 | * - Options : xml | json 17 | * - Default : xml 18 | */ 19 | responseFormatType?: 'xml' | 'json'; 20 | }; 21 | -------------------------------------------------------------------------------- /apps/server/prisma/schema/public-architecture-tag.prisma: -------------------------------------------------------------------------------- 1 | model PublicArchitectureTag { 2 | id Int @id @default(autoincrement()) 3 | publicArchitectureId Int @map("public_architecture_id") 4 | tagId Int @map("tag_id") 5 | 6 | publicArchitecture PublicArchitecture @relation(fields: [publicArchitectureId], references: [id]) 7 | tag Tag @relation(fields: [tagId], references: [id]) 8 | 9 | @@unique([publicArchitectureId, tagId], name: "unique_tag") 10 | @@map("public_architecture_tag") 11 | } 12 | -------------------------------------------------------------------------------- /apps/client/src/components/Connectors/index.tsx: -------------------------------------------------------------------------------- 1 | import Connector from '@components/Connectors/Connector'; 2 | import { Node } from '@types'; 3 | 4 | type Props = { 5 | node: Node; 6 | }; 7 | 8 | export default ({ node }: Props) => { 9 | return ( 10 | <> 11 | {Object.entries(node.connectors).map(([type, point]) => ( 12 | 17 | ))} 18 | 19 | ); 20 | }; 21 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/common/getRaidListRequest.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * getRaidList 요청 파라미터 3 | * @see {@link } 4 | */ 5 | export type GetRaidListRequest = { 6 | /** 7 | * 상품 유형 코드 8 | * - 상품 유형별로 사용 가능한 RAID 리스트를 조회 9 | * - productTypeCode는 {@link } getServerImageProductList 액션을 통해서 획득 가능 10 | * - Options : LINUX | WINNT 11 | */ 12 | productTypeCode: 'LINUX' | 'WINNT'; 13 | 14 | /** 15 | * 응답 결과의 포맷 타입 16 | * - Options : xml | json 17 | * - Default : xml 18 | */ 19 | responseFormatType?: 'xml' | 'json'; 20 | }; 21 | -------------------------------------------------------------------------------- /apps/server/src/user/test/user.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { Test, TestingModule } from '@nestjs/testing'; 2 | import { UserService } from '../user.service'; 3 | 4 | describe('UserService', () => { 5 | let service: UserService; 6 | 7 | beforeEach(async () => { 8 | const module: TestingModule = await Test.createTestingModule({ 9 | providers: [UserService], 10 | }).compile(); 11 | 12 | service = module.get(UserService); 13 | }); 14 | 15 | it('should be defined', () => { 16 | expect(service).toBeDefined(); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /apps/server/src/cloud/cloud.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { Test, TestingModule } from '@nestjs/testing'; 2 | import { CloudService } from './cloud.service'; 3 | 4 | describe('CloudService', () => { 5 | let service: CloudService; 6 | 7 | beforeEach(async () => { 8 | const module: TestingModule = await Test.createTestingModule({ 9 | providers: [CloudService], 10 | }).compile(); 11 | 12 | service = module.get(CloudService); 13 | }); 14 | 15 | it('should be defined', () => { 16 | expect(service).toBeDefined(); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /apps/server/src/public-architecture/public-architecture.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { PublicArchitectureService } from './public-architecture.service'; 3 | import { PublicArchitectureController } from './public-architecture.controller'; 4 | import { PrismaModule } from 'src/prisma/prisma.module'; 5 | import { CloudModule } from 'src/cloud/cloud.module'; 6 | 7 | @Module({ 8 | imports: [PrismaModule, CloudModule], 9 | controllers: [PublicArchitectureController], 10 | providers: [PublicArchitectureService], 11 | }) 12 | export class PublicArchitectureModule {} 13 | -------------------------------------------------------------------------------- /apps/server/prisma/schema/public-architecture.prisma: -------------------------------------------------------------------------------- 1 | model PublicArchitecture { 2 | id Int @id @default(autoincrement()) 3 | title String @db.Char(50) 4 | authorId Int @map("author_id") 5 | architecture Json 6 | createdAt DateTime @default(now()) @map("created_at") @db.Timestamp(0) 7 | cost Float @default(0) 8 | 9 | author User @relation(fields: [authorId], references: [id]) 10 | stars Star[] 11 | imports Import[] 12 | tags PublicArchitectureTag[] 13 | 14 | @@map("public_architecture") 15 | } 16 | -------------------------------------------------------------------------------- /apps/server/src/private-architecture/private-architecture.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { PrivateArchitectureService } from './private-architecture.service'; 3 | import { PrivateArchitectureController } from './private-architecture.controller'; 4 | import { PrismaModule } from 'src/prisma/prisma.module'; 5 | import { CloudModule } from 'src/cloud/cloud.module'; 6 | 7 | @Module({ 8 | imports: [PrismaModule, CloudModule], 9 | controllers: [PrivateArchitectureController], 10 | providers: [PrivateArchitectureService], 11 | }) 12 | export class PrivateArchitectureModule {} 13 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/common/getHypervisorTypeListRequest.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * getHypervisorTypeList 요청 파라미터 3 | * @see {@link } 4 | */ 5 | export type GetHypervisorTypeListRequest = { 6 | /** 7 | * 리전 코드 8 | * - 하이퍼바이저타입 리스트가 조회될 리전(Region) 결정 가능 9 | * - regionCode는 {@link } getRegionList 액션을 통해 획득 가능 10 | * - Default : getRegionList 조회 결과의 첫 번째 리전을 선택 11 | */ 12 | regionCode?: string; 13 | 14 | /** 15 | * 응답 결과의 포맷 타입 16 | * - Options : xml | json 17 | * - Default : xml 18 | */ 19 | responseFormatType?: 'xml' | 'json'; 20 | }; 21 | -------------------------------------------------------------------------------- /apps/client/src/models/ncloud/NatGateway.ts: -------------------------------------------------------------------------------- 1 | import { GraphNode } from '@helpers/node'; 2 | import { Node } from '@types'; 3 | import { Networks, NetworksProp } from './Networks'; 4 | 5 | export interface NatGatewayProp extends NetworksProp { 6 | //TODO: 7 | } 8 | 9 | export const NatGateway: Node = { 10 | ...GraphNode, 11 | type: 'nat-gateway', 12 | size: { 13 | '2d': { width: 90, height: 90 }, 14 | '3d': { width: 123, height: 108.05, offset: 0 }, 15 | }, 16 | properties: { 17 | ...Networks, 18 | }, 19 | }; 20 | 21 | export const NatGatewayRequiredFields = {}; 22 | -------------------------------------------------------------------------------- /packages/cloud-graph/src/components/Svg/Stroke.tsx: -------------------------------------------------------------------------------- 1 | import { ScreenPoint } from '@/types'; 2 | 3 | function Stroke({ 4 | points, 5 | stroke = '#000', 6 | strokeWidth = 2, 7 | }: { 8 | points: ScreenPoint[]; 9 | stroke?: string; 10 | strokeWidth?: number; 11 | }) { 12 | const pointsStr = points.map((p) => `${p.x},${p.y}`).join(' '); 13 | return ( 14 | 20 | ); 21 | } 22 | 23 | export default Stroke; 24 | -------------------------------------------------------------------------------- /apps/client/src/components/Connectors/Connector.tsx: -------------------------------------------------------------------------------- 1 | import { useTheme } from '@mui/material'; 2 | import { Point } from '@types'; 3 | 4 | type Props = { 5 | visible: boolean; 6 | point: Point; 7 | }; 8 | 9 | export default ({ point, visible }: Props) => { 10 | const theme = useTheme(); 11 | 12 | return ( 13 | 22 | ); 23 | }; 24 | -------------------------------------------------------------------------------- /apps/server/prisma/schema/private-architecture.prisma: -------------------------------------------------------------------------------- 1 | model PrivateArchitecture { 2 | id Int @id @default(autoincrement()) 3 | title String @db.Char(50) 4 | authorId Int @map("author_id") 5 | architecture Json 6 | cost Float @default(0) 7 | createdAt DateTime @default(now()) @map("created_at") @db.Timestamp(0) 8 | updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamp(0) 9 | 10 | author User @relation(fields: [authorId], references: [id]) 11 | versions Version[] 12 | 13 | @@map("private_architecture") 14 | } 15 | -------------------------------------------------------------------------------- /apps/server/src/public-architecture/dto/create-public-architecture.dto.ts: -------------------------------------------------------------------------------- 1 | import { 2 | IsArray, 3 | IsNotEmpty, 4 | IsNumber, 5 | IsObject, 6 | IsOptional, 7 | IsString, 8 | } from 'class-validator'; 9 | 10 | export class CreatePublicArchitectureDto { 11 | @IsString() 12 | @IsNotEmpty() 13 | title: string; 14 | 15 | @IsObject() 16 | @IsNotEmpty() 17 | architecture: Record; 18 | 19 | @IsNumber() 20 | @IsNotEmpty() 21 | cost: number; 22 | 23 | @IsOptional() 24 | @IsArray() 25 | @IsString({ each: true }) 26 | tags?: string[]; 27 | } 28 | -------------------------------------------------------------------------------- /apps/client/src/models/ncloud/CloudFunction.ts: -------------------------------------------------------------------------------- 1 | import { GraphNode } from '@helpers/node'; 2 | import { Node } from '@types'; 3 | import { Networks, NetworksProp } from './Networks'; 4 | 5 | export interface CloudFunctionProp extends NetworksProp { 6 | //TODO: 7 | } 8 | 9 | export const CloudFunction: Node & { 10 | properties: CloudFunctionProp; 11 | } = { 12 | ...GraphNode, 13 | type: 'cloud-function', 14 | size: { 15 | '2d': { width: 90, height: 90 }, 16 | '3d': { width: 96, height: 113.438, offset: 12.5 }, 17 | }, 18 | properties: { 19 | ...Networks, 20 | }, 21 | }; 22 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vpc/models/GetVpcListRequest.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * VPC 목록 조회 요청 파라미터 3 | * @typedef {Object} GetVpcListRequest 4 | * @property {string} [regionCode] - 조회할 리전 코드 (Optional) 5 | * @property {string} [vpcStatusCode] - VPC 상태 코드 (Optional, INIT|CREATING|RUN|TERMTING) 6 | * @property {string} [vpcName] - VPC 이름으로 검색 (Optional) 7 | * @property {string[]} [vpcNoList] - VPC 번호 목록으로 검색 (Optional) 8 | */ 9 | export interface GetVpcListRequest { 10 | regionCode: string; 11 | vpcStatusCode?: string; 12 | vpcName?: string; 13 | vpcNoList?: string[]; 14 | responseFormatType?: string; 15 | } 16 | -------------------------------------------------------------------------------- /apps/hub/src/components/MyPageSidebar/item.tsx: -------------------------------------------------------------------------------- 1 | import Link from 'next/link'; 2 | 3 | export const SidebarItem = ({ 4 | name, 5 | href, 6 | segment, 7 | }: { 8 | name: string; 9 | href: string; 10 | segment?: string | null; 11 | }) => { 12 | const isActive = segment === href.split('/').at(-1); 13 | return ( 14 |
  • 15 | 19 | {name} 20 | 21 |
  • 22 | ); 23 | }; 24 | -------------------------------------------------------------------------------- /apps/server/prisma/schema/star.prisma: -------------------------------------------------------------------------------- 1 | model Star { 2 | id Int @id @default(autoincrement()) 3 | publicArchitectureId Int @map("public_architecture_id") 4 | userId Int @map("user_id") 5 | createdAt DateTime @default(now()) @map("created_at") @db.Timestamp(0) 6 | 7 | publicArchitecture PublicArchitecture @relation(fields: [publicArchitectureId], references: [id]) 8 | user User @relation(fields: [userId], references: [id]) 9 | 10 | @@unique([publicArchitectureId, userId], name: "unique_star") 11 | @@map("star") 12 | } 13 | -------------------------------------------------------------------------------- /apps/server/src/cloud/cloud.controller.spec.ts: -------------------------------------------------------------------------------- 1 | import { Test, TestingModule } from '@nestjs/testing'; 2 | import { CloudController } from './cloud.controller'; 3 | 4 | describe('CloudController', () => { 5 | let controller: CloudController; 6 | 7 | beforeEach(async () => { 8 | const module: TestingModule = await Test.createTestingModule({ 9 | controllers: [CloudController], 10 | }).compile(); 11 | 12 | controller = module.get(CloudController); 13 | }); 14 | 15 | it('should be defined', () => { 16 | expect(controller).toBeDefined(); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/login-key/CreateLoginKeyResponse.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 로그인키 생성 응답 3 | * @see {@link https://api.ncloud-docs.com/docs/compute-vserver-server-loginkey-createloginkey} 4 | * @example 5 | * { 6 | * "requestId": "7dbc947d-669d-4245-9d68-16d1983c4dc3", 7 | * "returnCode": 0, 8 | * "returnMessage": "success", 9 | * "keyName": "test-***", 10 | * "privateKey": "-----BEGIN RSA PRIVATE KEY-----\n..." 11 | * } 12 | */ 13 | type CreateLoginKeyResponse = { 14 | requestId: string; 15 | returnCode: number; 16 | returnMessage: string; 17 | keyName: string; 18 | privateKey: string; 19 | }; 20 | -------------------------------------------------------------------------------- /apps/hub/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.* 7 | .yarn/* 8 | !.yarn/patches 9 | !.yarn/plugins 10 | !.yarn/releases 11 | !.yarn/versions 12 | 13 | # testing 14 | /coverage 15 | 16 | # next.js 17 | /.next/ 18 | /out/ 19 | 20 | # production 21 | /build 22 | 23 | # misc 24 | .DS_Store 25 | *.pem 26 | 27 | # debug 28 | npm-debug.log* 29 | yarn-debug.log* 30 | yarn-error.log* 31 | 32 | # env files (can opt-in for committing if needed) 33 | .env* 34 | 35 | # vercel 36 | .vercel 37 | 38 | # typescript 39 | *.tsbuildinfo 40 | next-env.d.ts 41 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/login-key/GetLoginKeyListRequest.ts: -------------------------------------------------------------------------------- 1 | export type GetLoginKeyListRequest = { 2 | /** 3 | * 조회할 키 이름 4 | * 키 이름으로 필터링하여 검색 가능 5 | */ 6 | keyName?: string; 7 | 8 | /** 9 | * 페이징된 결과의 페이지 번호 10 | * 결과값을 pageNo, pageSize를 이용하여 페이징 처리 가능 11 | */ 12 | pageNo?: number; 13 | 14 | /** 15 | * 페이징 시 보여줄 각 페이지 사이즈 16 | * 결과값을 pageNo, pageSize를 이용하여 페이징 처리 가능 17 | * pageNo 입력시 반드시 입력 필요 18 | */ 19 | pageSize?: number; 20 | 21 | /** 22 | * 응답 결과의 포맷 타입 23 | * @default xml 24 | */ 25 | responseFormatType?: 'xml' | 'json'; 26 | }; 27 | -------------------------------------------------------------------------------- /infra/modules/vpc_subnet/variables.tf: -------------------------------------------------------------------------------- 1 | variable "vpc_name" { 2 | description = "(Optional) The name to create. If omitted, Terraform will assign a random, unique name." 3 | type = string 4 | default = null 5 | } 6 | 7 | variable "ipv4_cidr_block" { 8 | description = "(Required) The CIDR block of the VPC. The range must be between /16 and/28 within the private band(10.0.0/8,172.16.0.0/12,192.168.0.0/16)." 9 | type = string 10 | } 11 | 12 | variable "subnets" { 13 | type = list(object({ 14 | subnet = string 15 | zone = string 16 | name = string 17 | subnet_type = string 18 | usage_type = string 19 | })) 20 | 21 | default = [] 22 | } -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vpc/models/Vpc.ts: -------------------------------------------------------------------------------- 1 | import { CommonCode } from './CommonCode'; 2 | /** 3 | * VPC 정보를 나타내는 인터페이스 4 | * @typedef {Object} Vpc 5 | * @property {string} vpcNo - VPC 번호 6 | * @property {string} vpcName - VPC 이름 (3~30자, 영문 소문자/숫자/'-' 허용) 7 | * @property {string} ipv4CidrBlock - VPC의 사설 IPv4 주소 범위 8 | * @property {CommonCode} vpcStatus - VPC 상태 정보 9 | * @property {string} regionCode - VPC가 위치한 리전 코드 10 | * @property {string} createDate - 생성 일시 11 | */ 12 | export interface Vpc { 13 | vpcNo: string; 14 | vpcName: string; 15 | ivp4CidrBlock: string; 16 | vpcStatus: CommonCode; 17 | regionCode: string; 18 | createDate: Date; 19 | } 20 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/login-key/ImportLoginKeyRequest.ts: -------------------------------------------------------------------------------- 1 | type ImportLoginKeyRequest = { 2 | /** 3 | * 생성할 키 이름 4 | * Default : NAVER Cloud Platform가 자동으로 부여 5 | * Min : 3, Max : 30 6 | * 영어, 숫자, "-"의 특수문자만 허용하며 영어로 시작함 7 | * 영어 또는 숫자로 끝남 8 | */ 9 | keyName?: string; 10 | 11 | /** 12 | * import 할 공개 키 13 | * ssh-keygen -t rsa -C "key-name" -f ~/.ssh/key-name 로 생성한 public 키 14 | * ssh-keygen 버전에 따라 다음 옵션들이 추가로 필요(-b 2048 -m PEM) 15 | */ 16 | publicKey: string; 17 | 18 | /** 19 | * 응답 결과의 포맷 타입 20 | * @default xml 21 | */ 22 | responseFormatType?: 'xml' | 'json'; 23 | }; 24 | -------------------------------------------------------------------------------- /apps/server/src/ncloud-resource/ncloud-resource.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { Test, TestingModule } from '@nestjs/testing'; 2 | import { NcloudResourcesService } from './ncloud-resource.service'; 3 | 4 | describe('NcloudResourcesService', () => { 5 | let service: NcloudResourcesService; 6 | 7 | beforeEach(async () => { 8 | const module: TestingModule = await Test.createTestingModule({ 9 | providers: [NcloudResourcesService], 10 | }).compile(); 11 | 12 | service = module.get(NcloudResourcesService); 13 | }); 14 | 15 | it('should be defined', () => { 16 | expect(service).toBeDefined(); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /apps/server/src/types/query-params.dto.ts: -------------------------------------------------------------------------------- 1 | import { Type } from 'class-transformer'; 2 | import { IsInt, IsOptional, IsString, Min } from 'class-validator'; 3 | 4 | export class QueryParamsDto { 5 | @IsOptional() 6 | @IsInt() 7 | @Min(1) 8 | @Type(() => Number) 9 | page?: number = 1; 10 | 11 | @IsOptional() 12 | @IsInt() 13 | @Min(0) 14 | @Type(() => Number) 15 | limit?: number = 10; 16 | 17 | @IsOptional() 18 | @IsString() 19 | search?: string; 20 | 21 | @IsOptional() 22 | @IsString() // #TODO add enum 23 | sort?: string; 24 | 25 | @IsOptional() 26 | @IsString() // #TODO add enum 27 | order?: string; 28 | } 29 | -------------------------------------------------------------------------------- /apps/hub/src/app/my/layout.tsx: -------------------------------------------------------------------------------- 1 | import { MyPageSidebar } from '@/components/MyPageSidebar'; 2 | import React from 'react'; 3 | 4 | export default function MyPageLayout({ 5 | children, 6 | }: Readonly<{ children: React.ReactNode }>) { 7 | return ( 8 | <> 9 | 17 |
    18 | {children} 19 |
    20 | 21 | ); 22 | } 23 | -------------------------------------------------------------------------------- /apps/server/src/my/test/my.controller.spec.ts: -------------------------------------------------------------------------------- 1 | import { Test, TestingModule } from '@nestjs/testing'; 2 | import { MyController } from '../my.controller'; 3 | import { MyService } from '../my.service'; 4 | 5 | describe('MyController', () => { 6 | let controller: MyController; 7 | 8 | beforeEach(async () => { 9 | const module: TestingModule = await Test.createTestingModule({ 10 | controllers: [MyController], 11 | providers: [MyService], 12 | }).compile(); 13 | 14 | controller = module.get(MyController); 15 | }); 16 | 17 | it('should be defined', () => { 18 | expect(controller).toBeDefined(); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /apps/client/src/models/ncloud/ContainerRegistry.ts: -------------------------------------------------------------------------------- 1 | import { GraphNode } from '@helpers/node'; 2 | import { Node } from '@types'; 3 | import { Networks, NetworksProp } from './Networks'; 4 | 5 | export interface ContainerRegistryProp extends NetworksProp { 6 | //TODO: 7 | } 8 | 9 | export const ContainerRegistry: Node & { 10 | properties: ContainerRegistryProp; 11 | } = { 12 | ...GraphNode, 13 | type: 'container-registry', 14 | size: { 15 | '2d': { width: 360, height: 360 }, 16 | '3d': { width: 512, height: 296, offset: 37 }, 17 | }, 18 | properties: { 19 | ...Networks, 20 | }, 21 | }; 22 | 23 | export const ContainerRegistryRequiredFields = {}; 24 | -------------------------------------------------------------------------------- /packages/terraform/model/NCloudObjectStorageBucket.ts: -------------------------------------------------------------------------------- 1 | import { ObjectStorageBucket } from '../interface/ObjectStorageBucket'; 2 | import { ResourcePriority } from '../enum/ResourcePriority'; 3 | 4 | export class NCloudObjectStorageBucket implements ObjectStorageBucket { 5 | bucketName: string; 6 | serviceType: string; 7 | priority: ResourcePriority; 8 | constructor(json: any) { 9 | this.serviceType = 'ncloud_objectstorage_bucket'; 10 | this.priority = ResourcePriority.OBJECT_STORAGE_BUCKET; 11 | this.bucketName = json.bucketName; 12 | } 13 | getProperties() { 14 | return { 15 | bucket_name: this.bucketName, 16 | }; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /apps/hub/src/components/ArchitectureBoard/ArchitectureList.tsx: -------------------------------------------------------------------------------- 1 | import { ArchitectureItem } from './ArchitectureItem'; 2 | 3 | export const ArchitectureList = ({ data }: { data: Array }) => { 4 | if (!data?.length) { 5 | return ( 6 |
    7 |
    8 | No architectures found. 9 |
    10 |
    11 | ); 12 | } 13 | 14 | return ( 15 |
    16 | {data.map((item) => ( 17 | 18 | ))} 19 |
    20 | ); 21 | }; 22 | -------------------------------------------------------------------------------- /apps/server/src/auth/auth.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable, UnauthorizedException } from '@nestjs/common'; 2 | import { JwtService } from '@nestjs/jwt'; 3 | import { UserService } from 'src/user/user.service'; 4 | 5 | @Injectable() 6 | export class AuthService { 7 | constructor( 8 | private readonly userService: UserService, 9 | private readonly jwtService: JwtService, 10 | ) {} 11 | 12 | async login() { 13 | const user = await this.userService.getTestUser(); 14 | if (!user) { 15 | throw new UnauthorizedException(); 16 | } 17 | const payload = { sub: user.id, username: user.name }; 18 | return this.jwtService.sign(payload); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /apps/hub/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:20 AS development 2 | WORKDIR /development 3 | COPY ./pnpm-lock.yaml ./apps/hub/package*.json . 4 | RUN npm install -g pnpm && pnpm install 5 | 6 | FROM node:20 AS build 7 | WORKDIR /build 8 | COPY --from=development /development/node_modules/ ./node_modules 9 | COPY ./apps/hub/ . 10 | RUN npm run build 11 | 12 | FROM node:20-alpine AS production 13 | WORKDIR /app 14 | RUN mkdir -p /app/server 15 | COPY --from=build /build/.next/standalone/ ./standalone/ 16 | COPY --from=build /build/.next/static/ ./standalone/.next/static 17 | COPY --from=build /build/public/ ./standalone/public 18 | 19 | ENV BACK_URL=https://api.cloudcanvas.kro.kr 20 | ENTRYPOINT ["sh", "-c", "node standalone/server.js"] 21 | -------------------------------------------------------------------------------- /apps/server/src/user/test/user.controller.spec.ts: -------------------------------------------------------------------------------- 1 | import { Test, TestingModule } from '@nestjs/testing'; 2 | import { UserController } from '../user.controller'; 3 | import { UserService } from '../user.service'; 4 | 5 | describe('UserController', () => { 6 | let controller: UserController; 7 | 8 | beforeEach(async () => { 9 | const module: TestingModule = await Test.createTestingModule({ 10 | controllers: [UserController], 11 | providers: [UserService], 12 | }).compile(); 13 | 14 | controller = module.get(UserController); 15 | }); 16 | 17 | it('should be defined', () => { 18 | expect(controller).toBeDefined(); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/common/getRegionListResponse.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * getRegionList 응답 3 | * @see {@link } 4 | * @example 5 | * { 6 | * "requestId": "ac39d0d1-6982-4f0b-8c18-47ca9100d51b", 7 | * "returnCode": "0", 8 | * "returnMessage": "success", 9 | * "totalRows": 1, 10 | * "regionList": [ 11 | * { 12 | * "regionCode": "KR", 13 | * "regionName": "Korea" 14 | * } 15 | * ] 16 | * } 17 | */ 18 | export type GetRegionListResponse = { 19 | requestId: string; 20 | returnCode: string; 21 | returnMessage: string; 22 | totalRows: number; 23 | regionList: Array<{ 24 | regionCode: string; 25 | regionName: string; 26 | }>; 27 | }; 28 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/VpcApi.ts: -------------------------------------------------------------------------------- 1 | import { ApiClient } from './ApiClient'; 2 | import { ApiKeyCredentials } from './types'; 3 | 4 | export class VpcApi { 5 | private client: ApiClient; 6 | private readonly resourcePath: string; 7 | constructor(apiKey?: ApiKeyCredentials) { 8 | this.resourcePath = '/vpc/v2'; 9 | this.client = new ApiClient(apiKey); 10 | } 11 | 12 | async createVpc(params: { 13 | regionCode: string; 14 | vpcName: string; 15 | ipv4CidrBlock: string; 16 | }) { 17 | return await this.client.request({ 18 | method: 'POST', 19 | url: this.resourcePath + '/createVpc', 20 | params, 21 | }); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /packages/cloud-graph/src/stories-example/assets/youtube.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/common/getServerSpecDetailRequest.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * getServerSpecDetail 요청 파라미터 3 | * @see {@link } 4 | */ 5 | export type GetServerSpecDetailRequest = { 6 | /** 7 | * 리전 코드 8 | * - 서버 스펙이 조회될 리전(Region) 결정 가능 9 | * - regionCode는 {@link } getRegionList 액션을 통해 획득 가능 10 | * - Default : getRegionList 조회 결과의 첫 번째 리전을 선택 11 | */ 12 | regionCode?: string; 13 | 14 | /** 15 | * 조회할 서버 스펙 코드 16 | * - serverSpecCode는 {@link } getServerSpecList 액션을 통해 획득 가능 17 | */ 18 | serverSpecCode: string; 19 | 20 | /** 21 | * 응답 결과의 포맷 타입 22 | * - Options : xml | json 23 | * - Default : xml 24 | */ 25 | responseFormatType?: 'xml' | 'json'; 26 | }; 27 | -------------------------------------------------------------------------------- /apps/hub/src/app/layout.tsx: -------------------------------------------------------------------------------- 1 | import type { Metadata } from 'next'; 2 | import './globals.css'; 3 | import { GlobalHeader } from '@/components/GlobalHeader'; 4 | import { gamjaFlower } from './fonts'; 5 | 6 | export const metadata: Metadata = { 7 | title: 'Cloud Canvas', 8 | description: 'Draw your cloud architecture with ease', 9 | }; 10 | 11 | export default function RootLayout({ 12 | children, 13 | }: Readonly<{ children: React.ReactNode }>) { 14 | return ( 15 | 16 | 17 | 18 |
    {children}
    19 | 20 | 21 | ); 22 | } 23 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/price/models/GetProductListRequest.ts: -------------------------------------------------------------------------------- 1 | export interface GetProductListRequest { 2 | /** 3 | * 페이지 번호 4 | */ 5 | pageNo?: number; 6 | /** 7 | * 페이지 크기(1000 이하, 기본값 1000) 8 | */ 9 | pageSize?: number; 10 | /** 11 | * 리전 코드 12 | */ 13 | regionCode: string; 14 | /** 15 | * 상품 품목 종류 코드 16 | */ 17 | productItemKindCode?: string; 18 | /** 19 | * 상품 카테고리 코드 20 | */ 21 | productCategoryCode?: string; 22 | /** 23 | * 상품 코드 24 | */ 25 | productCode?: string; 26 | /** 27 | * 상품명 28 | */ 29 | productName?: string; 30 | /** 31 | * 응답 결과의 형식 32 | */ 33 | responseFormatType?: 'xml' | 'json'; 34 | } 35 | -------------------------------------------------------------------------------- /packages/terraform/util/provider.ts: -------------------------------------------------------------------------------- 1 | import { NCloudProvider } from '../model/NCloudProvider'; 2 | import { CloudCanvasNode } from '../interface/CloudCanvasNode'; 3 | 4 | export const createProvider = (region: string): NCloudProvider => 5 | new NCloudProvider({ 6 | accessKey: 'var.access_key', 7 | secretKey: 'var.secret_key', 8 | region: region, 9 | site: 'public', 10 | alias: region.toLowerCase(), 11 | }); 12 | 13 | export const collectRegions = (nodes: any[]): Set => { 14 | const regions = new Set(); 15 | nodes.forEach((node) => { 16 | if (node.properties?.region) { 17 | regions.add(node.properties.region); 18 | } 19 | }); 20 | return regions; 21 | }; 22 | -------------------------------------------------------------------------------- /apps/server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "declaration": true, 5 | "removeComments": true, 6 | "emitDecoratorMetadata": true, 7 | "experimentalDecorators": true, 8 | "allowSyntheticDefaultImports": true, 9 | "target": "ES2021", 10 | "sourceMap": true, 11 | "outDir": "./dist", 12 | "baseUrl": "./", 13 | "incremental": true, 14 | "skipLibCheck": true, 15 | "strictNullChecks": false, 16 | "noImplicitAny": false, 17 | "strictBindCallApply": false, 18 | "forceConsistentCasingInFileNames": false, 19 | "noFallthroughCasesInSwitch": false, 20 | "resolveJsonModule": true 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/price/models/NcloudResponse.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 기본 응답 객체 3 | */ 4 | export interface NcloudResponse { 5 | /** 6 | * UUID 형태의 요청 ID. 7 | * 8 | * Required 9 | */ 10 | requestId: string; 11 | 12 | /** 13 | * 요청에 대한 응답 코드 14 | * 15 | * @see {@link https://api.ncloud-docs.com/docs/common-ncpapi#3%EC%9D%91%EB%8B%B5%EC%83%81%ED%83%9C%EC%BD%94%EB%93%9C}
    16 | * 17 | * Required 18 | */ 19 | returnCode: string; 20 | 21 | /** 22 | * 요청에 대한 응답 메시지 23 | * 24 | * @see {@link https://api.ncloud-docs.com/docs/common-ncpapi#3%EC%9D%91%EB%8B%B5%EC%83%81%ED%83%9C%EC%BD%94%EB%93%9C}
    25 | * 26 | * Required 27 | */ 28 | returnMessage: string; 29 | } 30 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/subnet/models/NcloudResponse.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 기본 응답 객체 3 | */ 4 | export interface NcloudResponse { 5 | /** 6 | * UUID 형태의 요청 ID. 7 | * 8 | * Required 9 | */ 10 | requestId: string; 11 | 12 | /** 13 | * 요청에 대한 응답 코드 14 | * 15 | * @see {@link https://api.ncloud-docs.com/docs/common-ncpapi#3%EC%9D%91%EB%8B%B5%EC%83%81%ED%83%9C%EC%BD%94%EB%93%9C}
    16 | * 17 | * Required 18 | */ 19 | returnCode: string; 20 | 21 | /** 22 | * 요청에 대한 응답 메시지 23 | * 24 | * @see {@link https://api.ncloud-docs.com/docs/common-ncpapi#3%EC%9D%91%EB%8B%B5%EC%83%81%ED%83%9C%EC%BD%94%EB%93%9C}
    25 | * 26 | * Required 27 | */ 28 | returnMessage: string; 29 | } 30 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vpc/models/VpcList.ts: -------------------------------------------------------------------------------- 1 | import { Vpc } from './Vpc'; 2 | 3 | /** 4 | * VPC 목록 정보 5 | * @interface VpcList 6 | * @property {number} totalRows - 전체 VPC 개수 7 | * @property {Vpc[]} vpcList - VPC 목록 8 | * 9 | * @example 10 | * { 11 | * "totalRows": 1, 12 | * "vpcList": [ 13 | * { 14 | * "vpcNo": "1234", 15 | * "vpcName": "test-vpc", 16 | * "ipv4CidrBlock": "10.0.0.0/16", 17 | * "vpcStatus": { 18 | * "code": "RUN", 19 | * "codeName": "run" 20 | * }, 21 | * "regionCode": "KR", 22 | * "createDate": "2020-07-16T22:23:50+0900" 23 | * } 24 | * ] 25 | * } 26 | */ 27 | export interface VpcList { 28 | totalRows: number; 29 | vpcList: Vpc[]; 30 | } 31 | -------------------------------------------------------------------------------- /apps/server/src/auth/auth.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { PassportModule } from '@nestjs/passport'; 3 | import { AuthService } from './auth.service'; 4 | import { AuthController } from './auth.controller'; 5 | import { UserModule } from 'src/user/user.module'; 6 | import { JwtModule } from '@nestjs/jwt'; 7 | import { JwtStrategy } from './strategies/jwt.strategy'; 8 | 9 | @Module({ 10 | imports: [ 11 | UserModule, 12 | PassportModule, 13 | JwtModule.register({ 14 | global: true, 15 | secret: 'JWT_SECRET', 16 | signOptions: { expiresIn: '1d' }, 17 | }), 18 | ], 19 | controllers: [AuthController], 20 | providers: [AuthService, JwtStrategy], 21 | }) 22 | export class AuthModule {} 23 | -------------------------------------------------------------------------------- /apps/server/src/auth/strategies/jwt.strategy.ts: -------------------------------------------------------------------------------- 1 | import { ExtractJwt, Strategy } from 'passport-jwt'; 2 | import { PassportStrategy } from '@nestjs/passport'; 3 | import { Injectable } from '@nestjs/common'; 4 | 5 | @Injectable() 6 | export class JwtStrategy extends PassportStrategy(Strategy) { 7 | constructor() { 8 | super({ 9 | jwtFromRequest: ExtractJwt.fromExtractors([ 10 | (req) => { 11 | return req?.cookies?.Authentication; 12 | }, 13 | ]), 14 | ignoreExpiration: false, 15 | secretOrKey: 'JWT_SECRET', 16 | }); 17 | } 18 | 19 | async validate(payload: any) { 20 | const { sub, username } = payload; 21 | return { id: sub, name: username }; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /packages/cloud-graph/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", 4 | "target": "ES2022", 5 | "lib": ["ES2023"], 6 | "module": "ESNext", 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "isolatedModules": true, 13 | "moduleDetection": "force", 14 | "noEmit": true, 15 | 16 | /* Linting */ 17 | "strict": true, 18 | "noUnusedLocals": true, 19 | "noUnusedParameters": true, 20 | "noFallthroughCasesInSwitch": true, 21 | "noUncheckedSideEffectImports": true 22 | }, 23 | "include": ["vite.config.ts"] 24 | } 25 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/common/getHypervisorTypeListResponse.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * getHypervisorTypeList 응답 3 | * @see {@link } 4 | * @example 5 | * { 6 | * "requestId": "", 7 | * "returnCode": "0", 8 | * "returnMessage": "success", 9 | * "totalRows": 2, 10 | * "hypervisorTypeList": [ 11 | * { 12 | * "code": "XEN", 13 | * "codeName": "XEN" 14 | * }, 15 | * { 16 | * "code": "KVM", 17 | * "codeName": "KVM" 18 | * } 19 | * ] 20 | * } 21 | */ 22 | export type GetHypervisorTypeListResponse = { 23 | requestId: string; 24 | returnCode: string; 25 | returnMessage: string; 26 | totalRows: number; 27 | hypervisorTypeList: Array<{ 28 | code: string; 29 | codeName: string; 30 | }>; 31 | }; 32 | -------------------------------------------------------------------------------- /apps/hub/tailwind.config.ts: -------------------------------------------------------------------------------- 1 | import type { Config } from 'tailwindcss'; 2 | 3 | export default { 4 | content: [ 5 | './src/pages/**/*.{js,ts,jsx,tsx,mdx}', 6 | './src/components/**/*.{js,ts,jsx,tsx,mdx}', 7 | './src/app/**/*.{js,ts,jsx,tsx,mdx}', 8 | './src/ui/**/*.{js,ts,jsx,tsx,mdx}', 9 | ], 10 | theme: { 11 | extend: { 12 | fontFamily: { 13 | gamjaFlower: ['var(--font-gamja-flower)', 'cursive'], 14 | }, 15 | colors: { 16 | background: 'var(--background)', 17 | foreground: 'var(--foreground)', 18 | }, 19 | spacing: { 20 | '8xl': '90rem', 21 | }, 22 | }, 23 | }, 24 | plugins: [], 25 | } satisfies Config; 26 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/public-ip/GetPublicIpTargetServerInstanceListRequest.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 공인 IP 인스턴스를 할당 가능한 서버 인스턴스 리스트 조회 요청 3 | * @see {@link https://api.ncloud-docs.com/docs/compute-vserver-publicip-getpubliciptargetserverinstancelist} 4 | */ 5 | export type GetPublicIpTargetServerInstanceListRequest = { 6 | /** 7 | * 리전 코드 8 | * 공인 IP 인스턴스를 할당 가능한 서버 인스턴스 리스트가 조회될 리전(Region) 결정 가능 9 | * regionCode는 {@link https://api.ncloud-docs.com/docs/compute-vserver-server-common-getregionlist} 액션을 통해 획득 가능 10 | * Default : getRegionList 조회 결과의 첫 번째 리전을 선택 11 | */ 12 | regionCode?: string; 13 | 14 | /** 15 | * 응답 결과의 포맷 타입 16 | * Options : xml | json 17 | * Default : xml 18 | */ 19 | responseFormatType?: 'xml' | 'json'; 20 | }; 21 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/server-image/GetServerImageDetailRequest.ts: -------------------------------------------------------------------------------- 1 | type GetServerImageDetailRequest = { 2 | /** 3 | * 리전 코드 4 | * 서버 이미지가 조회될 리전(Region) 결정 가능 5 | * regionCode는 getRegionList 액션을 통해 획득 가능 6 | * @link https://api.ncloud-docs.com/docs/compute-vserver-server-common-getregionlist 7 | * @default getRegionList 조회 결과의 첫 번째 리전을 선택 8 | */ 9 | regionCode?: string; 10 | 11 | /** 12 | * 조회할 서버 이미지 번호 13 | * serverImageNo는 getServerImageList 액션을 통해 획득 가능 14 | * @link https://api.ncloud-docs.com/docs/compute-vserver-serverimage-getserverimagelist 15 | */ 16 | serverImageNo: string; 17 | 18 | /** 19 | * 응답 결과의 포맷 타입 20 | * @default xml 21 | */ 22 | responseFormatType?: 'xml' | 'json'; 23 | }; 24 | -------------------------------------------------------------------------------- /docker-composes/cloud-canvas-back.yml: -------------------------------------------------------------------------------- 1 | services: 2 | back: 3 | image: t84ar7xr.kr.private-ncr.ntruss.com/back:dev 4 | container_name: back 5 | environment: 6 | NODE_ENV: production 7 | DATABASE_URL: ${DATABASE_URL} 8 | NCLOUD_ACCESS_KEY: ${NCLOUD_ACCESS_KEY} 9 | NCLOUD_SECRET_KEY: ${NCLOUD_SECRET_KEY} 10 | REDIS_HOST: ${REDIS_HOST} 11 | REDIS_PORT: ${REDIS_PORT} 12 | ports: 13 | - '3000:3000' 14 | entrypoint: sh -c "cd apps/server && npx prisma migrate reset --force && node ./dist/src/main.js" 15 | networks: 16 | - cloud-canvas-network 17 | restart: unless-stopped 18 | pull_policy: always 19 | networks: 20 | cloud-canvas-network: 21 | driver: bridge 22 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/server/GetServerInstanceDetailRequest.ts: -------------------------------------------------------------------------------- 1 | type GetServerInstanceDetailRequest = { 2 | /** 3 | * 리전 코드 4 | * 서버 인스턴스 상세 정보가 조회될 리전(Region)을 결정 가능 5 | * regionCode는 getRegionList 액션을 통해 획득 가능 6 | * @link https://api.ncloud-docs.com/docs/compute-vserver-server-common-getregionlist 7 | * @default getRegionList 조회 결과의 첫 번째 리전을 선택 8 | */ 9 | regionCode?: string; 10 | 11 | /** 12 | * 조회할 서버 인스턴스 번호 13 | * serverInstanceNo는 getServerInstanceList 액션을 통해 획득 가능 14 | * @link https://api.ncloud-docs.com/docs/compute-vserver-server-getserverinstancelist 15 | */ 16 | serverInstanceNo: string; 17 | 18 | /** 19 | * 응답 결과의 포맷 타입 20 | * @default xml 21 | */ 22 | responseFormatType?: 'xml' | 'json'; 23 | }; 24 | -------------------------------------------------------------------------------- /apps/client/src/contexts/SvgContext.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | createContext, 3 | PropsWithChildren, 4 | RefObject, 5 | useContext, 6 | useRef, 7 | } from 'react'; 8 | 9 | type SvgContextProps = { 10 | svgRef: RefObject; 11 | }; 12 | 13 | const SvgContext = createContext(undefined); 14 | 15 | export const SvgProvider = ({ children }: PropsWithChildren) => { 16 | const svgRef = useRef(null); 17 | 18 | return ( 19 | {children} 20 | ); 21 | }; 22 | 23 | export const useSvgContext = () => { 24 | const context = useContext(SvgContext); 25 | if (!context) { 26 | throw new Error('SvgContext: context is undefined'); 27 | } 28 | return context; 29 | }; 30 | -------------------------------------------------------------------------------- /apps/client/src/models/ncloud/ObjectStorage.ts: -------------------------------------------------------------------------------- 1 | import { GraphNode } from '@helpers/node'; 2 | import { Node } from '@types'; 3 | import { Networks, NetworksProp } from './Networks'; 4 | 5 | export interface ObjectStorageProp extends NetworksProp { 6 | bucketName: string | null; 7 | } 8 | 9 | export const ObjectStorage: Node & { 10 | properties: ObjectStorageProp; 11 | } = { 12 | ...GraphNode, 13 | type: 'object-storage', 14 | size: { 15 | '2d': { width: 90, height: 90 }, 16 | '3d': { width: 100.626, height: 115.695, offset: 20 }, 17 | }, 18 | properties: { 19 | ...Networks, 20 | bucketName: null, 21 | }, 22 | }; 23 | 24 | export const ObjectStorageRequiredFields = { 25 | bucketName: true, 26 | vpc: true, 27 | subnet: true, 28 | region: true, 29 | }; 30 | -------------------------------------------------------------------------------- /apps/hub/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hub", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "next": "15.0.3", 13 | "react": "19.0.0-rc-66855b96-20241106", 14 | "react-dom": "19.0.0-rc-66855b96-20241106", 15 | "swr": "^2.2.5" 16 | }, 17 | "devDependencies": { 18 | "@faker-js/faker": "^9.2.0", 19 | "@types/node": "^20", 20 | "@types/react": "^18", 21 | "@types/react-dom": "^18", 22 | "eslint": "^8", 23 | "eslint-config-next": "15.0.3", 24 | "postcss": "^8", 25 | "tailwindcss": "^3.4.1", 26 | "typescript": "^5" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /apps/hub/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2017", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "noEmit": true, 9 | "esModuleInterop": true, 10 | "module": "esnext", 11 | "moduleResolution": "bundler", 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "jsx": "preserve", 15 | "incremental": true, 16 | "plugins": [ 17 | { 18 | "name": "next" 19 | } 20 | ], 21 | "paths": { 22 | "@/*": ["./src/*"] 23 | } 24 | }, 25 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], 26 | "exclude": ["node_modules"] 27 | } 28 | -------------------------------------------------------------------------------- /apps/server/prisma/schema/ncloud-server-resoruce.prisma: -------------------------------------------------------------------------------- 1 | model NcloudServerResource { 2 | id Int @id @default(autoincrement()) 3 | serverResourceTypeId Int @map("server_resource_type_id") 4 | serverSpecCode String @map("server_spec_code") @db.VarChar(50) 5 | productName String @map("product_name") @db.VarChar(200) 6 | hourCost Float @map("hour_cost") 7 | monthCost Float @map("month_cost") 8 | createdAt DateTime @default(now()) @map("created_at") @db.Timestamp(0) 9 | updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamp(0) 10 | 11 | serverResoruceType NcloudServerResourceType @relation(fields: [serverResourceTypeId], references: [id]) 12 | 13 | @@map("ncloud_server_resource") 14 | } 15 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/placement-group/DeletePlacementGroupRequest.ts: -------------------------------------------------------------------------------- 1 | type DeletePlacementGroupRequest = { 2 | /** 3 | * 리전 코드 4 | * 삭제할 물리 배치 그룹의 리전(Region) 결정 가능 5 | * regionCode는 getRegionList 액션을 통해 획득 가능 6 | * @link https://api.ncloud-docs.com/docs/compute-vserver-server-common-getregionlist 7 | * @default getRegionList 조회 결과의 첫 번째 리전을 선택 8 | */ 9 | regionCode?: string; 10 | 11 | /** 12 | * 삭제할 물리 배치 그룹 번호 13 | * placementGroupNo는 getPlacementGroupList 액션을 통해 획득 가능 14 | * @link https://api.ncloud-docs.com/docs/compute-vserver-server-placementgroup-getplacementgrouplist 15 | */ 16 | placementGroupNo: string; 17 | 18 | /** 19 | * 응답 결과의 포맷 타입 20 | * @default xml 21 | */ 22 | responseFormatType?: 'xml' | 'json'; 23 | }; 24 | -------------------------------------------------------------------------------- /packages/terraform/util/generator.ts: -------------------------------------------------------------------------------- 1 | import { formatProperties } from './formatter'; 2 | 3 | export const generateTerraformBlock = ( 4 | providerSource: string, 5 | version: string, 6 | ): string => ` 7 | terraform { 8 | required_providers { 9 | ncloud = { 10 | source = "${providerSource}" 11 | } 12 | } 13 | required_version = "${version}" 14 | }`; 15 | 16 | export const generateProviderBlock = ( 17 | name: string, 18 | properties: { [key: string]: any }, 19 | ): string => ` 20 | provider "${name}" { 21 | ${formatProperties(properties)} 22 | }`; 23 | 24 | export const generateResourceBlock = ( 25 | serviceType: string, 26 | name: string, 27 | properties: { [key: string]: any }, 28 | ): string => ` 29 | resource "${serviceType}" "${name}" { 30 | ${formatProperties(properties)} 31 | }`; 32 | -------------------------------------------------------------------------------- /packages/cloud-graph/src/stories-example/header.css: -------------------------------------------------------------------------------- 1 | .storybook-header { 2 | display: flex; 3 | justify-content: space-between; 4 | align-items: center; 5 | border-bottom: 1px solid rgba(0, 0, 0, 0.1); 6 | padding: 15px 20px; 7 | font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif; 8 | } 9 | 10 | .storybook-header svg { 11 | display: inline-block; 12 | vertical-align: top; 13 | } 14 | 15 | .storybook-header h1 { 16 | display: inline-block; 17 | vertical-align: top; 18 | margin: 6px 0 6px 10px; 19 | font-weight: 700; 20 | font-size: 20px; 21 | line-height: 1; 22 | } 23 | 24 | .storybook-header button + button { 25 | margin-left: 10px; 26 | } 27 | 28 | .storybook-header .welcome { 29 | margin-right: 10px; 30 | color: #333; 31 | font-size: 14px; 32 | } 33 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/placement-group/GetPlacementGroupDetailRequest.ts: -------------------------------------------------------------------------------- 1 | type GetPlacementGroupDetailRequest = { 2 | /** 3 | * 리전 코드 4 | * 물리 배치 그룹 상세 정보가 조회될 리전(Region) 결정 가능 5 | * regionCode는 getRegionList 액션을 통해 획득 가능 6 | * @link https://api.ncloud-docs.com/docs/compute-vserver-server-common-getregionlist 7 | * @default getRegionList 조회 결과의 첫 번째 리전을 선택 8 | */ 9 | regionCode?: string; 10 | 11 | /** 12 | * 물리 배치 그룹 번호 13 | * placementGroupNo는 getPlacementGroupList 액션을 통해 획득 가능 14 | * @link https://api.ncloud-docs.com/docs/compute-vserver-server-placementgroup-getplacementgrouplist 15 | */ 16 | placementGroupNo: string; 17 | 18 | /** 19 | * 응답 결과의 포맷 타입 20 | * @default xml 21 | */ 22 | responseFormatType?: 'xml' | 'json'; 23 | }; 24 | -------------------------------------------------------------------------------- /apps/server/src/app.controller.spec.ts: -------------------------------------------------------------------------------- 1 | import { Test, TestingModule } from '@nestjs/testing'; 2 | import { AppController } from './app.controller'; 3 | import { AppService } from './app.service'; 4 | import { describe, beforeEach, it, expect } from 'vitest'; 5 | 6 | describe('AppController', () => { 7 | let appController: AppController; 8 | 9 | beforeEach(async () => { 10 | const app: TestingModule = await Test.createTestingModule({ 11 | controllers: [AppController], 12 | providers: [AppService], 13 | }).compile(); 14 | 15 | appController = app.get(AppController); 16 | }); 17 | 18 | describe('root', () => { 19 | it('should return "Hello World!"', () => { 20 | expect(appController.getHello()).toBe('Hello World!'); 21 | }); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /apps/server/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | parser: '@typescript-eslint/parser', 3 | parserOptions: { 4 | project: 'tsconfig.json', 5 | tsconfigRootDir: __dirname, 6 | sourceType: 'module', 7 | }, 8 | plugins: ['@typescript-eslint/eslint-plugin'], 9 | extends: [ 10 | 'plugin:@typescript-eslint/recommended', 11 | 'plugin:prettier/recommended', 12 | ], 13 | root: true, 14 | env: { 15 | node: true, 16 | jest: true, 17 | }, 18 | ignorePatterns: ['.eslintrc.js'], 19 | rules: { 20 | '@typescript-eslint/interface-name-prefix': 'off', 21 | '@typescript-eslint/explicit-function-return-type': 'off', 22 | '@typescript-eslint/explicit-module-boundary-types': 'off', 23 | '@typescript-eslint/no-explicit-any': 'off', 24 | }, 25 | }; 26 | -------------------------------------------------------------------------------- /apps/server/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | MYSQL_HOST=${MYSQL_HOST} 3 | MYSQL_PORT=${MYSQL_PORT} 4 | REDIS_HOST=${REDIS_HOST} 5 | REDIS_PORT=${REDIS_PORT} 6 | 7 | # MySQL 헬스체크 8 | echo "Checking MySQL connection at ${MYSQL_HOST}:${MYSQL_PORT}..." 9 | until nc -z -v -w30 "${MYSQL_HOST}" "${MYSQL_PORT}"; do 10 | echo "Waiting for MySQL connection..." 11 | sleep 1 12 | done 13 | echo "MySQL is up and running at ${MYSQL_HOST}:${MYSQL_PORT}!" 14 | 15 | # Redis 헬스체크 16 | echo "Checking Redis connection at ${REDIS_HOST}:${REDIS_PORT}..." 17 | until nc -z -v -w30 "${REDIS_HOST}" "${REDIS_PORT}"; do 18 | echo "Waiting for Redis connection..." 19 | sleep 1 20 | done 21 | echo "Redis is up and running at ${REDIS_HOST}:${REDIS_PORT}!" 22 | 23 | # Prisma 및 애플리케이션 시작 24 | npx prisma generate 25 | npx prisma migrate deploy 26 | npx prisma db seed 27 | node ./dist/src/main.js -------------------------------------------------------------------------------- /packages/cloud-graph/src/stories-example/button.css: -------------------------------------------------------------------------------- 1 | .storybook-button { 2 | display: inline-block; 3 | cursor: pointer; 4 | border: 0; 5 | border-radius: 3em; 6 | font-weight: 700; 7 | line-height: 1; 8 | font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif; 9 | } 10 | .storybook-button--primary { 11 | background-color: #1ea7fd; 12 | color: white; 13 | } 14 | .storybook-button--secondary { 15 | box-shadow: rgba(0, 0, 0, 0.15) 0px 0px 0px 1px inset; 16 | background-color: transparent; 17 | color: #333; 18 | } 19 | .storybook-button--small { 20 | padding: 10px 16px; 21 | font-size: 12px; 22 | } 23 | .storybook-button--medium { 24 | padding: 11px 20px; 25 | font-size: 14px; 26 | } 27 | .storybook-button--large { 28 | padding: 12px 24px; 29 | font-size: 16px; 30 | } 31 | -------------------------------------------------------------------------------- /packages/terraform/parser/VPCParser.ts: -------------------------------------------------------------------------------- 1 | import { BaseResourceParser } from './BaseResourceParser'; 2 | import { ValidationError } from '../util/ValidationError'; 3 | import { NCloudVPC } from '../model/NCloudVPC'; 4 | 5 | export class VPCParser extends BaseResourceParser { 6 | protected resourceType = ['vpc']; 7 | 8 | protected validateProperties(properties: any) { 9 | if (!properties.cidrBlock) { 10 | throw new ValidationError( 11 | 'VPC', 12 | 'ipv4CidrBlock', 13 | '필수 속성이 없습니다.', 14 | ); 15 | } 16 | } 17 | 18 | protected createModel(properties: any): NCloudVPC { 19 | return new NCloudVPC({ 20 | name: this.getNameOrDefault(properties, 'vpc'), 21 | ipv4CidrBlock: properties.cidrBlock, 22 | }); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /apps/server/test/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { Test, TestingModule } from '@nestjs/testing'; 2 | import { INestApplication } from '@nestjs/common'; 3 | import request from 'supertest'; 4 | import { AppModule } from './../src/app.module'; 5 | import { describe, beforeEach, it } from 'vitest'; 6 | 7 | describe('AppController (e2e)', () => { 8 | let app: INestApplication; 9 | 10 | beforeEach(async () => { 11 | const moduleFixture: TestingModule = await Test.createTestingModule({ 12 | imports: [AppModule], 13 | }).compile(); 14 | 15 | app = moduleFixture.createNestApplication(); 16 | await app.init(); 17 | }); 18 | 19 | it('/ (GET)', () => { 20 | return request(app.getHttpServer()) 21 | .get('/') 22 | .expect(200) 23 | .expect('Hello World!'); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/price/models/GetProductPriceListRequest.ts: -------------------------------------------------------------------------------- 1 | export interface GetProductPriceListRequest { 2 | /** 3 | * 페이지 번호 4 | */ 5 | pageNo?: number; 6 | /** 7 | * 페이지 크기(1000 이하, 기본값 1000) 8 | */ 9 | pageSize?: number; 10 | /** 11 | * 리전 코드 12 | */ 13 | regionCode: string; 14 | /** 15 | * 상품 품목 종류 코드 16 | */ 17 | productItemKindCode?: string; 18 | /** 19 | * 상품 카테고리 코드 20 | */ 21 | productCategoryCode?: string; 22 | /** 23 | * 상품 코드 24 | */ 25 | productCode?: string; 26 | /** 27 | * 상품명 28 | */ 29 | productName?: string; 30 | /** 31 | * 결제 통화 코드 32 | */ 33 | payCurrencyCode?: 'KRW' | 'USD' | 'JPY'; 34 | /** 35 | * 응답 결과의 형식 36 | */ 37 | responseFormatType?: 'xml' | 'json'; 38 | } 39 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/server/InterruptServerInstanceRequest.ts: -------------------------------------------------------------------------------- 1 | type InterruptServerInstanceRequest = { 2 | /** 3 | * 리전 코드 4 | * 인터럽트를 실행할 서버 인스턴스의 리전(Region) 결정 가능 5 | * regionCode는 getRegionList 액션을 통해 획득 가능 6 | * @link https://api.ncloud-docs.com/docs/compute-vserver-server-common-getregionlist 7 | * @default getRegionList 조회 결과의 첫 번째 리전을 선택 8 | */ 9 | regionCode?: string; 10 | 11 | /** 12 | * 인터럽트를 실행할 서버 인스턴스 번호 13 | * serverInstanceNo는 getServerInstanceList 액션을 통해 획득 가능 14 | * @link https://api.ncloud-docs.com/docs/compute-vserver-server-getserverinstancelist 15 | * ex) serverInstanceNo=1234 16 | */ 17 | serverInstanceNo: string; 18 | 19 | /** 20 | * 응답 결과의 포맷 타입 21 | * @default xml 22 | */ 23 | responseFormatType?: 'xml' | 'json'; 24 | }; 25 | -------------------------------------------------------------------------------- /packages/terraform/model/NCloudNetworkACL.ts: -------------------------------------------------------------------------------- 1 | import { NetworkACL } from '../interface/NetworkACL'; 2 | import { NCloudModel } from '../interface/NCloudModel'; 3 | import { ResourcePriority } from '../enum/ResourcePriority'; 4 | 5 | export class NCloudNetworkACL implements NetworkACL, NCloudModel { 6 | id: string; 7 | name: string; 8 | vpcNo: string; 9 | serviceType: string; 10 | priority: ResourcePriority; 11 | 12 | constructor(json: any) { 13 | this.serviceType = 'ncloud_network_acl'; 14 | this.priority = ResourcePriority.NETWORK_ACL; 15 | this.id = json.id; 16 | this.name = json.name.toLowerCase(); 17 | this.vpcNo = `ncloud_vpc.${json.vpcName.toLowerCase()}.id`; 18 | } 19 | 20 | getProperties() { 21 | return { 22 | vpc_no: this.vpcNo, 23 | }; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/server/SetProtectServerTerminationResponse.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 서버 반납 보호 설정 응답 3 | * @see {@link https://api.ncloud-docs.com/docs/compute-vserver-server-setprotectservertermination} 4 | * @example 5 | * { 6 | * "returnCode": 0, 7 | * "returnMessage": "success", 8 | * "totalRows": 1, 9 | * "serverInstanceList": [ 10 | * { 11 | * "serverInstanceNo": "***4299", 12 | * "serverName": "test-***", 13 | * "isProtectServerTermination": true 14 | * } 15 | * ] 16 | * } 17 | */ 18 | type SetProtectServerTerminationResponse = { 19 | returnCode: number; 20 | returnMessage: string; 21 | totalRows: number; 22 | serverInstanceList: Array<{ 23 | serverInstanceNo: string; 24 | serverName: string; 25 | isProtectServerTermination: boolean; 26 | }>; 27 | }; 28 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/server-image/DeleteServerImageRequest.ts: -------------------------------------------------------------------------------- 1 | type DeleteServerImageRequest = { 2 | /** 3 | * 리전 코드 4 | * 삭제할 서버 이미지의 리전(Region) 결정 가능 5 | * regionCode는 getRegionList 액션을 통해 획득 가능 6 | * @link https://api.ncloud-docs.com/docs/compute-vserver-server-common-getregionlist 7 | * @default getRegionList 조회 결과의 첫 번째 리전을 선택 8 | */ 9 | regionCode?: string; 10 | 11 | /** 12 | * 삭제할 서버 이미지 번호 리스트 13 | * serverImageNo는 getServerImageList 액션을 통해 획득 가능 14 | * @link https://api.ncloud-docs.com/docs/compute-vserver-serverimage-getserverimagelist 15 | * ex) serverImageNoList.1=1234&serverImageNoList.2=2345 16 | */ 17 | serverImageNoList: string[]; 18 | 19 | /** 20 | * 응답 결과의 포맷 타입 21 | * @default xml 22 | */ 23 | responseFormatType?: 'xml' | 'json'; 24 | }; 25 | -------------------------------------------------------------------------------- /.github/workflows/pr-build-test.yml: -------------------------------------------------------------------------------- 1 | name: PR-BUILD-TEST 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - development 7 | types: 8 | - opened 9 | - reopened 10 | - synchronize 11 | - ready_for_review 12 | 13 | jobs: 14 | build-test: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - name: Check out repository 18 | uses: actions/checkout@v3 19 | 20 | - name: Setup pnpm 21 | uses: pnpm/action-setup@v2 22 | with: 23 | version: 9.12.3 24 | node-version: 20 25 | cache: true 26 | 27 | - name: Install dependencies with pnpm 28 | run: pnpm install --no-frozen-lockfile 29 | 30 | - name: Build the project 31 | run: pnpm build 32 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/login-key/ImportLoginKeyResponse.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 로그인 키 import 응답 3 | * @see {@link https://api.ncloud-docs.com/docs/compute-vserver-server-loginkey-importloginkey} 4 | * @example 5 | * { 6 | * "requestId": "46b585b6-fb86-4cea-8913-9552e6cb8cce", 7 | * "returnCode": 0, 8 | * "returnMessage": "success", 9 | * "totalRows": 1, 10 | * "loginKeyList": [ 11 | * { 12 | * "fingerprint": "-", 13 | * "keyName": "test-***", 14 | * "createDate": "2020-08-11T11:47:34+0900" 15 | * } 16 | * ] 17 | * } 18 | */ 19 | type ImportLoginKeyResponse = { 20 | requestId: string; 21 | returnCode: number; 22 | returnMessage: string; 23 | totalRows: number; 24 | loginKeyList: Array<{ 25 | fingerprint: string; 26 | keyName: string; 27 | createDate: string; 28 | }>; 29 | }; 30 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/server/GetRootPasswordServerInstanceListResponse.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 서버 인스턴스 root 계정 비밀번호 리스트 조회 응답 3 | * @see {@link https://api.ncloud-docs.com/docs/compute-vserver-server-getrootpasswordserverinstancelist} 4 | * @example 5 | * { 6 | * "requestId": "", 7 | * "returnCode": 0, 8 | * "returnMessage": "success", 9 | * "totalRows": 1, 10 | * "rootPasswordServerInstanceList": [ 11 | * { 12 | * "serverInstanceNo": "***4299", 13 | * "rootPassword": "P3e7fLnd6=***" 14 | * } 15 | * ] 16 | * } 17 | */ 18 | type GetRootPasswordServerInstanceListResponse = { 19 | requestId: string; 20 | returnCode: number; 21 | returnMessage: string; 22 | totalRows: number; 23 | rootPasswordServerInstanceList: Array<{ 24 | serverInstanceNo: string; 25 | rootPassword: string; 26 | }>; 27 | }; 28 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/server/StartServerInstancesRequest.ts: -------------------------------------------------------------------------------- 1 | type StartServerInstancesRequest = { 2 | /** 3 | * 리전 코드 4 | * 시작할 서버 인스턴스의 리전(Region) 결정 가능 5 | * regionCode는 getRegionList 액션을 통해 획득 가능 6 | * @link https://api.ncloud-docs.com/docs/compute-vserver-server-common-getregionlist 7 | * @default getRegionList 조회 결과의 첫 번째 리전을 선택 8 | */ 9 | regionCode?: string; 10 | 11 | /** 12 | * 시작할 서버 인스턴스 번호 리스트 13 | * serverInstanceNo는 getServerInstanceList 액션을 통해 획득 가능 14 | * @link https://api.ncloud-docs.com/docs/compute-vserver-server-getserverinstancelist 15 | * ex) serverInstanceNoList.1=1234&serverInstanceNoList.2=2345 16 | */ 17 | serverInstanceNoList: string[]; 18 | 19 | /** 20 | * 응답 결과의 포맷 타입 21 | * @default xml 22 | */ 23 | responseFormatType?: 'xml' | 'json'; 24 | }; 25 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/server/StopServerInstancesRequest.ts: -------------------------------------------------------------------------------- 1 | type StopServerInstancesRequest = { 2 | /** 3 | * 리전 코드 4 | * 정지할 서버 인스턴스의 리전(Region) 결정 가능 5 | * regionCode는 getRegionList 액션을 통해 획득 가능 6 | * @link https://api.ncloud-docs.com/docs/compute-vserver-server-common-getregionlist 7 | * @default getRegionList 조회 결과의 첫 번째 리전을 선택 8 | */ 9 | regionCode?: string; 10 | 11 | /** 12 | * 정지할 서버 인스턴스 번호 리스트 13 | * serverInstanceNo는 getServerInstanceList 액션을 통해 획득 가능 14 | * @link https://api.ncloud-docs.com/docs/compute-vserver-server-getserverinstancelist 15 | * ex) serverInstanceNoList.1=1234&serverInstanceNoList.2=2345 16 | */ 17 | serverInstanceNoList: string[]; 18 | 19 | /** 20 | * 응답 결과의 포맷 타입 21 | * @default xml 22 | */ 23 | responseFormatType?: 'xml' | 'json'; 24 | }; 25 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/subnet/models/DeleteSubnetRequest.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 서브넷 삭제를 위한 요청 객체 3 | */ 4 | export interface DeleteSubnetRequest { 5 | /** 6 | * 삭제하려는 Subnet의 리전 코드. 7 | * 조회 결과의 첫 번째 리전(기본값). 8 | * getRegionList를 통해 확인 가능. 9 | * 10 | * @see {@link https://api.ncloud-docs.com/docs/compute-vserver-server-common-getregionlist}
    11 | * 12 | * Optional 13 | */ 14 | regionCode?: string; 15 | 16 | /** 17 | * 삭제하려는 Subnet 번호. 18 | * getSubnetList를 통해 확인 가능. 19 | * 20 | * @see {@link https://api.ncloud-docs.com/docs/networking-vpc-subnetmanagement-getsubnetlist}
    21 | * 22 | * Required 23 | */ 24 | subnetNo: string; 25 | 26 | /** 27 | * 응답 결과의 형식 (JSON 또는 XML). 28 | * 29 | * Optional 30 | * @default "json" 31 | */ 32 | responseFormatType?: string; 33 | } 34 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/server/RebootServerInstancesRequest.ts: -------------------------------------------------------------------------------- 1 | type RebootServerInstancesRequest = { 2 | /** 3 | * 리전 코드 4 | * 재시작할 서버 인스턴스의 리전(Region) 결정 가능 5 | * regionCode는 getRegionList 액션을 통해 획득 가능 6 | * @link https://api.ncloud-docs.com/docs/compute-vserver-server-common-getregionlist 7 | * @default getRegionList 조회 결과의 첫 번째 리전을 선택 8 | */ 9 | regionCode?: string; 10 | 11 | /** 12 | * 재시작할 서버 인스턴스 번호 리스트 13 | * serverInstanceNo는 getServerInstanceList 액션을 통해 획득 가능 14 | * @link https://api.ncloud-docs.com/docs/compute-vserver-server-getserverinstancelist 15 | * ex) serverInstanceNoList.1=1234&serverInstanceNoList.2=2345 16 | */ 17 | serverInstanceNoList: string[]; 18 | 19 | /** 20 | * 응답 결과의 포맷 타입 21 | * @default xml 22 | */ 23 | responseFormatType?: 'xml' | 'json'; 24 | }; 25 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/server/TerminateServerInstancesRequest.ts: -------------------------------------------------------------------------------- 1 | type TerminateServerInstancesRequest = { 2 | /** 3 | * 리전 코드 4 | * 반납할 서버 인스턴스의 리전(Region) 결정 가능 5 | * regionCode는 getRegionList 액션을 통해 획득 가능 6 | * @link https://api.ncloud-docs.com/docs/compute-vserver-server-common-getregionlist 7 | * @default getRegionList 조회 결과의 첫 번째 리전을 선택 8 | */ 9 | regionCode?: string; 10 | 11 | /** 12 | * 반납할 서버 인스턴스 번호 리스트 13 | * serverInstanceNo는 getServerInstanceList 액션을 통해 획득 가능 14 | * @link https://api.ncloud-docs.com/docs/compute-vserver-server-getserverinstancelist 15 | * ex) serverInstanceNoList.1=1234&serverInstanceNoList.2=2345 16 | */ 17 | serverInstanceNoList: string[]; 18 | 19 | /** 20 | * 응답 결과의 포맷 타입 21 | * @default xml 22 | */ 23 | responseFormatType?: 'xml' | 'json'; 24 | }; 25 | -------------------------------------------------------------------------------- /packages/terraform/model/NCloudLoginKey.ts: -------------------------------------------------------------------------------- 1 | import { NCloudModel } from '../interface/NCloudModel'; 2 | import { ResourcePriority } from '../enum/ResourcePriority'; 3 | import { LoginKey } from '../interface/LoginKey'; 4 | 5 | export class NCloudLoginKey implements LoginKey, NCloudModel { 6 | name: string; 7 | privateKey?: string; 8 | fingerprint?: string; 9 | serviceType: string; 10 | priority: ResourcePriority; 11 | 12 | constructor(json: any) { 13 | this.serviceType = 'ncloud_login_key'; 14 | this.priority = ResourcePriority.LOGIN_KEY; 15 | 16 | if (!json.name && !json.name) { 17 | throw new Error('key_name is required for Login Key'); 18 | } 19 | this.name = json.name.toLowerCase(); 20 | } 21 | 22 | getProperties() { 23 | return { 24 | key_name: this.name, 25 | }; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/init-script/DeleteInitScriptsRequest.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 초기화 스크립트 삭제 요청 파라미터 3 | * @see {@link https://api.ncloud-docs.com/docs/compute-vserver-initscript-deleteinitscripts} 4 | */ 5 | type DeleteInitScriptsRequest = { 6 | /** 7 | * 리전 코드 8 | * 삭제할 초기화 스크립트의 리전(Region) 결정 가능 9 | * regionCode는 {@link https://api.ncloud-docs.com/docs/compute-vserver-server-common-getregionlist} 액션을 통해 획득 가능 10 | * Default : getRegionList 조회 결과의 첫 번째 리전을 선택 11 | */ 12 | regionCode?: string; 13 | 14 | /** 15 | * 삭제할 초기화 스크립트 번호 리스트 16 | * initScriptNo는 {@link https://api.ncloud-docs.com/docs/compute-vserver-initscript-getinitscriptlist} 액션을 통해 획득 가능 17 | */ 18 | initScriptNoList: string[]; 19 | 20 | /** 21 | * 응답 결과의 포맷 타입 22 | * Default : xml 23 | */ 24 | responseFormatType?: 'xml' | 'json'; 25 | }; 26 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/init-script/GetInitScriptDetailRequest.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 초기화 스크립트 상세 정보 조회 요청 파라미터 3 | * @see {@link https://api.ncloud-docs.com/docs/compute-vserver-initscript-getinitscriptdetail} 4 | */ 5 | type GetInitScriptDetailRequest = { 6 | /** 7 | * 리전 코드 8 | * 초기화 스크립트 상세 정보가 조회될 리전(Region) 결정 가능 9 | * regionCode는 {@link https://api.ncloud-docs.com/docs/compute-vserver-server-common-getregionlist} 액션을 통해 획득 가능 10 | * Default : getRegionList 조회 결과의 첫 번째 리전을 선택 11 | */ 12 | regionCode?: string; 13 | 14 | /** 15 | * 조회할 초기화 스크립트 번호 16 | * initScriptNo는 {@link https://api.ncloud-docs.com/docs/compute-vserver-initscript-getinitscriptlist} 액션을 통해 획득 가능 17 | */ 18 | initScriptNo: string; 19 | 20 | /** 21 | * 응답 결과의 포맷 타입 22 | * Default : xml 23 | */ 24 | responseFormatType?: 'xml' | 'json'; 25 | }; 26 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/server-image/GetMemberServerImageInstanceDetailRequest.ts: -------------------------------------------------------------------------------- 1 | type GetMemberServerImageInstanceDetailRequest = { 2 | /** 3 | * 리전 코드 4 | * 회원 서버 이미지 인스턴스 상세 정보가 조회될 리전(Region) 결정 가능 5 | * regionCode는 getRegionList 액션을 통해 획득 가능 6 | * @link https://api.ncloud-docs.com/docs/compute-vserver-server-common-getregionlist 7 | * @default getRegionList 조회 결과의 첫 번째 리전을 선택 8 | */ 9 | regionCode?: string; 10 | 11 | /** 12 | * 조회할 회원 서버 이미지 인스턴스 번호 13 | * memberServerImageInstanceNo는 getMemberServerImageInstanceList 액션을 통해 획득 가능 14 | * @link https://api.ncloud-docs.com/docs/compute-vserver-serverimage-getmemberserverimageinstancelist 15 | */ 16 | memberServerImageInstanceNo: string; 17 | 18 | /** 19 | * 응답 결과의 포맷 타입 20 | * @default xml 21 | */ 22 | responseFormatType?: 'xml' | 'json'; 23 | }; 24 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/placement-group/CreatePlacementGroupRequest.ts: -------------------------------------------------------------------------------- 1 | type CreatePlacementGroupRequest = { 2 | /** 3 | * 리전 코드 4 | * 물리 배치 그룹이 생성될 리전(Region) 결정 가능 5 | * regionCode는 getRegionList 액션을 통해 획득 가능 6 | * @link https://api.ncloud-docs.com/docs/compute-vserver-server-common-getregionlist 7 | * @default getRegionList 조회 결과의 첫 번째 리전을 선택 8 | */ 9 | regionCode?: string; 10 | 11 | /** 12 | * 생성할 물리 배치 그룹 이름 13 | * Min : 3, Max : 30 14 | * 소문자, 숫자, "-"의 특수문자만 허용하며 알파벳 문자로 시작함 15 | * @default NAVER Cloud Platform가 자동으로 부여 16 | */ 17 | placementGroupName?: string; 18 | 19 | /** 20 | * 물리 배치 그룹 유형 코드 21 | * @default AA 22 | */ 23 | placementGroupTypeCode?: 'AA'; 24 | 25 | /** 26 | * 응답 결과의 포맷 타입 27 | * @default xml 28 | */ 29 | responseFormatType?: 'xml' | 'json'; 30 | }; 31 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/signature.ts: -------------------------------------------------------------------------------- 1 | import { createHmac } from 'crypto'; 2 | import { ApiKeyCredentials, RequestConfig } from './types'; 3 | 4 | interface SignatureConfig extends RequestConfig { 5 | apiKey: ApiKeyCredentials; 6 | } 7 | 8 | export function generateSignature({ 9 | method, 10 | url, 11 | timestamp, 12 | params, 13 | apiKey, 14 | }: SignatureConfig): string { 15 | const space = ' '; 16 | const newLine = '\n'; 17 | 18 | const fullUrl = params 19 | ? `${url}?${new URLSearchParams(params).toString()}` 20 | : url; 21 | 22 | const message = [ 23 | method, 24 | space, 25 | fullUrl, 26 | newLine, 27 | timestamp, 28 | newLine, 29 | apiKey.accessKey, 30 | ].join(''); 31 | 32 | return createHmac('sha256', apiKey.secretKey) 33 | .update(message) 34 | .digest('base64'); 35 | } 36 | -------------------------------------------------------------------------------- /apps/client/src/models/ncloud/LoadBalancer.ts: -------------------------------------------------------------------------------- 1 | import { GraphNode } from '@helpers/node'; 2 | import { Node } from '@types'; 3 | import { Networks, NetworksProp } from './Networks'; 4 | 5 | export interface LoadBalancerProp extends NetworksProp { 6 | name: string | null; 7 | networkType: string | null; 8 | subnetNoList: [] | null; 9 | } 10 | 11 | export const LoadBalancer: Node & { 12 | properties: LoadBalancerProp; 13 | } = { 14 | ...GraphNode, 15 | type: 'load-balancer', 16 | size: { 17 | '2d': { width: 90, height: 90 }, 18 | '3d': { width: 97, height: 94, offset: 10 }, 19 | }, 20 | properties: { 21 | ...Networks, 22 | name: null, 23 | networkType: null, 24 | subnetNoList: null, 25 | }, 26 | }; 27 | 28 | export const LoadBalancerRequiredFields = { 29 | name: true, 30 | networkType: true, 31 | subnetNoList: true, 32 | }; 33 | -------------------------------------------------------------------------------- /packages/cloud-graph/src/store/useSvgStore.ts: -------------------------------------------------------------------------------- 1 | import { Dimension, ViewBox } from '@/types'; 2 | import { create } from 'zustand'; 3 | 4 | type SvgStoreState = { 5 | viewBox: ViewBox; 6 | dimension: Dimension; 7 | }; 8 | 9 | type SvgStoreAction = { 10 | setViewBox: ({ x, y, width, height }: ViewBox) => void; 11 | toggleDimension: () => void; 12 | }; 13 | 14 | const useSvgStore = create((set) => ({ 15 | dimension: '3d', 16 | viewBox: { 17 | x: 0, 18 | y: 0, 19 | width: window.innerWidth, 20 | height: window.innerHeight, 21 | }, 22 | setViewBox: ({ x, y, width, height }) => 23 | set(() => ({ viewBox: { x, y, width, height } })), 24 | toggleDimension: () => 25 | set((state) => ({ 26 | dimension: state.dimension === '2d' ? '3d' : '2d', 27 | })), 28 | })); 29 | 30 | export default useSvgStore; 31 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/subnet/models/GetSubnetDetailRequest.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 서브넷 상세 정보 조회를 위한 요청 객체 3 | */ 4 | export interface GetSubnetDetailRequest { 5 | /** 6 | * Subnet 상세 정보를 조회하려는 리전 코드. 7 | * 조회 결과의 첫 번째 리전(기본값). 8 | * getRegionList를 통해 확인 가능. 9 | * 10 | * @see {@link https://api.ncloud-docs.com/docs/compute-vserver-server-common-getregionlist}
    11 | * 12 | * Optional 13 | */ 14 | regionCode?: string; 15 | 16 | /** 17 | * Subnet 번호로 Subnet 상세 정보 조회. 18 | * subnetNo는 getSubnetList를 통해 확인 가능. 19 | * 20 | * @see {@link https://api.ncloud-docs.com/docs/networking-vpc-subnetmanagement-getsubnetlist}
    21 | * 22 | * Required 23 | */ 24 | subnetNo: string; 25 | 26 | /** 27 | * 응답 결과의 형식 (JSON 또는 XML). 28 | * 29 | * Optional 30 | * @default "json" 31 | */ 32 | responseFormatType?: string; 33 | } 34 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/login-key/GetLoginKeyListResponse.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 로그인키 목록 조회 응답 3 | * @see {@link https://api.ncloud-docs.com/docs/compute-vserver-server-loginkey-getloginkeylist} 4 | * @example 5 | * { 6 | * "requestId": "c3967303-ebed-433d-9cb7-e25750236a7c", 7 | * "returnCode": 0, 8 | * "returnMessage": "success", 9 | * "totalRows": 1, 10 | * "loginKeyList": [ 11 | * { 12 | * "fingerprint": "**:**:**:23:e4:fc:2f:35:21:1a:17:13:84:89:c1:e7", 13 | * "keyName": "test-***", 14 | * "createDate": "2020-08-11T10:49:11+0900" 15 | * } 16 | * ] 17 | * } 18 | */ 19 | type GetLoginKeyListResponse = { 20 | requestId: string; 21 | returnCode: number; 22 | returnMessage: string; 23 | totalRows: number; 24 | loginKeyList: Array<{ 25 | fingerprint: string; 26 | keyName: string; 27 | createDate: string; 28 | }>; 29 | }; 30 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/server/SetProtectServerTerminationRequest.ts: -------------------------------------------------------------------------------- 1 | type SetProtectServerTerminationRequest = { 2 | /** 3 | * 리전 코드 4 | * 반납 보호 여부를 설정할 서버 인스턴스의 리전(Region) 결정 가능 5 | * regionCode는 getRegionList 액션을 통해 획득 가능 6 | * @link https://api.ncloud-docs.com/docs/compute-vserver-server-common-getregionlist 7 | * @default getRegionList 조회 결과의 첫 번째 리전을 선택 8 | */ 9 | regionCode?: string; 10 | 11 | /** 12 | * 반납 보호 여부를 설정할 서버 인스턴스 번호 13 | * serverInstanceNo는 getServerInstanceList 액션을 통해 획득 가능 14 | * @link https://api.ncloud-docs.com/docs/compute-vserver-server-getserverinstancelist 15 | */ 16 | serverInstanceNo: string; 17 | 18 | /** 19 | * 반납 보호 여부 20 | */ 21 | isProtectServerTermination: boolean; 22 | 23 | /** 24 | * 응답 결과의 포맷 타입 25 | * @default xml 26 | */ 27 | responseFormatType?: 'xml' | 'json'; 28 | }; 29 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vpc/models/CreateVpcResponse.ts: -------------------------------------------------------------------------------- 1 | import { CommonResponse } from './CommonResponse'; 2 | 3 | /** 4 | * VPC 생성 API 응답 5 | * @interface CreateVpcResponse 6 | * @extends {CommonResponse} 7 | * @see {@link https://api.ncloud-docs.com/docs/networking-vpc-vpcmanagement-createvpc} 8 | * 9 | * @example 10 | * { 11 | * "requestId": "21a29c59-3139-4c23-9f92-10c1fddafef6", 12 | * "returnCode": "0", 13 | * "returnMessage": "success", 14 | * "totalRows": 1, 15 | * "vpcList": [ 16 | * { 17 | * "vpcNo": "1234", 18 | * "vpcName": "test-vpc", 19 | * "ipv4CidrBlock": "10.0.0.0/16", 20 | * "vpcStatus": { 21 | * "code": "INIT", 22 | * "codeName": "init" 23 | * }, 24 | * "regionCode": "KR", 25 | * "createDate": "2020-07-27T17:17:05+0900" 26 | * } 27 | * ] 28 | * } 29 | */ 30 | export interface CreateVpcResponse extends CommonResponse {} 31 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/network-interface/DeleteNetworkInterfaceRequest.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 네트워크 인터페이스 삭제 요청 파라미터 3 | * @see {@link https://api.ncloud-docs.com/docs/compute-vserver-networkinterface-deletenetworkinterface} 4 | */ 5 | type DeleteNetworkInterfaceRequest = { 6 | /** 7 | * 리전 코드 8 | * 삭제할 네트워크 인터페이스의 리전(Region) 결정 가능 9 | * regionCode는 {@link https://api.ncloud-docs.com/docs/compute-vserver-server-common-getregionlist} 액션을 통해 획득 가능 10 | * Default : getRegionList 조회 결과의 첫 번째 리전을 선택 11 | */ 12 | regionCode?: string; 13 | 14 | /** 15 | * 삭제할 네트워크 인터페이스 번호 16 | * networkInterfaceNo는 {@link https://api.ncloud-docs.com/docs/compute-vserver-networkinterface-getnetworkinterfacelist} 액션을 통해 획득 가능 17 | */ 18 | networkInterfaceNo: string; 19 | 20 | /** 21 | * 응답 결과의 포맷 타입 22 | * Default : xml 23 | */ 24 | responseFormatType?: 'xml' | 'json'; 25 | }; 26 | -------------------------------------------------------------------------------- /apps/server/.gitignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /dist 3 | /node_modules 4 | /build 5 | 6 | # Logs 7 | logs 8 | *.log 9 | npm-debug.log* 10 | pnpm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | lerna-debug.log* 14 | 15 | # OS 16 | .DS_Store 17 | 18 | # Tests 19 | /coverage 20 | /.nyc_output 21 | 22 | # IDEs and editors 23 | /.idea 24 | .project 25 | .classpath 26 | .c9/ 27 | *.launch 28 | .settings/ 29 | *.sublime-workspace 30 | 31 | # IDE - VSCode 32 | .vscode/* 33 | !.vscode/settings.json 34 | !.vscode/tasks.json 35 | !.vscode/launch.json 36 | !.vscode/extensions.json 37 | 38 | # dotenv environment variable files 39 | .env 40 | .env.development.local 41 | .env.test.local 42 | .env.production.local 43 | .env.local 44 | 45 | # temp directory 46 | .temp 47 | .tmp 48 | 49 | # Runtime data 50 | pids 51 | *.pid 52 | *.seed 53 | *.pid.lock 54 | 55 | # Diagnostic reports (https://nodejs.org/api/report.html) 56 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vpc/models/GetVpcListResponse.ts: -------------------------------------------------------------------------------- 1 | import { CommonResponse } from './CommonResponse'; 2 | 3 | /** 4 | * VPC 목록 조회 API 응답 5 | * @interface GetVpcListResponse 6 | * @extends {CommonResponse} 7 | * @see {@link https://api.ncloud-docs.com/docs/networking-vpc-vpcmanagement-getvpclist} 8 | * 9 | * @example 10 | * { 11 | * "requestId": "9b37ea3e-3ca9-462f-abad-6e23a35fcb76", 12 | * "returnCode": "0", 13 | * "returnMessage": "success", 14 | * "totalRows": 1, 15 | * "vpcList": [ 16 | * { 17 | * "vpcNo": "1234", 18 | * "vpcName": "test-vpc", 19 | * "ipv4CidrBlock": "10.0.0.0/16", 20 | * "vpcStatus": { 21 | * "code": "RUN", 22 | * "codeName": "run" 23 | * }, 24 | * "regionCode": "KR", 25 | * "createDate": "2020-07-16T22:23:50+0900" 26 | * } 27 | * ] 28 | * } 29 | */ 30 | export interface GetVpcListResponse extends CommonResponse {} 31 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vpc/models/DeleteVpcResponse.ts: -------------------------------------------------------------------------------- 1 | import { CommonResponse } from './CommonResponse'; 2 | 3 | /** 4 | * VPC 삭제 API 응답 5 | * @interface DeleteVpcResponse 6 | * @extends {CommonResponse} 7 | * @see {@link https://api.ncloud-docs.com/docs/networking-vpc-vpcmanagement-deletevpc} 8 | * 9 | * @example 10 | * { 11 | * "requestId": "f6d32d67-ab92-4096-b240-ed2e96d8d265", 12 | * "returnCode": "0", 13 | * "returnMessage": "success", 14 | * "totalRows": 1, 15 | * "vpcList": [ 16 | * { 17 | * "vpcNo": "1234", 18 | * "vpcName": "test-vpc", 19 | * "ipv4CidrBlock": "10.0.0.0/16", 20 | * "vpcStatus": { 21 | * "code": "TERMTING", 22 | * "codeName": "terminating" 23 | * }, 24 | * "regionCode": "KR", 25 | * "createDate": "2020-07-27T17:17:05+0900" 26 | * } 27 | * ] 28 | * } 29 | */ 30 | export interface DeleteVpcResponse extends CommonResponse {} 31 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/acg/GetAccessControlGroupDetailRequest.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * ACG 상세 정보 조회 요청 타입 3 | * @see {@link https://api.ncloud-docs.com/docs/compute-vserver-acg-getaccesscontrolgroupdetail} 4 | */ 5 | export type GetAccessControlGroupDetailRequest = { 6 | /** 7 | * 리전 코드 8 | * ACG 상세 정보가 조회될 리전(Region) 결정 가능 9 | * regionCode는 {@link https://api.ncloud-docs.com/docs/compute-vserver-server-common-getregionlist} 액션을 통해 획득 가능 10 | * Default : getRegionList 조회 결과의 첫 번째 리전을 선택 11 | */ 12 | regionCode?: string; 13 | 14 | /** 15 | * 조회할 ACG 번호 16 | * accessControlGroupNo는 {@link https://api.ncloud-docs.com/docs/compute-vserver-acg-getaccesscontrolgrouplist} 액션을 통해 획득 가능 17 | */ 18 | accessControlGroupNo: string; 19 | 20 | /** 21 | * 응답 결과의 포맷 타입 22 | * Options : xml | json 23 | * Default : xml 24 | */ 25 | responseFormatType?: 'xml' | 'json'; 26 | }; 27 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/public-ip/DeletePublicIpInstanceRequest.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 공인 IP 인스턴스 삭제 요청 3 | * @see {@link https://api.ncloud-docs.com/docs/compute-vserver-publicip-deletepublicipinstance} 4 | */ 5 | export type DeletePublicIpInstanceRequest = { 6 | /** 7 | * 리전 코드 8 | * 삭제할 공인 IP 인스턴스의 리전(Region) 결정 가능 9 | * regionCode는 {@link https://api.ncloud-docs.com/docs/compute-vserver-server-common-getregionlist} 액션을 통해 획득 가능 10 | * Default : getRegionList 조회 결과의 첫 번째 리전을 선택 11 | */ 12 | regionCode?: string; 13 | 14 | /** 15 | * 삭제할 공인 IP 인스턴스 번호 16 | * publicIpInstanceNo는 {@link https://api.ncloud-docs.com/docs/compute-vserver-publicip-getpublicipinstancelist} 액션을 통해 획득 가능 17 | */ 18 | publicIpInstanceNo: string; 19 | 20 | /** 21 | * 응답 결과의 포맷 타입 22 | * Options : xml | json 23 | * Default : xml 24 | */ 25 | responseFormatType?: 'xml' | 'json'; 26 | }; 27 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vpc/models/GetVpcDetailResponse.ts: -------------------------------------------------------------------------------- 1 | import { CommonResponse } from './CommonResponse'; 2 | 3 | /** 4 | * VPC 상세 정보 조회 API 응답 5 | * @interface GetVpcDetailResponse 6 | * @extends {CommonResponse} 7 | * @see {@link https://api.ncloud-docs.com/docs/networking-vpc-vpcmanagement-getvpcdetail} 8 | * 9 | * @example 10 | * { 11 | * "requestId": "13f37a8e-780f-4f32-9115-503a2026cf6d", 12 | * "returnCode": "0", 13 | * "returnMessage": "success", 14 | * "totalRows": 1, 15 | * "vpcList": [ 16 | * { 17 | * "vpcNo": "1234", 18 | * "vpcName": "test-vpc", 19 | * "ipv4CidrBlock": "10.0.0.0/16", 20 | * "vpcStatus": { 21 | * "code": "RUN", 22 | * "codeName": "run" 23 | * }, 24 | * "regionCode": "KR", 25 | * "createDate": "2020-07-16T22:23:50+0900" 26 | * } 27 | * ] 28 | * } 29 | */ 30 | export interface GetVpcDetailResponse extends CommonResponse {} 31 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/network-interface/DisableFlowLogRequest.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * FlowLog 비활성화 요청 타입 3 | * @see {@link https://api.ncloud-docs.com/docs/compute-vserver-networkinterface-disableflowlog} 4 | */ 5 | export type DisableFlowLogRequest = { 6 | /** 7 | * 리전 코드 8 | * 네트워크 인터페이스 리스트가 조회될 리전(Region) 결정 가능 9 | * regionCode는 {@link https://api.ncloud-docs.com/docs/compute-vserver-server-common-getregionlist} 액션을 통해 획득 가능 10 | * Default : getRegionList 조회 결과의 첫 번째 리전을 선택 11 | */ 12 | regionCode?: string; 13 | 14 | /** 15 | * 네트워크 인터페이스 번호 16 | * networkInterfaceNo는 {@link https://api.ncloud-docs.com/docs/compute-vserver-networkinterface-getnetworkinterfacelist} 액션을 통해 획득 가능 17 | */ 18 | networkInterfaceNo: string; 19 | 20 | /** 21 | * 응답 결과의 포맷 타입 22 | * Options : xml | json 23 | * Default : xml 24 | */ 25 | responseFormatType?: 'xml' | 'json'; 26 | }; 27 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/signature.ts: -------------------------------------------------------------------------------- 1 | import { createHmac } from 'crypto'; 2 | import { ApiKeyCredentials, RequestConfig } from './types'; 3 | 4 | interface SignatureConfig extends RequestConfig { 5 | apiKey: ApiKeyCredentials; 6 | } 7 | 8 | export function generateSignature({ 9 | method, 10 | url, 11 | timestamp, 12 | params, 13 | apiKey, 14 | }: SignatureConfig): string { 15 | const space = ' '; 16 | const newLine = '\n'; 17 | 18 | const fullUrl = params 19 | ? `${url}?${new URLSearchParams(params).toString()}` 20 | : url; 21 | 22 | console.log(fullUrl); 23 | const message = [ 24 | method, 25 | space, 26 | fullUrl, 27 | newLine, 28 | timestamp, 29 | newLine, 30 | apiKey.accessKey, 31 | ].join(''); 32 | 33 | return createHmac('sha256', apiKey.secretKey) 34 | .update(message) 35 | .digest('base64'); 36 | } 37 | -------------------------------------------------------------------------------- /apps/client/assets/JP.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /apps/hub/public/JP.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /packages/cloud-graph/src/components/Node/cloud/Container/Container2D.tsx: -------------------------------------------------------------------------------- 1 | import Rect from '@/components/Svg/Rect'; 2 | import Stroke from '@/components/Svg/Stroke'; 3 | import { GRID_SIZE_2D } from '@/constants'; 4 | import { GridSize } from '@/types'; 5 | 6 | type Container2DProps = { 7 | size: GridSize; 8 | }; 9 | 10 | function Container2D(props: Container2DProps) { 11 | const { size } = props; 12 | const width = GRID_SIZE_2D * size.cols; 13 | const height = GRID_SIZE_2D * size.rows; 14 | 15 | const strokePoints = [ 16 | { x: 0, y: 0 }, // topLeft 17 | { x: width, y: 0 }, // topRight 18 | { x: width, y: height }, // bottomRight 19 | { x: 0, y: height }, // bottomLeft 20 | ]; 21 | 22 | return ( 23 | <> 24 | 25 | 26 | 27 | ); 28 | } 29 | 30 | export default Container2D; 31 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/network-interface/GetNetworkInterfaceDetailRequest.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 네트워크 인터페이스 상세 정보 조회 요청 파라미터 3 | * @see {@link https://api.ncloud-docs.com/docs/compute-vserver-networkinterface-getnetworkinterfacedetail} 4 | */ 5 | type GetNetworkInterfaceDetailRequest = { 6 | /** 7 | * 리전 코드 8 | * 네트워크 인터페이스 상세 정보가 조회될 리전(Region) 결정 가능 9 | * regionCode는 {@link https://api.ncloud-docs.com/docs/compute-vserver-server-common-getregionlist} 액션을 통해 획득 가능 10 | * Default : getRegionList 조회 결과의 첫 번째 리전을 선택 11 | */ 12 | regionCode?: string; 13 | 14 | /** 15 | * 조회할 네트워크 인터페이스 번호 16 | * networkInterfaceNo는 {@link https://api.ncloud-docs.com/docs/compute-vserver-networkinterface-getnetworkinterfacelist} 액션을 통해 획득 가능 17 | */ 18 | networkInterfaceNo: string; 19 | 20 | /** 21 | * 응답 결과의 포맷 타입 22 | * Default : xml 23 | */ 24 | responseFormatType?: 'xml' | 'json'; 25 | }; 26 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/storage/GetBlockStorageInstanceDetailRequest.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 블록 스토리지 인스턴스 상세 정보 조회 요청 타입 3 | * @see {@link https://api.ncloud-docs.com/docs/compute-vserver-storage-getblockstorageinstancedetail} 4 | */ 5 | export type GetBlockStorageInstanceDetailRequest = { 6 | /** 7 | * 리전 코드 8 | * 블록 스토리지 인스턴스 상세 정보가 조회될 리전(Region) 결정 가능 9 | * @link https://api.ncloud-docs.com/docs/compute-vserver-server-common-getregionlist 액션을 통해 획득 가능 10 | * Default : getRegionList 조회 결과의 첫 번째 리전을 선택 11 | */ 12 | regionCode?: string; 13 | 14 | /** 15 | * 조회할 블록 스토리지 인스턴스 번호 16 | * @link https://api.ncloud-docs.com/docs/compute-vserver-storage-getblockstorageinstancelist 액션을 통해 획득 가능 17 | */ 18 | blockStorageInstanceNo: string; 19 | 20 | /** 21 | * 응답 결과의 포맷 타입 22 | * Options : xml | json 23 | * Default : xml 24 | */ 25 | responseFormatType?: 'xml' | 'json'; 26 | }; 27 | -------------------------------------------------------------------------------- /packages/terraform/model/NCloudPublicIP.ts: -------------------------------------------------------------------------------- 1 | import { ResourcePriority } from '../enum/ResourcePriority'; 2 | import { NCloudModel } from '../interface/NCloudModel'; 3 | import { PublicIp } from '../interface/PublicIp'; 4 | 5 | export class NCloudPublicIP implements PublicIp, NCloudModel { 6 | id: string; 7 | name: string; 8 | serverInstanceNo?: string; 9 | publicIp?: string; 10 | kindType?: string; 11 | serviceType: string; 12 | priority: ResourcePriority; 13 | 14 | constructor(json: any) { 15 | this.serviceType = 'ncloud_public_ip'; 16 | this.priority = ResourcePriority.PUBLIC_IP; 17 | this.id = json.id || `publicIp-${Date.now()}`; 18 | this.name = json.name.toLowerCase(); 19 | this.serverInstanceNo = `ncloud_server.${json.serverName}.id`; 20 | } 21 | 22 | getProperties() { 23 | return { 24 | server_instance_no: this.serverInstanceNo, 25 | }; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /packages/cli/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cloud-canvas", 3 | "version": "0.0.1", 4 | "description": "", 5 | "private": false, 6 | "keywords": [], 7 | "bin": { 8 | "cloud-canvas": "./dist/index.js" 9 | }, 10 | "files": [ 11 | "dist" 12 | ], 13 | "scripts": { 14 | "start": "node dist/index.js", 15 | "dev": "cross-env NODE_ENV=development tsx watch src/index.ts", 16 | "build": "tsup && chmod +x dist/index.js", 17 | "bundle": "tsup && chmod +x dist/index.js", 18 | "clean": "rm -rf dist" 19 | }, 20 | "dependencies": { 21 | "chalk": "4.1.2", 22 | "express": "^4.21.1", 23 | "open": "^10.1.0" 24 | }, 25 | "devDependencies": { 26 | "@types/node": "^22.8.2", 27 | "cross-env": "^7.0.3", 28 | "tsup": "^8.3.5", 29 | "tsx": "^4.19.2" 30 | }, 31 | "publishConfig": { 32 | "access": "public" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /apps/client/src/contexts/GraphConetxt/reducer.ts: -------------------------------------------------------------------------------- 1 | import { ViewBox } from '@types'; 2 | 3 | export type GraphState = { 4 | viewBox: ViewBox; 5 | initialViewBox: ViewBox; 6 | }; 7 | 8 | export type GraphAction = { 9 | type: 'SET_VIEWBOX'; 10 | payload: GraphState['viewBox']; 11 | }; 12 | // | { 13 | // type: 'INITIAL_VIEWBOX'; 14 | // payload: GraphState['initialViewBox']; 15 | // }; 16 | 17 | export const graphReducer = ( 18 | state: GraphState, 19 | action: GraphAction, 20 | ): GraphState => { 21 | switch (action.type) { 22 | case 'SET_VIEWBOX': 23 | return { ...state, viewBox: action.payload }; 24 | // case 'INITIAL_VIEWBOX': { 25 | // return { 26 | // ...state, 27 | // viewBox: action.payload, 28 | // initialViewBox: action.payload, 29 | // }; 30 | // } 31 | default: 32 | return state; 33 | } 34 | }; 35 | -------------------------------------------------------------------------------- /docker-composes/monitoring/logging/fluentd/conf/fluent.conf: -------------------------------------------------------------------------------- 1 | 2 | @type forward 3 | port 24224 4 | bind 0.0.0.0 5 | 6 | 7 | 8 | @type copy 9 | 10 | @type elasticsearch 11 | host elasticsearch 12 | port 9200 13 | logstash_format true 14 | logstash_prefix fluentd 15 | logstash_dateformat %Y%m%d 16 | include_tag_key true 17 | type_name mysql_log 18 | tag_key @log_name 19 | flush_interval 1s 20 | 21 | 22 | @type stdout 23 | 24 | 25 | 26 | 27 | @type copy 28 | 29 | @type elasticsearch 30 | host elasticsearch 31 | port 9200 32 | logstash_format true 33 | logstash_prefix fluentd 34 | logstash_dateformat %Y%m%d 35 | include_tag_key true 36 | type_name redis_log 37 | tag_key @log_name 38 | flush_interval 1s 39 | 40 | 41 | @type stdout 42 | 43 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/public-ip/GetPublicIpInstanceDetailRequest.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 공인 IP 인스턴스 상세 정보 조회 요청 3 | * @see {@link https://api.ncloud-docs.com/docs/compute-vserver-publicip-getpublicipinstancedetail} 4 | */ 5 | export type GetPublicIpInstanceDetailRequest = { 6 | /** 7 | * 리전 코드 8 | * 공인 IP 인스턴스 상세 정보가 조회될 리전(Region) 결정 가능 9 | * regionCode는 {@link https://api.ncloud-docs.com/docs/compute-vserver-server-common-getregionlist} 액션을 통해 획득 가능 10 | * Default : getRegionList 조회 결과의 첫 번째 리전을 선택 11 | */ 12 | regionCode?: string; 13 | 14 | /** 15 | * 조회할 공인 IP 인스턴스 번호 16 | * publicIpInstanceNo는 {@link https://api.ncloud-docs.com/docs/compute-vserver-publicip-getpublicipinstancelist} 액션을 통해 획득 가능 17 | */ 18 | publicIpInstanceNo: string; 19 | 20 | /** 21 | * 응답 결과의 포맷 타입 22 | * Options : xml | json 23 | * Default : xml 24 | */ 25 | responseFormatType?: 'xml' | 'json'; 26 | }; 27 | -------------------------------------------------------------------------------- /apps/server/src/user/user.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@nestjs/common'; 2 | import { CreateUserDto } from './dto/create-user.dto'; 3 | import { UpdateUserDto } from './dto/update-user.dto'; 4 | 5 | @Injectable() 6 | export class UserService { 7 | private readonly testUser = { 8 | id: 1, 9 | name: 'Test User', 10 | } as const; 11 | 12 | getTestUser() { 13 | return this.testUser; 14 | } 15 | 16 | create(createUserDto: CreateUserDto) { 17 | return 'This action adds a new user'; 18 | } 19 | 20 | findAll() { 21 | return `This action returns all user`; 22 | } 23 | 24 | findOne(id: number) { 25 | return `This action returns a #${id} user`; 26 | } 27 | 28 | update(id: number, updateUserDto: UpdateUserDto) { 29 | return `This action updates a #${id} user`; 30 | } 31 | 32 | remove(id: number) { 33 | return `This action removes a #${id} user`; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /packages/terraform/parser/BaseResourceParser.ts: -------------------------------------------------------------------------------- 1 | import { ResourceParsingStrategy } from '../util/interface/ResourceParsingStrategy'; 2 | import { NCloudModel } from '../interface/NCloudModel'; 3 | 4 | export abstract class BaseResourceParser implements ResourceParsingStrategy { 5 | protected abstract resourceType: string[]; 6 | 7 | protected abstract createModel(properties: any): NCloudModel; 8 | 9 | canParse(type: string): boolean { 10 | return this.resourceType.includes(type.toLowerCase()); 11 | } 12 | 13 | parse(properties: any): NCloudModel { 14 | this.validateProperties(properties); 15 | return this.createModel(properties); 16 | } 17 | 18 | protected validateProperties(properties: any): void {} 19 | 20 | protected getNameOrDefault(properties: any, defaultPrefix: string): string { 21 | return ( 22 | properties.name?.toLowerCase() || `${defaultPrefix}-${Date.now()}` 23 | ); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vpc/signature.ts: -------------------------------------------------------------------------------- 1 | import { createHmac } from 'crypto'; 2 | import { ApiKeyCredentials, RequestConfig } from './types'; 3 | 4 | interface SignatureConfig extends RequestConfig { 5 | apiKey: ApiKeyCredentials; 6 | baseURL: string; 7 | } 8 | 9 | export function generateSignature({ 10 | method, 11 | url, 12 | timestamp, 13 | params, 14 | apiKey, 15 | }: SignatureConfig): string { 16 | const space = ' '; 17 | const newLine = '\n'; 18 | 19 | const fullUrl = params 20 | ? `${url}?${new URLSearchParams(params).toString()}` 21 | : url; 22 | 23 | console.log(fullUrl); 24 | const message = [ 25 | method, 26 | space, 27 | fullUrl, 28 | newLine, 29 | timestamp, 30 | newLine, 31 | apiKey.accessKey, 32 | ].join(''); 33 | 34 | return createHmac('sha256', apiKey.secretKey) 35 | .update(message) 36 | .digest('base64'); 37 | } 38 | -------------------------------------------------------------------------------- /packages/terraform/model/NCloudRedisConfigGroup.ts: -------------------------------------------------------------------------------- 1 | import { RedisConfigGroup } from '../interface/RedisConfigGroup'; 2 | import { NCloudModel } from '../interface/NCloudModel'; 3 | import { ResourcePriority } from '../enum/ResourcePriority'; 4 | 5 | export class NCloudRedisConfigGroup implements RedisConfigGroup, NCloudModel { 6 | name: string; 7 | serviceType: string; 8 | redisVersion: string; 9 | description?: string; 10 | priority: ResourcePriority; 11 | constructor(json: any) { 12 | this.serviceType = 'ncloud_redis_config_group'; 13 | this.name = json.name; 14 | this.priority = ResourcePriority.REDIS_CONFIG_GROUP; 15 | this.redisVersion = json.redisVersion; 16 | this.description = json.description; 17 | } 18 | getProperties() { 19 | return { 20 | name: this.name, 21 | redis_version: this.redisVersion, 22 | description: this.description, 23 | }; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /apps/client/src/models/ncloud/Server.ts: -------------------------------------------------------------------------------- 1 | import { GraphNode } from '@helpers/node'; 2 | import { Node } from '@types'; 3 | import { Networks, NetworksProp } from './Networks'; 4 | 5 | export interface ServerProp extends NetworksProp { 6 | name: string | null; 7 | server_image_number: string | null; 8 | server_spec_code: string | null; 9 | } 10 | 11 | export const Server: Node & { 12 | properties: ServerProp; 13 | } = { 14 | ...GraphNode, 15 | type: 'server', 16 | size: { 17 | '2d': { width: 90, height: 90 }, 18 | '3d': { width: 128, height: 111, offset: 0 }, 19 | }, 20 | properties: { 21 | ...Networks, 22 | name: null, 23 | server_image_number: null, 24 | server_spec_code: null, 25 | }, 26 | }; 27 | 28 | export const ServerRequiredFields = { 29 | name: true, 30 | server_image_number: true, 31 | server_spec_code: true, 32 | vpc: true, 33 | subnet: true, 34 | region: true, 35 | }; 36 | -------------------------------------------------------------------------------- /apps/client/src/models/ncloud/utils.ts: -------------------------------------------------------------------------------- 1 | export const transformObject = (obj: any) => { 2 | return Object.fromEntries( 3 | Object.entries(obj).map(([key, value]) => { 4 | if ( 5 | typeof value === 'object' && 6 | value !== null && 7 | 'value' in value 8 | ) { 9 | return [key, value.value]; 10 | } 11 | return [key, value]; 12 | }), 13 | ); 14 | }; 15 | 16 | export const validateObject = ( 17 | obj: any, 18 | requiredFields: Record, 19 | ) => { 20 | return Object.entries(requiredFields).every(([key, isRequired]) => { 21 | if (!isRequired) { 22 | return true; 23 | } 24 | 25 | const value = obj[key]; 26 | if (typeof value === 'object' && value !== null && 'value' in value) { 27 | return Boolean(value.value); 28 | } 29 | return Boolean(value); 30 | }); 31 | }; 32 | -------------------------------------------------------------------------------- /packages/cloud-graph/.storybook/main.ts: -------------------------------------------------------------------------------- 1 | import type { StorybookConfig } from '@storybook/react-vite'; 2 | 3 | import { join, dirname } from 'path'; 4 | 5 | /** 6 | * This function is used to resolve the absolute path of a package. 7 | * It is needed in projects that use Yarn PnP or are set up within a monorepo. 8 | */ 9 | function getAbsolutePath(value: string): any { 10 | return dirname(require.resolve(join(value, 'package.json'))); 11 | } 12 | const config: StorybookConfig = { 13 | stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'], 14 | addons: [ 15 | getAbsolutePath('@storybook/addon-onboarding'), 16 | getAbsolutePath('@storybook/addon-essentials'), 17 | getAbsolutePath('@chromatic-com/storybook'), 18 | getAbsolutePath('@storybook/addon-interactions'), 19 | ], 20 | framework: { 21 | name: getAbsolutePath('@storybook/react-vite'), 22 | options: {}, 23 | }, 24 | }; 25 | export default config; 26 | -------------------------------------------------------------------------------- /packages/cloud-graph/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", 4 | "target": "ES2020", 5 | "useDefineForClassFields": true, 6 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 7 | "module": "ESNext", 8 | "skipLibCheck": true, 9 | 10 | /* Bundler mode */ 11 | "moduleResolution": "bundler", 12 | "allowImportingTsExtensions": true, 13 | "isolatedModules": true, 14 | "moduleDetection": "force", 15 | "noEmit": true, 16 | "jsx": "react-jsx", 17 | 18 | /* Linting */ 19 | "strict": true, 20 | "noUnusedLocals": true, 21 | "noUnusedParameters": true, 22 | "noFallthroughCasesInSwitch": true, 23 | "noUncheckedSideEffectImports": true, 24 | 25 | "baseUrl": ".", 26 | "paths": { 27 | "@/*": ["src/*"] 28 | } 29 | }, 30 | "include": ["src"] 31 | } 32 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/server-image/DeleteMemberServerImageInstancesRequest.ts: -------------------------------------------------------------------------------- 1 | type DeleteMemberServerImageInstancesRequest = { 2 | /** 3 | * 리전 코드 4 | * 삭제할 회원 서버 이미지 인스턴스의 리전(Region) 결정 가능 5 | * regionCode는 getRegionList 액션을 통해 획득 가능 6 | * @link https://api.ncloud-docs.com/docs/compute-vserver-server-common-getregionlist 7 | * @default getRegionList 조회 결과의 첫 번째 리전을 선택 8 | */ 9 | regionCode?: string; 10 | 11 | /** 12 | * 삭제할 회원 서버 이미지 인스턴스 번호 리스트 13 | * memberServerImageInstanceNo는 getMemberServerImageInstanceList 액션을 통해 획득 가능 14 | * @link https://api.ncloud-docs.com/docs/compute-vserver-serverimage-getmemberserverimageinstancelist 15 | * ex) memberServerImageInstanceNoList.1=1234&memberServerImageInstanceNoList.2=2345 16 | */ 17 | memberServerImageInstanceNoList: string[]; 18 | 19 | /** 20 | * 응답 결과의 포맷 타입 21 | * @default xml 22 | */ 23 | responseFormatType?: 'xml' | 'json'; 24 | }; 25 | -------------------------------------------------------------------------------- /config/cz.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | types: [ 3 | { value: '✨ Feat', name: '✨ Feat:\t새로운 기능 추가' }, 4 | { value: '🐞 Fix', name: '🐞 Fix:\t버그 수정' }, 5 | { 6 | value: '🐛 Design', 7 | name: '🐛 Design:\tCSS 등 사용자 UI 디자인 변경', 8 | }, 9 | { value: '📝 Docs', name: '📝 Docs:\t문서 수정' }, 10 | { 11 | value: '💄 Style', 12 | name: '💄 Style:\t코드 포맷 변경(세미콜론, 들여쓰기 등)만 수정', 13 | }, 14 | { 15 | value: '🤖 Refactor', 16 | name: '🤖 Refactor:\t리팩토링, 파일 삭제, 수정, 이동 등', 17 | }, 18 | { 19 | value: '✅ Test', 20 | name: '✅ Test:\t테스트 코드 관련작업', 21 | }, 22 | { 23 | value: '🚚 Setting', 24 | name: '🚚 Setting:\t기타 작업(빌드 스크립트, 패키지 매니저 등등)', 25 | }, 26 | ], 27 | allowCustomScopes: false, 28 | allowBreakingChanges: ['feat', 'fix'], 29 | skipQuestions: ['body'], 30 | subjectLimit: 200, 31 | }; 32 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/common/getZoneListResponse.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * getZoneList 응답 3 | * @see {@link } 4 | * @example 5 | * { 6 | * "requestId": "9a3aefb2-4d35-4cfe-9152-e4c451cc7966", 7 | * "returnCode": "0", 8 | * "returnMessage": "success", 9 | * "totalRows": 2, 10 | * "zoneList": [ 11 | * { 12 | * "zoneName": "KR-2", 13 | * "zoneCode": "KR-2", 14 | * "regionCode": "KR", 15 | * "zoneDescription": "평촌 zone" 16 | * }, 17 | * { 18 | * "zoneName": "KR-1", 19 | * "zoneCode": "KR-1", 20 | * "regionCode": "KR", 21 | * "zoneDescription": "가산 zone" 22 | * } 23 | * ] 24 | * } 25 | */ 26 | export type GetZoneListResponse = { 27 | requestId: string; 28 | returnCode: string; 29 | returnMessage: string; 30 | totalRows: number; 31 | zoneList: Array<{ 32 | zoneName: string; 33 | zoneCode: string; 34 | regionCode: string; 35 | zoneDescription: string; 36 | }>; 37 | }; 38 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/server-image/DeleteServerImageResponse.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 서버 이미지 삭제 응답 3 | * @see {@link https://api.ncloud-docs.com/docs/deleteserverimage} 4 | * @example 5 | * { 6 | * "requestId": "", 7 | * "returnCode": 0, 8 | * "returnMessage": "success", 9 | * "totalRows": 1, 10 | * "serverImageList": [ 11 | * { 12 | * "serverImageNo": "***5847", 13 | * "serverImageName": "test-***", 14 | * "serverImageStatus": { 15 | * "code": "TERMT", 16 | * "codeName": "Server TERMINATE state" 17 | * } 18 | * } 19 | * ] 20 | * } 21 | */ 22 | type DeleteServerImageResponse = { 23 | requestId: string; 24 | returnCode: number; 25 | returnMessage: string; 26 | totalRows: number; 27 | serverImageList: Array<{ 28 | serverImageNo: string; 29 | serverImageName: string; 30 | serverImageStatus: { 31 | code: string; 32 | codeName: string; 33 | }; 34 | }>; 35 | }; 36 | -------------------------------------------------------------------------------- /packages/cloud-graph/src/stories-example/Header.stories.ts: -------------------------------------------------------------------------------- 1 | import type { Meta, StoryObj } from '@storybook/react'; 2 | import { fn } from '@storybook/test'; 3 | 4 | import { Header } from './Header'; 5 | 6 | const meta = { 7 | title: 'Example/Header', 8 | component: Header, 9 | // This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs 10 | tags: ['autodocs'], 11 | parameters: { 12 | // More on how to position stories at: https://storybook.js.org/docs/configure/story-layout 13 | layout: 'fullscreen', 14 | }, 15 | args: { 16 | onLogin: fn(), 17 | onLogout: fn(), 18 | onCreateAccount: fn(), 19 | }, 20 | } satisfies Meta; 21 | 22 | export default meta; 23 | type Story = StoryObj; 24 | 25 | export const LoggedIn: Story = { 26 | args: { 27 | user: { 28 | name: 'Jane Doe', 29 | }, 30 | }, 31 | }; 32 | 33 | export const LoggedOut: Story = {}; 34 | -------------------------------------------------------------------------------- /packages/cloud-graph/eslint.config.js: -------------------------------------------------------------------------------- 1 | import js from '@eslint/js'; 2 | import globals from 'globals'; 3 | import reactHooks from 'eslint-plugin-react-hooks'; 4 | import reactRefresh from 'eslint-plugin-react-refresh'; 5 | import tseslint from 'typescript-eslint'; 6 | 7 | export default tseslint.config( 8 | { ignores: ['dist'] }, 9 | { 10 | extends: [js.configs.recommended, ...tseslint.configs.recommended], 11 | files: ['**/*.{ts,tsx}'], 12 | languageOptions: { 13 | ecmaVersion: 2020, 14 | globals: globals.browser, 15 | }, 16 | plugins: { 17 | 'react-hooks': reactHooks, 18 | 'react-refresh': reactRefresh, 19 | }, 20 | rules: { 21 | ...reactHooks.configs.recommended.rules, 22 | 'react-refresh/only-export-components': [ 23 | 'warn', 24 | { allowConstantExport: true }, 25 | ], 26 | 'react-refresh/only-export-components': 'off', 27 | }, 28 | }, 29 | ); 30 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/storage/DeleteBlockStorageInstancesRequest.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 블록 스토리지 인스턴스 리스트 삭제 요청 타입 3 | * @see {@link https://api.ncloud-docs.com/docs/compute-vserver-storage-deleteblockstorageinstances} 4 | */ 5 | export type DeleteBlockStorageInstancesRequest = { 6 | /** 7 | * 리전 코드 8 | * 삭제할 블록 스토리지 인스턴스의 리전(Region) 결정 가능 9 | * @link https://api.ncloud-docs.com/docs/compute-vserver-server-common-getregionlist 액션을 통해 획득 가능 10 | * Default : getRegionList 조회 결과의 첫 번째 리전을 선택 11 | */ 12 | regionCode?: string; 13 | 14 | /** 15 | * 삭제할 블록 스토리지 인스턴스 번호 리스트 16 | * @link https://api.ncloud-docs.com/docs/compute-vserver-storage-getblockstorageinstancelist 액션을 통해 획득 가능 17 | * ex) blockStorageInstanceNoList.1=1234&blockStorageInstanceNoList.2=2345 18 | */ 19 | blockStorageInstanceNoList: string[]; 20 | 21 | /** 22 | * 응답 결과의 포맷 타입 23 | * Options : xml | json 24 | * Default : xml 25 | */ 26 | responseFormatType?: 'xml' | 'json'; 27 | }; 28 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/server/GetRootPasswordRequest.ts: -------------------------------------------------------------------------------- 1 | type GetRootPasswordRequest = { 2 | /** 3 | * 리전 코드 4 | * root 계정의 비밀번호를 조회할 서버 인스턴스의 리전(Region) 결정 5 | * regionCode는 getRegionList 액션을 통해서 획득 가능 6 | * @link https://api.ncloud-docs.com/docs/compute-vserver-server-common-getregionlist 7 | * @default getRegionList 조회 결과의 첫 번째 리전을 선택 8 | */ 9 | regionCode?: string; 10 | 11 | /** 12 | * 서버 인스턴스 번호 13 | * serverInstanceNo는 getServerInstanceList 액션을 통해 획득 가능 14 | * @link https://api.ncloud-docs.com/docs/compute-vserver-server-getserverinstancelist 15 | */ 16 | serverInstanceNo: string; 17 | 18 | /** 19 | * 서버 인스턴스에 할당된 로그인 키 20 | * 생성하거나 import한 로그인 키의 개인 키 텍스트 입력 21 | * 서버의 로그인 키 파일(.pem)을 통해 획득 가능 22 | * 로그인 키 내용이 그대로 들어와야 하므로 '\n'을 붙여주고, GET 방식을 이용시 URL 인코딩 필요 23 | */ 24 | privateKey?: string; 25 | 26 | /** 27 | * 응답 결과의 포맷 타입 28 | * @default xml 29 | */ 30 | responseFormatType?: 'xml' | 'json'; 31 | }; 32 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/server-image/RemoveServerImageSharingPermissionRequest.ts: -------------------------------------------------------------------------------- 1 | type RemoveServerImageSharingPermissionRequest = { 2 | /** 3 | * 리전 코드 4 | * 공유 권한을 제거할 회원 서버 이미지 인스턴스의 리전(Region) 결정 가능 5 | * regionCode는 getRegionList 액션을 통해 획득 가능 6 | * @link https://api.ncloud-docs.com/docs/compute-vserver-server-common-getregionlist 7 | * @default getRegionList 조회 결과의 첫 번째 리전을 선택 8 | */ 9 | regionCode?: string; 10 | 11 | /** 12 | * 서버 이미지 번호 13 | * serverImageNo는 getServerImageList 액션을 통해 획득 가능 14 | * @link https://api.ncloud-docs.com/docs/compute-vserver-serverimage-getserverimagelist 15 | */ 16 | serverImageNo: string; 17 | 18 | /** 19 | * 대상 로그인 ID 리스트 20 | * 제거할 대상의 로그인 ID 리스트 지정 21 | * ex) targetLoginIdList.1=id1@email.com&targetLoginIdList.2=id2@email.com 22 | */ 23 | targetLoginIdList: string[]; 24 | 25 | /** 26 | * 응답 결과의 포맷 타입 27 | * @default xml 28 | */ 29 | responseFormatType?: 'xml' | 'json'; 30 | }; 31 | -------------------------------------------------------------------------------- /packages/cloud-graph/src/components/Node/cloud/Server/Server3D.tsx: -------------------------------------------------------------------------------- 1 | import Block, { calculateBlockPoints } from '@/components/Svg/Block'; 2 | import Stroke from '@/components/Svg/Stroke'; 3 | import { GridSize } from '@/types'; 4 | 5 | type Server3DProps = { 6 | size: Required; 7 | }; 8 | 9 | function Server3D(props: Server3DProps) { 10 | const { size } = props; 11 | 12 | //INFO: 하단 파란색 표면 포인트 계산 13 | const { depth } = size as Required; 14 | const points = calculateBlockPoints(size as Required); 15 | 16 | const strokePoints = [ 17 | points[0], 18 | points[1], 19 | { x: points[1].x, y: points[1].y + depth }, 20 | { x: points[2].x, y: points[2].y + depth }, 21 | { x: points[3].x, y: points[3].y + depth }, 22 | { x: points[3].x, y: points[3].y }, 23 | ]; 24 | 25 | return ( 26 | }> 27 | 28 | 29 | ); 30 | } 31 | 32 | export default Server3D; 33 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/server-image/AddServerImageSharingPermissionRequest.ts: -------------------------------------------------------------------------------- 1 | type AddServerImageSharingPermissionRequest = { 2 | /** 3 | * 리전 코드 4 | * 공유 권한을 추가할 회원 서버 이미지 인스턴스의 리전(Region) 결정 가능 5 | * regionCode는 getRegionList 액션을 통해 획득 가능 6 | * @link https://api.ncloud-docs.com/docs/compute-vserver-server-common-getregionlist 7 | * @default getRegionList 조회 결과의 첫 번째 리전을 선택 8 | */ 9 | regionCode?: string; 10 | 11 | /** 12 | * 서버 이미지 번호 13 | * serverImageNo는 getServerImageList 액션을 통해 획득 가능 14 | * @link https://api.ncloud-docs.com/docs/compute-vserver-serverimage-getserverimagelist 15 | */ 16 | serverImageNo: string; 17 | 18 | /** 19 | * 대상 로그인 ID 리스트 20 | * 회원 서버 이미지를 공유할 대상의 로그인 ID 리스트 지정 21 | * ex) targetLoginIdList.1=id1@email.com&targetLoginIdList.2=id2@email.com 22 | */ 23 | targetLoginIdList: string[]; 24 | 25 | /** 26 | * 응답 결과의 포맷 타입 27 | * @default xml 28 | */ 29 | responseFormatType?: 'xml' | 'json'; 30 | }; 31 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/snapshot/DeleteBlockStorageSnapshotInstancesRequest.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 블록 스토리지 스냅샷 인스턴스 삭제 요청 3 | * @see {@link https://api.ncloud-docs.com/docs/compute-vserver-snapshot-deleteblockstoragesnapshotinstances} 4 | */ 5 | export type DeleteBlockStorageSnapshotInstancesRequest = { 6 | /** 7 | * 리전 코드 8 | * 삭제할 블록 스토리지 스냅샷 인스턴스의 리전(Region) 결정 가능 9 | * regionCode는 {@link https://api.ncloud-docs.com/docs/compute-vserver-server-common-getregionlist} 액션을 통해 획득 가능 10 | * Default : getRegionList 조회 결과의 첫 번째 리전을 선택 11 | */ 12 | regionCode?: string; 13 | 14 | /** 15 | * 삭제할 블록 스토리지 스냅샷 인스턴스 번호 리스트 16 | * blockStorageSnapshotInstanceNo는 {@link https://api.ncloud-docs.com/docs/compute-vserver-snapshot-getblockstoragesnapshotinstancelist} 액션을 통해 획득 가능 17 | */ 18 | blockStorageSnapshotInstanceNoList: string[]; 19 | 20 | /** 21 | * 응답 결과의 포맷 타입 22 | * Options : xml | json 23 | * Default : xml 24 | */ 25 | responseFormatType?: 'xml' | 'json'; 26 | }; 27 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/server/GetRootPasswordServerInstanceListRequest.ts: -------------------------------------------------------------------------------- 1 | type GetRootPasswordServerInstanceList = { 2 | /** 3 | * 리전 코드 4 | * root 계정의 비밀번호를 조회할 서버 인스턴스 리스트의 리전(Region) 결정 5 | * regionCode는 getRegionList 액션을 통해 획득 가능 6 | * @link https://api.ncloud-docs.com/docs/compute-vserver-server-common-getregionlist 7 | * @default getRegionList 조회 결과의 첫 번째 리전을 선택 8 | */ 9 | regionCode?: string; 10 | 11 | /** 12 | * 서버 인스턴스 정보 목록 13 | * serverInstanceNo는 getServerInstanceList 액션을 통해 획득 가능 14 | * @link https://api.ncloud-docs.com/docs/compute-vserver-server-getserverinstancelist 15 | * ex) rootPasswordServerInstanceList.1.serverInstanceNo=1234&rootPasswordServerInstanceList.2.serverInstanceNo=2345 16 | */ 17 | rootPasswordServerInstanceList: Array<{ 18 | serverInstanceNo: string; 19 | privateKey?: string; 20 | }>; 21 | 22 | /** 23 | * 응답 결과의 포맷 타입 24 | * @default xml 25 | */ 26 | responseFormatType?: 'xml' | 'json'; 27 | }; 28 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/snapshot/GetBlockStorageSnapshotInstanceDetailRequest.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 블록 스토리지 스냅샷 인스턴스 상세 정보 조회 요청 3 | * @see {@link https://api.ncloud-docs.com/docs/compute-vserver-snapshot-getblockstoragesnapshotinstancedetail} 4 | */ 5 | export type GetBlockStorageSnapshotInstanceDetailRequest = { 6 | /** 7 | * 리전 코드 8 | * 블록 스토리지 스냅샷 인스턴스 상세 정보가 조회될 리전(Region) 결정 가능 9 | * regionCode는 {@link https://api.ncloud-docs.com/docs/compute-vserver-server-common-getregionlist} 액션을 통해 획득 가능 10 | * Default : getRegionList 조회 결과의 첫 번째 리전을 선택 11 | */ 12 | regionCode?: string; 13 | 14 | /** 15 | * 조회할 블록 스토리지 스냅샷 인스턴스 번호 16 | * blockStorageSnapshotInstanceNo는 {@link https://api.ncloud-docs.com/docs/compute-vserver-snapshot-getblockstoragesnapshotinstancelist} 액션을 통해 획득 가능 17 | */ 18 | blockStorageSnapshotInstanceNo: string; 19 | 20 | /** 21 | * 응답 결과의 포맷 타입 22 | * Options : xml | json 23 | * Default : xml 24 | */ 25 | responseFormatType?: 'xml' | 'json'; 26 | }; 27 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/createVpc.ts: -------------------------------------------------------------------------------- 1 | import { ApiKeyCredentials } from './types'; 2 | import { VpcApi } from './VpcApi'; 3 | import * as process from 'node:process'; 4 | import dotenv from 'dotenv'; 5 | 6 | dotenv.config(); 7 | 8 | async function main() { 9 | if (!process.env.NCLOUD_ACCESS_KEY || !process.env.NCLOUD_SECRET_KEY) { 10 | throw new Error('API Key not found'); 11 | } 12 | 13 | const apiKey: ApiKeyCredentials = { 14 | accessKey: process.env.NCLOUD_ACCESS_KEY, 15 | secretKey: process.env.NCLOUD_SECRET_KEY, 16 | }; 17 | 18 | const vpcApi = new VpcApi(apiKey); 19 | 20 | try { 21 | const result = await vpcApi.createVpc({ 22 | regionCode: 'KR', 23 | vpcName: `test-vpc-${Date.now()}`, 24 | ipv4CidrBlock: '10.0.0.0/16', 25 | }); 26 | console.log('VPC Created:', result); 27 | } catch (error) { 28 | console.error('Failed to create VPC:', error); 29 | } 30 | } 31 | 32 | if (require.main === module) { 33 | main().catch(console.error); 34 | } 35 | -------------------------------------------------------------------------------- /apps/hub/src/ui/ArrowDownIcon.tsx: -------------------------------------------------------------------------------- 1 | export const ArrowDownIcon = ({ size = 12 }: { size?: number }) => ( 2 | 8 | 12 | 13 | ); 14 | -------------------------------------------------------------------------------- /infra/modules/server/variables.tf: -------------------------------------------------------------------------------- 1 | variable "login_key_name" { 2 | description = "server login key name" 3 | type = string 4 | } 5 | 6 | variable "public_servers" { 7 | description = "public server module variables" 8 | type = list(object({ 9 | server_image_product_code = optional(string) 10 | server_product_code = optional(string) 11 | server_spec_code = optional(string) 12 | member_server_image_no = optional(string) 13 | name = string 14 | description = optional(string) 15 | zone = optional(string) 16 | subnet_no = string 17 | })) 18 | 19 | default = [] 20 | } 21 | 22 | variable "private_servers" { 23 | description = "private server module variables" 24 | type = list(object({ 25 | server_image_product_code = optional(string) 26 | server_product_code = optional(string) 27 | server_spec_code = optional(string) 28 | member_server_image_no = optional(string) 29 | name = string 30 | description = optional(string) 31 | zone = optional(string) 32 | subnet_no = string 33 | })) 34 | 35 | default = [] 36 | } -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/placement-group/CreatePlacementGroupResponse.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 물리 배치 그룹 생성 응답 3 | * @see {@link https://api.ncloud-docs.com/docs/compute-vserver-server-placementgroup-createplacementgroup} 4 | * @example 5 | * { 6 | * "requestId": "", 7 | * "returnCode": 0, 8 | * "returnMessage": "success", 9 | * "totalRows": 1, 10 | * "placementGroupList": [ 11 | * { 12 | * "placementGroupNo": "***61", 13 | * "placementGroupName": "test-***", 14 | * "placementGroupType": { 15 | * "code": "AA", 16 | * "codeName": "Anti-Affinity" 17 | * } 18 | * } 19 | * ] 20 | * } 21 | */ 22 | type CreatePlacementGroupResponse = { 23 | requestId: string; 24 | returnCode: number; 25 | returnMessage: string; 26 | totalRows: number; 27 | placementGroupList: Array<{ 28 | placementGroupNo: string; 29 | placementGroupName: string; 30 | placementGroupType: { 31 | code: string; 32 | codeName: string; 33 | }; 34 | }>; 35 | }; 36 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/placement-group/DeletePlacementGroupResponse.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 물리 배치 그룹 삭제 응답 3 | * @see {@link https://api.ncloud-docs.com/docs/compute-vserver-server-placementgroup-deleteplacementgroup} 4 | * @example 5 | * { 6 | * "requestId": "", 7 | * "returnCode": 0, 8 | * "returnMessage": "success", 9 | * "totalRows": 1, 10 | * "placementGroupList": [ 11 | * { 12 | * "placementGroupNo": "***61", 13 | * "placementGroupName": "test-***", 14 | * "placementGroupType": { 15 | * "code": "AA", 16 | * "codeName": "Anti-Affinity" 17 | * } 18 | * } 19 | * ] 20 | * } 21 | */ 22 | type DeletePlacementGroupResponse = { 23 | requestId: string; 24 | returnCode: number; 25 | returnMessage: string; 26 | totalRows: number; 27 | placementGroupList: Array<{ 28 | placementGroupNo: string; 29 | placementGroupName: string; 30 | placementGroupType: { 31 | code: string; 32 | codeName: string; 33 | }; 34 | }>; 35 | }; 36 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vpc/createVpc.ts: -------------------------------------------------------------------------------- 1 | import { ApiKeyCredentials } from './types'; 2 | import { VpcApi } from './VpcApi'; 3 | import * as process from 'node:process'; 4 | import dotenv from 'dotenv'; 5 | 6 | dotenv.config(); 7 | 8 | async function main() { 9 | if (!process.env.NCLOUD_ACCESS_KEY || !process.env.NCLOUD_SECRET_KEY) { 10 | throw new Error('API Key not found'); 11 | } 12 | 13 | const apiKey: ApiKeyCredentials = { 14 | accessKey: process.env.NCLOUD_ACCESS_KEY, 15 | secretKey: process.env.NCLOUD_SECRET_KEY, 16 | }; 17 | 18 | const vpcApi = new VpcApi(apiKey); 19 | 20 | try { 21 | const result = await vpcApi.createVpc({ 22 | regionCode: 'KR', 23 | vpcName: `test-vpc-${Date.now()}`, 24 | ipv4CidrBlock: '10.0.0.0/16', 25 | }); 26 | console.log('VPC Created:', result); 27 | } catch (error) { 28 | console.error('Failed to create VPC:', error); 29 | } 30 | } 31 | 32 | if (require.main === module) { 33 | main().catch(console.error); 34 | } 35 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/placement-group/GetPlacementGroupListRequest.ts: -------------------------------------------------------------------------------- 1 | type GetPlacementGroupListRequest = { 2 | /** 3 | * 리전 코드 4 | * 물리 배치 그룹 리스트가 조회될 리전(Region) 결정 가능 5 | * regionCode는 getRegionList 액션을 통해 획득 가능 6 | * @link https://api.ncloud-docs.com/docs/compute-vserver-server-common-getregionlist 7 | * @default getRegionList 조회 결과의 첫 번째 리전을 선택 8 | */ 9 | regionCode?: string; 10 | 11 | /** 12 | * 물리 배치 그룹 번호 리스트 13 | * 물리 배치 그룹 번호로 필터링하여 검색 가능 14 | * placementGroupNo는 getPlacementGroupList 액션을 통해 획득 가능 15 | * @link https://api.ncloud-docs.com/docs/compute-vserver-server-placementgroup-getplacementgrouplist 16 | * ex) placementGroupNoList.1=1234&placementGroupNoList.2=2345 17 | */ 18 | placementGroupNoList?: string[]; 19 | 20 | /** 21 | * 물리 배치 그룹 이름 22 | * 물리 배치 그룹 이름으로 필터링하여 검색 가능 23 | */ 24 | placementGroupName?: string; 25 | 26 | /** 27 | * 응답 결과의 포맷 타입 28 | * @default xml 29 | */ 30 | responseFormatType?: 'xml' | 'json'; 31 | }; 32 | -------------------------------------------------------------------------------- /packages/ncloud-sdk/src/services/vserver/models/placement-group/GetPlacementGroupListResponse.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 물리 배치 그룹 리스트 조회 응답 3 | * @see {@link https://api.ncloud-docs.com/docs/compute-vserver-server-placementgroup-getplacementgrouplist} 4 | * @example 5 | * { 6 | * "requestId": "", 7 | * "returnCode": 0, 8 | * "returnMessage": "success", 9 | * "totalRows": 1, 10 | * "placementGroupList": [ 11 | * { 12 | * "placementGroupNo": "***61", 13 | * "placementGroupName": "test-***", 14 | * "placementGroupType": { 15 | * "code": "AA", 16 | * "codeName": "Anti-Affinity" 17 | * } 18 | * } 19 | * ] 20 | * } 21 | */ 22 | type GetPlacementGroupListResponse = { 23 | requestId: string; 24 | returnCode: number; 25 | returnMessage: string; 26 | totalRows: number; 27 | placementGroupList: Array<{ 28 | placementGroupNo: string; 29 | placementGroupName: string; 30 | placementGroupType: { 31 | code: string; 32 | codeName: string; 33 | }; 34 | }>; 35 | }; 36 | --------------------------------------------------------------------------------