├── .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 |
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 |
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 |
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 |
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 |
16 |
--------------------------------------------------------------------------------
/apps/hub/public/JP.svg:
--------------------------------------------------------------------------------
1 |
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 |
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 |
--------------------------------------------------------------------------------