From eb301176e21ce2cc8e8dabe5e835c8153a4a4fc6 Mon Sep 17 00:00:00 2001 From: tunm4 <8-tunm4_2@users.noreply.git.vngcloud.dev> Date: Sat, 25 May 2024 20:44:46 +0700 Subject: [PATCH 01/14] init --- .terraform.tfstate.lock.info | 1 - build.sh | 13 +- client/client.go | 8 +- client/vks/README.md | 68 ++ client/vks/api/swagger.yaml | 1083 +++++++++++++++++ client/vks/api_v1_cluster_controller.go | 629 ++++++++++ client/vks/api_v1_node_group_controller.go | 641 ++++++++++ .../vks/api_v1_node_group_image_controller.go | 110 ++ client/vks/api_v1_workspace_controller.go | 306 +++++ client/vks/client.go | 482 ++++++++ client/vks/configuration.go | 72 ++ client/vks/docs/ClusterDetailDto.md | 24 + client/vks/docs/ClusterDto.md | 16 + client/vks/docs/CreateClusterComboDto.md | 19 + client/vks/docs/CreateNodeGroupDto.md | 21 + client/vks/docs/NetworkType.md | 8 + client/vks/docs/NodeDto.md | 14 + .../vks/docs/NodeGroupAutoScaleConfigDto.md | 10 + client/vks/docs/NodeGroupDetailDto.md | 26 + client/vks/docs/NodeGroupDto.md | 16 + client/vks/docs/NodeGroupImageDto.md | 12 + client/vks/docs/NodeGroupTaintDto.md | 11 + client/vks/docs/NodeGroupUpgradeConfigDto.md | 11 + client/vks/docs/PagingResultDtoClusterDto.md | 12 + client/vks/docs/PagingResultDtoNodeDto.md | 12 + .../vks/docs/PagingResultDtoNodeGroupDto.md | 12 + client/vks/docs/UpdateClusterDto.md | 10 + client/vks/docs/UpdateNodeGroupDto.md | 13 + client/vks/docs/V1ClusterControllerApi.md | 219 ++++ client/vks/docs/V1NodeGroupControllerApi.md | 231 ++++ .../vks/docs/V1NodeGroupImageControllerApi.md | 30 + client/vks/docs/V1WorkspaceControllerApi.md | 106 ++ client/vks/docs/WorkspaceDto.md | 11 + client/vks/model_cluster_detail_dto.go | 28 + client/vks/model_cluster_dto.go | 20 + client/vks/model_create_cluster_combo_dto.go | 23 + client/vks/model_create_node_group_dto.go | 25 + client/vks/model_network_type.go | 17 + client/vks/model_node_dto.go | 18 + .../model_node_group_auto_scale_config_dto.go | 14 + client/vks/model_node_group_detail_dto.go | 30 + client/vks/model_node_group_dto.go | 20 + client/vks/model_node_group_image_dto.go | 16 + client/vks/model_node_group_taint_dto.go | 15 + .../model_node_group_upgrade_config_dto.go | 15 + .../model_paging_result_dto_cluster_dto.go | 16 + .../vks/model_paging_result_dto_node_dto.go | 16 + .../model_paging_result_dto_node_group_dto.go | 16 + client/vks/model_update_cluster_dto.go | 14 + client/vks/model_update_node_group_dto.go | 17 + client/vks/model_workspace_dto.go | 15 + client/vks/response.go | 42 + provider/provider.go | 16 +- resource/vks/config.go | 11 + resource/vks/resource_cluster.go | 505 ++++++++ resource/vks/resrouce_cluster_node_group.go | 291 +++++ resource/vks/util.go | 44 + terraform_run_with_debug.sh | 16 - 58 files changed, 5492 insertions(+), 25 deletions(-) delete mode 100644 .terraform.tfstate.lock.info create mode 100644 client/vks/README.md create mode 100644 client/vks/api/swagger.yaml create mode 100644 client/vks/api_v1_cluster_controller.go create mode 100644 client/vks/api_v1_node_group_controller.go create mode 100644 client/vks/api_v1_node_group_image_controller.go create mode 100644 client/vks/api_v1_workspace_controller.go create mode 100644 client/vks/client.go create mode 100644 client/vks/configuration.go create mode 100644 client/vks/docs/ClusterDetailDto.md create mode 100644 client/vks/docs/ClusterDto.md create mode 100644 client/vks/docs/CreateClusterComboDto.md create mode 100644 client/vks/docs/CreateNodeGroupDto.md create mode 100644 client/vks/docs/NetworkType.md create mode 100644 client/vks/docs/NodeDto.md create mode 100644 client/vks/docs/NodeGroupAutoScaleConfigDto.md create mode 100644 client/vks/docs/NodeGroupDetailDto.md create mode 100644 client/vks/docs/NodeGroupDto.md create mode 100644 client/vks/docs/NodeGroupImageDto.md create mode 100644 client/vks/docs/NodeGroupTaintDto.md create mode 100644 client/vks/docs/NodeGroupUpgradeConfigDto.md create mode 100644 client/vks/docs/PagingResultDtoClusterDto.md create mode 100644 client/vks/docs/PagingResultDtoNodeDto.md create mode 100644 client/vks/docs/PagingResultDtoNodeGroupDto.md create mode 100644 client/vks/docs/UpdateClusterDto.md create mode 100644 client/vks/docs/UpdateNodeGroupDto.md create mode 100644 client/vks/docs/V1ClusterControllerApi.md create mode 100644 client/vks/docs/V1NodeGroupControllerApi.md create mode 100644 client/vks/docs/V1NodeGroupImageControllerApi.md create mode 100644 client/vks/docs/V1WorkspaceControllerApi.md create mode 100644 client/vks/docs/WorkspaceDto.md create mode 100644 client/vks/model_cluster_detail_dto.go create mode 100644 client/vks/model_cluster_dto.go create mode 100644 client/vks/model_create_cluster_combo_dto.go create mode 100644 client/vks/model_create_node_group_dto.go create mode 100644 client/vks/model_network_type.go create mode 100644 client/vks/model_node_dto.go create mode 100644 client/vks/model_node_group_auto_scale_config_dto.go create mode 100644 client/vks/model_node_group_detail_dto.go create mode 100644 client/vks/model_node_group_dto.go create mode 100644 client/vks/model_node_group_image_dto.go create mode 100644 client/vks/model_node_group_taint_dto.go create mode 100644 client/vks/model_node_group_upgrade_config_dto.go create mode 100644 client/vks/model_paging_result_dto_cluster_dto.go create mode 100644 client/vks/model_paging_result_dto_node_dto.go create mode 100644 client/vks/model_paging_result_dto_node_group_dto.go create mode 100644 client/vks/model_update_cluster_dto.go create mode 100644 client/vks/model_update_node_group_dto.go create mode 100644 client/vks/model_workspace_dto.go create mode 100644 client/vks/response.go create mode 100644 resource/vks/config.go create mode 100644 resource/vks/resource_cluster.go create mode 100644 resource/vks/resrouce_cluster_node_group.go create mode 100644 resource/vks/util.go delete mode 100755 terraform_run_with_debug.sh diff --git a/.terraform.tfstate.lock.info b/.terraform.tfstate.lock.info deleted file mode 100644 index f69078b..0000000 --- a/.terraform.tfstate.lock.info +++ /dev/null @@ -1 +0,0 @@ -{"ID":"ce8a6c85-724a-2103-76d4-17478b531b03","Operation":"OperationTypeApply","Info":"","Who":"duy@duy-ThinkPad-T460","Version":"1.3.5","Created":"2023-02-08T09:12:08.869515269Z","Path":"terraform.tfstate"} \ No newline at end of file diff --git a/build.sh b/build.sh index 646bda0..048bee5 100755 --- a/build.sh +++ b/build.sh @@ -1,16 +1,17 @@ #bin/bash #export TF_LOG=debug rm -rf .terraform -rm -r .terraform.lock.hcl +rm -rf .terraform.* +#rm -rf terraform.* go build -o terraform-provider-vngcloud #OS_ARCH="$(go env GOHOSTOS)_$(go env GOHOSTARCH)" -OS_ARCH="linux_amd64" +OS_ARCH="darwin_amd64" echo $OS_ARCH #rm -rf ~/.terraform.d/plugins/vngcloud.vn/terraform/vngcloud/0.2 #mkdir -p ~/.terraform.d/plugins/vngcloud.vn/terraform/vngcloud/0.2/$OS_ARCH #mv terraform-provider-vngcloud ~/.terraform.d/plugins/vngcloud.vn/terraform/vngcloud/0.2/$OS_ARCH -rm -rf ~/.terraform.d/plugins/registry.terraform.tunm4/vngcloud/vngcloud/0.2 -mkdir -p ~/.terraform.d/plugins/registry.terraform.tunm4/vngcloud/vngcloud/0.2/$OS_ARCH -mv terraform-provider-vngcloud ~/.terraform.d/plugins/registry.terraform.tunm4/vngcloud/vngcloud/0.2/$OS_ARCH -#terraform init +rm -rf ~/.terraform.d/plugins/registry.terraform.tunm4/vngcloud/vngcloud/1.0.0 +mkdir -p ~/.terraform.d/plugins/registry.terraform.tunm4/vngcloud/vngcloud/1.0.0/$OS_ARCH +mv terraform-provider-vngcloud ~/.terraform.d/plugins/registry.terraform.tunm4/vngcloud/vngcloud/1.0.0/$OS_ARCH +terraform init #terraform apply \ No newline at end of file diff --git a/client/client.go b/client/client.go index 4ce5af0..4ddc8d8 100644 --- a/client/client.go +++ b/client/client.go @@ -3,6 +3,7 @@ package client import ( "github.com/vngcloud/terraform-provider-vngcloud/client/authen" "github.com/vngcloud/terraform-provider-vngcloud/client/vdb" + "github.com/vngcloud/terraform-provider-vngcloud/client/vks" "github.com/vngcloud/terraform-provider-vngcloud/client/vloadbalancing" "github.com/vngcloud/terraform-provider-vngcloud/client/vserver" ) @@ -12,6 +13,7 @@ type Client struct { VserverClient *vserver.APIClient VdbClient *vdb.APIClient VlbClient *vloadbalancing.APIClient + VksClient *vks.APIClient ProjectId string } @@ -43,7 +45,7 @@ func NewClient(vdbBaseURL string, vserverBaseURL string, vlbBaseURL string, proj return client, nil } -func NewClientV2(vserverBaseURL string, vlbBaseURL string, ClientID string, ClientSecret string, TokenURL string) (*Client, error) { +func NewClientV2(vserverBaseURL string, vlbBaseURL string, vksBaseURL string, ClientID string, ClientSecret string, TokenURL string) (*Client, error) { authenConfig := authen.NewConfiguration(ClientID, ClientSecret, TokenURL) authenClient, err := authen.NewAuthenClient(authenConfig) if err != nil { @@ -56,10 +58,14 @@ func NewClientV2(vserverBaseURL string, vlbBaseURL string, ClientID string, Clie vlbConfig := vloadbalancing.NewConfiguration(vlbBaseURL, authenClient.Client) vlbClient := vloadbalancing.NewAPIClient(vlbConfig) + vksConfig := vks.NewConfiguration(vksBaseURL, authenClient.Client) + vksClient := vks.NewAPIClient(vksConfig) + client := &Client{ AuthenClient: authenClient, VserverClient: vserverClient, VdbClient: nil, + VksClient: vksClient, VlbClient: vlbClient, ProjectId: "projectId", } diff --git a/client/vks/README.md b/client/vks/README.md new file mode 100644 index 0000000..fdcb2fc --- /dev/null +++ b/client/vks/README.md @@ -0,0 +1,68 @@ +# Go API client for swagger + +No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + +## Overview +This API client was generated by the [swagger-codegen](https://github.com/swagger-api/swagger-codegen) project. By using the [swagger-spec](https://github.com/swagger-api/swagger-spec) from a remote server, you can easily generate an API client. + +- API version: 1.0-SNAPSHOT +- Package version: 1.0.0 +- Build package: io.swagger.codegen.v3.generators.go.GoClientCodegen + +## Installation +Put the package under your project folder and add the following in import: +```golang +import "./swagger" +``` + +## Documentation for API Endpoints + +All URIs are relative to */* + +Class | Method | HTTP request | Description +------------ | ------------- | ------------- | ------------- +*V1ClusterControllerApi* | [**V1ClustersClusterIdDelete**](docs/V1ClusterControllerApi.md#v1clustersclusteriddelete) | **Delete** /v1/clusters/{clusterId} | +*V1ClusterControllerApi* | [**V1ClustersClusterIdGet**](docs/V1ClusterControllerApi.md#v1clustersclusteridget) | **Get** /v1/clusters/{clusterId} | +*V1ClusterControllerApi* | [**V1ClustersClusterIdKubeconfigGet**](docs/V1ClusterControllerApi.md#v1clustersclusteridkubeconfigget) | **Get** /v1/clusters/{clusterId}/kubeconfig | +*V1ClusterControllerApi* | [**V1ClustersClusterIdPut**](docs/V1ClusterControllerApi.md#v1clustersclusteridput) | **Put** /v1/clusters/{clusterId} | +*V1ClusterControllerApi* | [**V1ClustersGet**](docs/V1ClusterControllerApi.md#v1clustersget) | **Get** /v1/clusters | +*V1ClusterControllerApi* | [**V1ClustersPost**](docs/V1ClusterControllerApi.md#v1clusterspost) | **Post** /v1/clusters | +*V1NodeGroupControllerApi* | [**V1ClustersClusterIdNodeGroupsGet**](docs/V1NodeGroupControllerApi.md#v1clustersclusteridnodegroupsget) | **Get** /v1/clusters/{clusterId}/node-groups | +*V1NodeGroupControllerApi* | [**V1ClustersClusterIdNodeGroupsNodeGroupIdDelete**](docs/V1NodeGroupControllerApi.md#v1clustersclusteridnodegroupsnodegroupiddelete) | **Delete** /v1/clusters/{clusterId}/node-groups/{nodeGroupId} | +*V1NodeGroupControllerApi* | [**V1ClustersClusterIdNodeGroupsNodeGroupIdGet**](docs/V1NodeGroupControllerApi.md#v1clustersclusteridnodegroupsnodegroupidget) | **Get** /v1/clusters/{clusterId}/node-groups/{nodeGroupId} | +*V1NodeGroupControllerApi* | [**V1ClustersClusterIdNodeGroupsNodeGroupIdNodesGet**](docs/V1NodeGroupControllerApi.md#v1clustersclusteridnodegroupsnodegroupidnodesget) | **Get** /v1/clusters/{clusterId}/node-groups/{nodeGroupId}/nodes | +*V1NodeGroupControllerApi* | [**V1ClustersClusterIdNodeGroupsNodeGroupIdPut**](docs/V1NodeGroupControllerApi.md#v1clustersclusteridnodegroupsnodegroupidput) | **Put** /v1/clusters/{clusterId}/node-groups/{nodeGroupId} | +*V1NodeGroupControllerApi* | [**V1ClustersClusterIdNodeGroupsPost**](docs/V1NodeGroupControllerApi.md#v1clustersclusteridnodegroupspost) | **Post** /v1/clusters/{clusterId}/node-groups | +*V1NodeGroupImageControllerApi* | [**V1NodeGroupImagesGet**](docs/V1NodeGroupImageControllerApi.md#v1nodegroupimagesget) | **Get** /v1/node-group-images | +*V1WorkspaceControllerApi* | [**V1WorkspaceGet**](docs/V1WorkspaceControllerApi.md#v1workspaceget) | **Get** /v1/workspace | +*V1WorkspaceControllerApi* | [**V1WorkspacePost**](docs/V1WorkspaceControllerApi.md#v1workspacepost) | **Post** /v1/workspace | +*V1WorkspaceControllerApi* | [**V1WorkspaceResetServiceAccountPost**](docs/V1WorkspaceControllerApi.md#v1workspaceresetserviceaccountpost) | **Post** /v1/workspace/reset-service-account | + +## Documentation For Models + + - [ClusterDetailDto](docs/ClusterDetailDto.md) + - [ClusterDto](docs/ClusterDto.md) + - [CreateClusterComboDto](docs/CreateClusterComboDto.md) + - [CreateNodeGroupDto](docs/CreateNodeGroupDto.md) + - [NetworkType](docs/NetworkType.md) + - [NodeDto](docs/NodeDto.md) + - [NodeGroupAutoScaleConfigDto](docs/NodeGroupAutoScaleConfigDto.md) + - [NodeGroupDetailDto](docs/NodeGroupDetailDto.md) + - [NodeGroupDto](docs/NodeGroupDto.md) + - [NodeGroupImageDto](docs/NodeGroupImageDto.md) + - [NodeGroupTaintDto](docs/NodeGroupTaintDto.md) + - [NodeGroupUpgradeConfigDto](docs/NodeGroupUpgradeConfigDto.md) + - [PagingResultDtoClusterDto](docs/PagingResultDtoClusterDto.md) + - [PagingResultDtoNodeDto](docs/PagingResultDtoNodeDto.md) + - [PagingResultDtoNodeGroupDto](docs/PagingResultDtoNodeGroupDto.md) + - [UpdateClusterDto](docs/UpdateClusterDto.md) + - [UpdateNodeGroupDto](docs/UpdateNodeGroupDto.md) + - [WorkspaceDto](docs/WorkspaceDto.md) + +## Documentation For Authorization + Endpoints do not require authorization. + + +## Author + + diff --git a/client/vks/api/swagger.yaml b/client/vks/api/swagger.yaml new file mode 100644 index 0000000..71f857d --- /dev/null +++ b/client/vks/api/swagger.yaml @@ -0,0 +1,1083 @@ +openapi: 3.0.3 +info: + title: vks-api API + version: 1.0-SNAPSHOT +servers: +- url: / +paths: + /v1/clusters: + get: + tags: + - V 1 Cluster Controller + parameters: + - name: filter + in: query + required: false + style: form + explode: true + schema: + type: string + default: "{}" + - name: page + in: query + required: false + style: form + explode: true + schema: + minimum: 0 + type: integer + format: int32 + default: 0 + - name: pageSize + in: query + required: false + style: form + explode: true + schema: + minimum: 1 + type: integer + format: int32 + default: 10 + - name: portal-user-id + in: header + required: false + style: simple + explode: false + schema: + type: integer + format: int64 + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/PagingResultDtoClusterDto' + post: + tags: + - V 1 Cluster Controller + parameters: + - name: poc + in: query + required: false + style: form + explode: true + schema: + type: boolean + default: false + - name: portal-user-id + in: header + required: false + style: simple + explode: false + schema: + type: integer + format: int64 + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CreateClusterComboDto' + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/ClusterDto' + /v1/clusters/{clusterId}: + get: + tags: + - V 1 Cluster Controller + parameters: + - name: clusterId + in: path + required: true + style: simple + explode: false + schema: + type: string + - name: portal-user-id + in: header + required: false + style: simple + explode: false + schema: + type: integer + format: int64 + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/ClusterDetailDto' + put: + tags: + - V 1 Cluster Controller + parameters: + - name: clusterId + in: path + required: true + style: simple + explode: false + schema: + type: string + - name: portal-user-id + in: header + required: false + style: simple + explode: false + schema: + type: integer + format: int64 + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateClusterDto' + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/ClusterDto' + delete: + tags: + - V 1 Cluster Controller + parameters: + - name: clusterId + in: path + required: true + style: simple + explode: false + schema: + type: string + - name: portal-user-id + in: header + required: false + style: simple + explode: false + schema: + type: integer + format: int64 + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/ClusterDto' + /v1/clusters/{clusterId}/kubeconfig: + get: + tags: + - V 1 Cluster Controller + parameters: + - name: clusterId + in: path + required: true + style: simple + explode: false + schema: + type: string + - name: portal-user-id + in: header + required: false + style: simple + explode: false + schema: + type: integer + format: int64 + responses: + "200": + description: OK + content: + text/plain: + schema: + type: string + x-content-type: text/plain + /v1/clusters/{clusterId}/node-groups: + get: + tags: + - V 1 Node Group Controller + parameters: + - name: clusterId + in: path + required: true + style: simple + explode: false + schema: + type: string + - name: page + in: query + required: false + style: form + explode: true + schema: + minimum: 0 + type: integer + format: int32 + default: 0 + - name: pageSize + in: query + required: false + style: form + explode: true + schema: + minimum: 1 + type: integer + format: int32 + default: 10 + - name: portal-user-id + in: header + required: false + style: simple + explode: false + schema: + type: integer + format: int64 + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/PagingResultDtoNodeGroupDto' + post: + tags: + - V 1 Node Group Controller + parameters: + - name: clusterId + in: path + required: true + style: simple + explode: false + schema: + type: string + - name: portal-user-id + in: header + required: false + style: simple + explode: false + schema: + type: integer + format: int64 + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CreateNodeGroupDto' + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/NodeGroupDto' + /v1/clusters/{clusterId}/node-groups/{nodeGroupId}: + get: + tags: + - V 1 Node Group Controller + parameters: + - name: clusterId + in: path + required: true + style: simple + explode: false + schema: + type: string + - name: nodeGroupId + in: path + required: true + style: simple + explode: false + schema: + type: string + - name: portal-user-id + in: header + required: false + style: simple + explode: false + schema: + type: integer + format: int64 + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/NodeGroupDetailDto' + put: + tags: + - V 1 Node Group Controller + parameters: + - name: clusterId + in: path + required: true + style: simple + explode: false + schema: + type: string + - name: nodeGroupId + in: path + required: true + style: simple + explode: false + schema: + type: string + - name: portal-user-id + in: header + required: false + style: simple + explode: false + schema: + type: integer + format: int64 + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateNodeGroupDto' + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/NodeGroupDto' + delete: + tags: + - V 1 Node Group Controller + parameters: + - name: clusterId + in: path + required: true + style: simple + explode: false + schema: + type: string + - name: nodeGroupId + in: path + required: true + style: simple + explode: false + schema: + type: string + - name: portal-user-id + in: header + required: false + style: simple + explode: false + schema: + type: integer + format: int64 + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/NodeGroupDto' + /v1/clusters/{clusterId}/node-groups/{nodeGroupId}/nodes: + get: + tags: + - V 1 Node Group Controller + parameters: + - name: clusterId + in: path + required: true + style: simple + explode: false + schema: + type: string + - name: nodeGroupId + in: path + required: true + style: simple + explode: false + schema: + type: string + - name: page + in: query + required: false + style: form + explode: true + schema: + minimum: 0 + type: integer + format: int32 + default: 0 + - name: pageSize + in: query + required: false + style: form + explode: true + schema: + minimum: 1 + type: integer + format: int32 + default: 10 + - name: portal-user-id + in: header + required: false + style: simple + explode: false + schema: + type: integer + format: int64 + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/PagingResultDtoNodeDto' + /v1/node-group-images: + get: + tags: + - V 1 Node Group Image Controller + responses: + "200": + description: OK + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/NodeGroupImageDto' + x-content-type: application/json + /v1/workspace: + get: + tags: + - V 1 Workspace Controller + parameters: + - name: portal-user-id + in: header + required: false + style: simple + explode: false + schema: + type: integer + format: int64 + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/WorkspaceDto' + post: + tags: + - V 1 Workspace Controller + parameters: + - name: portal-user-id + in: header + required: false + style: simple + explode: false + schema: + type: integer + format: int64 + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/WorkspaceDto' + /v1/workspace/reset-service-account: + post: + tags: + - V 1 Workspace Controller + parameters: + - name: portal-user-id + in: header + required: false + style: simple + explode: false + schema: + type: integer + format: int64 + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/WorkspaceDto' +components: + schemas: + ClusterDetailDto: + type: object + properties: + id: + type: string + name: + type: string + description: + type: string + status: + type: string + version: + type: string + numNodes: + type: integer + format: int64 + createdAt: + $ref: '#/components/schemas/Date' + updatedAt: + $ref: '#/components/schemas/Date' + enablePrivateCluster: + type: boolean + networkType: + $ref: '#/components/schemas/NetworkType' + vpcId: + type: string + subnetId: + type: string + cidr: + type: string + enabledLoadBalancerPlugin: + type: boolean + enabledBlockStoreCsiPlugin: + type: boolean + whitelistNodeCIDRs: + type: array + items: + type: string + example: + subnetId: subnetId + enabledBlockStoreCsiPlugin: true + enabledLoadBalancerPlugin: true + whitelistNodeCIDRs: + - whitelistNodeCIDRs + - whitelistNodeCIDRs + description: description + version: version + createdAt: 2022-03-10T00:00:00.000+00:00 + numNodes: 0 + vpcId: vpcId + name: name + cidr: cidr + id: id + networkType: CALICO + enablePrivateCluster: true + status: status + updatedAt: null + ClusterDto: + type: object + properties: + id: + type: string + name: + type: string + description: + type: string + status: + type: string + version: + type: string + numNodes: + type: integer + format: int64 + createdAt: + $ref: '#/components/schemas/Date' + updatedAt: + $ref: '#/components/schemas/Date' + example: + createdAt: 2022-03-10T00:00:00.000+00:00 + numNodes: 0 + name: name + description: description + id: id + version: version + status: status + updatedAt: null + CreateClusterComboDto: + required: + - cidr + - enablePrivateCluster + - name + - networkType + - nodeGroups + - subnetId + - version + - vpcId + type: object + properties: + name: + pattern: "^[a-zA-Z0-9_\\-.]{5,50}$" + type: string + description: + pattern: "^[a-zA-Z0-9_\\-. @]{0,255}$" + type: string + version: + pattern: "^v[0-9]+.[0-9]+.[0-9]+$" + type: string + enablePrivateCluster: + type: boolean + networkType: + pattern: ^CALICO$ + type: string + vpcId: + maxLength: 50 + minLength: 1 + type: string + subnetId: + maxLength: 50 + minLength: 1 + type: string + cidr: + pattern: "^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}/\\d{1,2}$" + type: string + enabledLoadBalancerPlugin: + type: boolean + enabledBlockStoreCsiPlugin: + type: boolean + nodeGroups: + maxItems: 100 + minItems: 1 + type: array + items: + $ref: '#/components/schemas/CreateNodeGroupDto' + CreateNodeGroupDto: + required: + - diskSize + - diskType + - enablePrivateNodes + - flavorId + - imageId + - name + - numNodes + - securityGroups + - sshKeyId + - upgradeConfig + type: object + properties: + name: + maxLength: 50 + minLength: 5 + pattern: "^[a-zA-Z0-9_\\-.]+$" + type: string + numNodes: + maximum: 100 + minimum: 1 + type: integer + format: int32 + autoScaleConfig: + $ref: '#/components/schemas/NodeGroupAutoScaleConfigDto' + upgradeConfig: + $ref: '#/components/schemas/NodeGroupUpgradeConfigDto' + imageId: + maxLength: 50 + minLength: 1 + type: string + flavorId: + maxLength: 50 + minLength: 1 + type: string + diskSize: + maximum: 5000 + minimum: 20 + type: integer + format: int32 + diskType: + maxLength: 50 + minLength: 1 + type: string + enablePrivateNodes: + type: boolean + securityGroups: + type: array + items: + type: string + sshKeyId: + maxLength: 50 + minLength: 1 + type: string + labels: + type: object + additionalProperties: + type: string + taints: + maxItems: 50 + type: array + items: + $ref: '#/components/schemas/NodeGroupTaintDto' + Date: + type: string + format: date + example: 2022-03-10 + NetworkType: + type: string + enum: + - CALICO + - CILIUM + NodeDto: + type: object + properties: + id: + type: string + name: + type: string + status: + type: string + floatingIp: + type: string + fixedIp: + type: string + ready: + type: boolean + example: + floatingIp: floatingIp + ready: true + name: name + fixedIp: fixedIp + id: id + status: status + NodeGroupAutoScaleConfigDto: + required: + - maxSize + - minSize + type: object + properties: + minSize: + maximum: 100 + minimum: 1 + type: integer + format: int32 + maxSize: + maximum: 100 + minimum: 1 + type: integer + format: int32 + example: + minSize: 15 + maxSize: 60 + NodeGroupDetailDto: + type: object + properties: + id: + type: string + clusterId: + type: string + name: + type: string + status: + type: string + numNodes: + type: integer + format: int64 + imageId: + type: string + createdAt: + $ref: '#/components/schemas/Date' + updatedAt: + $ref: '#/components/schemas/Date' + flavorId: + type: string + diskSize: + type: integer + format: int32 + diskType: + type: string + enablePrivateNodes: + type: boolean + sshKeyId: + type: string + securityGroups: + type: array + items: + type: string + autoScaleConfig: + $ref: '#/components/schemas/NodeGroupAutoScaleConfigDto' + upgradeConfig: + $ref: '#/components/schemas/NodeGroupUpgradeConfigDto' + labels: + type: object + additionalProperties: + type: string + taints: + type: array + items: + $ref: '#/components/schemas/NodeGroupTaintDto' + example: + imageId: imageId + enablePrivateNodes: true + autoScaleConfig: + minSize: 15 + maxSize: 60 + flavorId: flavorId + clusterId: clusterId + taints: + - effect: effect + value: value + key: key + - effect: effect + value: value + key: key + sshKeyId: sshKeyId + upgradeConfig: + maxSurge: 56 + maxUnavailable: 23 + strategy: strategy + labels: + key: labels + createdAt: 2022-03-10T00:00:00.000+00:00 + numNodes: 0 + diskSize: 6 + name: name + securityGroups: + - securityGroups + - securityGroups + id: id + diskType: diskType + status: status + updatedAt: null + NodeGroupDto: + type: object + properties: + id: + type: string + clusterId: + type: string + name: + type: string + status: + type: string + numNodes: + type: integer + format: int64 + imageId: + type: string + createdAt: + $ref: '#/components/schemas/Date' + updatedAt: + $ref: '#/components/schemas/Date' + example: + createdAt: 2022-03-10T00:00:00.000+00:00 + numNodes: 0 + imageId: imageId + name: name + id: id + clusterId: clusterId + status: status + updatedAt: null + NodeGroupImageDto: + type: object + properties: + id: + type: string + os: + type: string + kubernetesVersion: + type: string + enable: + type: boolean + example: + os: os + enable: true + id: id + kubernetesVersion: kubernetesVersion + NodeGroupTaintDto: + required: + - effect + - key + - value + type: object + properties: + key: + pattern: "^([a-zA-Z0-9]([a-zA-Z0-9._\\-/][a-zA-Z0-9])?){1,63}$" + type: string + value: + pattern: "^[a-zA-Z0-9._\\-/]{1,63}$" + type: string + effect: + pattern: ^NoSchedule|PreferNoSchedule|NoExecute$ + type: string + example: + effect: effect + value: value + key: key + NodeGroupUpgradeConfigDto: + required: + - strategy + type: object + properties: + strategy: + pattern: ^SURGE$ + type: string + maxSurge: + maximum: 100 + minimum: 1 + type: integer + format: int32 + maxUnavailable: + maximum: 100 + minimum: 0 + type: integer + format: int32 + example: + maxSurge: 56 + maxUnavailable: 23 + strategy: strategy + PagingResultDtoClusterDto: + type: object + properties: + items: + type: array + items: + $ref: '#/components/schemas/ClusterDto' + total: + type: integer + format: int64 + page: + type: integer + format: int32 + pageSize: + type: integer + format: int32 + example: + total: 6 + pageSize: 5 + page: 1 + items: + - createdAt: 2022-03-10T00:00:00.000+00:00 + numNodes: 0 + name: name + description: description + id: id + version: version + status: status + updatedAt: null + - createdAt: 2022-03-10T00:00:00.000+00:00 + numNodes: 0 + name: name + description: description + id: id + version: version + status: status + updatedAt: null + PagingResultDtoNodeDto: + type: object + properties: + items: + type: array + items: + $ref: '#/components/schemas/NodeDto' + total: + type: integer + format: int64 + page: + type: integer + format: int32 + pageSize: + type: integer + format: int32 + example: + total: 0 + pageSize: 1 + page: 6 + items: + - floatingIp: floatingIp + ready: true + name: name + fixedIp: fixedIp + id: id + status: status + - floatingIp: floatingIp + ready: true + name: name + fixedIp: fixedIp + id: id + status: status + PagingResultDtoNodeGroupDto: + type: object + properties: + items: + type: array + items: + $ref: '#/components/schemas/NodeGroupDto' + total: + type: integer + format: int64 + page: + type: integer + format: int32 + pageSize: + type: integer + format: int32 + example: + total: 6 + pageSize: 5 + page: 1 + items: + - createdAt: 2022-03-10T00:00:00.000+00:00 + numNodes: 0 + imageId: imageId + name: name + id: id + clusterId: clusterId + status: status + updatedAt: null + - createdAt: 2022-03-10T00:00:00.000+00:00 + numNodes: 0 + imageId: imageId + name: name + id: id + clusterId: clusterId + status: status + updatedAt: null + UpdateClusterDto: + required: + - version + - whitelistNodeCIDRs + type: object + properties: + version: + type: string + whitelistNodeCIDRs: + maxItems: 10 + minItems: 1 + type: array + items: + type: string + UpdateNodeGroupDto: + required: + - imageId + - securityGroups + - upgradeConfig + type: object + properties: + autoScaleConfig: + $ref: '#/components/schemas/NodeGroupAutoScaleConfigDto' + numNodes: + maximum: 100 + minimum: 1 + type: integer + format: int64 + upgradeConfig: + $ref: '#/components/schemas/NodeGroupUpgradeConfigDto' + securityGroups: + type: array + items: + type: string + imageId: + maxLength: 50 + minLength: 1 + type: string + WorkspaceDto: + type: object + properties: + projectId: + type: string + serviceAccountId: + type: string + status: + type: string + example: + serviceAccountId: serviceAccountId + projectId: projectId + status: status diff --git a/client/vks/api_v1_cluster_controller.go b/client/vks/api_v1_cluster_controller.go new file mode 100644 index 0000000..3d84832 --- /dev/null +++ b/client/vks/api_v1_cluster_controller.go @@ -0,0 +1,629 @@ +/* + * vks-api API + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 1.0-SNAPSHOT + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ +package vks + +import ( + "bytes" + "context" + "fmt" + "github.com/antihax/optional" + "io/ioutil" + "net/http" + "net/url" + "strings" +) + +// Linger please +var ( + _ context.Context +) + +type V1ClusterControllerApiService service + +/* +V1ClusterControllerApiService + * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + * @param clusterId + * @param optional nil or *V1ClusterControllerApiV1ClustersClusterIdDeleteOpts - Optional Parameters: + * @param "PortalUserId" (optional.Int64) - +@return ClusterDto +*/ + +type V1ClusterControllerApiV1ClustersClusterIdDeleteOpts struct { + PortalUserId optional.Int64 +} + +func (a *V1ClusterControllerApiService) V1ClustersClusterIdDelete(ctx context.Context, clusterId string, localVarOptionals *V1ClusterControllerApiV1ClustersClusterIdDeleteOpts) (ClusterDto, *http.Response, error) { + var ( + localVarHttpMethod = strings.ToUpper("Delete") + localVarPostBody interface{} + localVarFileName string + localVarFileBytes []byte + localVarReturnValue ClusterDto + ) + + // create path and map variables + localVarPath := a.client.cfg.BasePath + "/v1/clusters/{clusterId}" + localVarPath = strings.Replace(localVarPath, "{"+"clusterId"+"}", fmt.Sprintf("%v", clusterId), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHttpContentTypes := []string{} + + // set Content-Type header + localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes) + if localVarHttpContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHttpContentType + } + + // to determine the Accept header + localVarHttpHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts) + if localVarHttpHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHttpHeaderAccept + } + if localVarOptionals != nil && localVarOptionals.PortalUserId.IsSet() { + localVarHeaderParams["portal-user-id"] = parameterToString(localVarOptionals.PortalUserId.Value(), "") + } + r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHttpResponse, err := a.client.callAPI(r) + if err != nil || localVarHttpResponse == nil { + return localVarReturnValue, localVarHttpResponse, err + } + + localVarBody, _ := ioutil.ReadAll(localVarHttpResponse.Body) + localVarHttpResponse.Body = ioutil.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHttpResponse, err + } + + if localVarHttpResponse.StatusCode < 300 { + // If we succeed, return the data, otherwise pass on to decode error. + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err == nil { + return localVarReturnValue, localVarHttpResponse, err + } + } + + if localVarHttpResponse.StatusCode >= 300 { + newErr := GenericSwaggerError{ + body: localVarBody, + error: localVarHttpResponse.Status, + } + if localVarHttpResponse.StatusCode == 200 { + var v ClusterDto + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + return localVarReturnValue, localVarHttpResponse, newErr + } + + return localVarReturnValue, localVarHttpResponse, nil +} + +/* +V1ClusterControllerApiService + * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + * @param clusterId + * @param optional nil or *V1ClusterControllerApiV1ClustersClusterIdGetOpts - Optional Parameters: + * @param "PortalUserId" (optional.Int64) - +@return ClusterDetailDto +*/ + +type V1ClusterControllerApiV1ClustersClusterIdGetOpts struct { + PortalUserId optional.Int64 +} + +func (a *V1ClusterControllerApiService) V1ClustersClusterIdGet(ctx context.Context, clusterId string, localVarOptionals *V1ClusterControllerApiV1ClustersClusterIdGetOpts) (ClusterDetailDto, *http.Response, error) { + var ( + localVarHttpMethod = strings.ToUpper("Get") + localVarPostBody interface{} + localVarFileName string + localVarFileBytes []byte + localVarReturnValue ClusterDetailDto + ) + + // create path and map variables + localVarPath := a.client.cfg.BasePath + "/v1/clusters/{clusterId}" + localVarPath = strings.Replace(localVarPath, "{"+"clusterId"+"}", fmt.Sprintf("%v", clusterId), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHttpContentTypes := []string{} + + // set Content-Type header + localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes) + if localVarHttpContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHttpContentType + } + + // to determine the Accept header + localVarHttpHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts) + if localVarHttpHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHttpHeaderAccept + } + if localVarOptionals != nil && localVarOptionals.PortalUserId.IsSet() { + localVarHeaderParams["portal-user-id"] = parameterToString(localVarOptionals.PortalUserId.Value(), "") + } + r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHttpResponse, err := a.client.callAPI(r) + if err != nil || localVarHttpResponse == nil { + return localVarReturnValue, localVarHttpResponse, err + } + + localVarBody, _ := ioutil.ReadAll(localVarHttpResponse.Body) + localVarHttpResponse.Body = ioutil.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHttpResponse, err + } + + if localVarHttpResponse.StatusCode < 300 { + // If we succeed, return the data, otherwise pass on to decode error. + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err == nil { + return localVarReturnValue, localVarHttpResponse, err + } + } + + if localVarHttpResponse.StatusCode >= 300 { + newErr := GenericSwaggerError{ + body: localVarBody, + error: localVarHttpResponse.Status, + } + if localVarHttpResponse.StatusCode == 200 { + var v ClusterDetailDto + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + return localVarReturnValue, localVarHttpResponse, newErr + } + + return localVarReturnValue, localVarHttpResponse, nil +} + +/* +V1ClusterControllerApiService + * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + * @param clusterId + * @param optional nil or *V1ClusterControllerApiV1ClustersClusterIdKubeconfigGetOpts - Optional Parameters: + * @param "PortalUserId" (optional.Int64) - +@return string +*/ + +type V1ClusterControllerApiV1ClustersClusterIdKubeconfigGetOpts struct { + PortalUserId optional.Int64 +} + +func (a *V1ClusterControllerApiService) V1ClustersClusterIdKubeconfigGet(ctx context.Context, clusterId string, localVarOptionals *V1ClusterControllerApiV1ClustersClusterIdKubeconfigGetOpts) (string, *http.Response, error) { + var ( + localVarHttpMethod = strings.ToUpper("Get") + localVarPostBody interface{} + localVarFileName string + localVarFileBytes []byte + localVarReturnValue string + ) + + // create path and map variables + localVarPath := a.client.cfg.BasePath + "/v1/clusters/{clusterId}/kubeconfig" + localVarPath = strings.Replace(localVarPath, "{"+"clusterId"+"}", fmt.Sprintf("%v", clusterId), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHttpContentTypes := []string{} + + // set Content-Type header + localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes) + if localVarHttpContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHttpContentType + } + + // to determine the Accept header + localVarHttpHeaderAccepts := []string{"text/plain"} + + // set Accept header + localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts) + if localVarHttpHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHttpHeaderAccept + } + if localVarOptionals != nil && localVarOptionals.PortalUserId.IsSet() { + localVarHeaderParams["portal-user-id"] = parameterToString(localVarOptionals.PortalUserId.Value(), "") + } + r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHttpResponse, err := a.client.callAPI(r) + if err != nil || localVarHttpResponse == nil { + return localVarReturnValue, localVarHttpResponse, err + } + + localVarBody, _ := ioutil.ReadAll(localVarHttpResponse.Body) + localVarHttpResponse.Body = ioutil.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHttpResponse, err + } + + if localVarHttpResponse.StatusCode < 300 { + // If we succeed, return the data, otherwise pass on to decode error. + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err == nil { + return localVarReturnValue, localVarHttpResponse, err + } + } + + if localVarHttpResponse.StatusCode >= 300 { + newErr := GenericSwaggerError{ + body: localVarBody, + error: localVarHttpResponse.Status, + } + if localVarHttpResponse.StatusCode == 200 { + var v string + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + return localVarReturnValue, localVarHttpResponse, newErr + } + + return string(localVarBody), localVarHttpResponse, nil +} + +/* +V1ClusterControllerApiService + * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + * @param clusterId + * @param optional nil or *V1ClusterControllerApiV1ClustersClusterIdPutOpts - Optional Parameters: + * @param "Body" (optional.Interface of UpdateClusterDto) - + * @param "PortalUserId" (optional.Int64) - +@return ClusterDto +*/ + +type V1ClusterControllerApiV1ClustersClusterIdPutOpts struct { + Body optional.Interface + PortalUserId optional.Int64 +} + +func (a *V1ClusterControllerApiService) V1ClustersClusterIdPut(ctx context.Context, clusterId string, localVarOptionals *V1ClusterControllerApiV1ClustersClusterIdPutOpts) (ClusterDto, *http.Response, error) { + var ( + localVarHttpMethod = strings.ToUpper("Put") + localVarPostBody interface{} + localVarFileName string + localVarFileBytes []byte + localVarReturnValue ClusterDto + ) + + // create path and map variables + localVarPath := a.client.cfg.BasePath + "/v1/clusters/{clusterId}" + localVarPath = strings.Replace(localVarPath, "{"+"clusterId"+"}", fmt.Sprintf("%v", clusterId), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHttpContentTypes := []string{"application/json"} + + // set Content-Type header + localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes) + if localVarHttpContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHttpContentType + } + + // to determine the Accept header + localVarHttpHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts) + if localVarHttpHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHttpHeaderAccept + } + if localVarOptionals != nil && localVarOptionals.PortalUserId.IsSet() { + localVarHeaderParams["portal-user-id"] = parameterToString(localVarOptionals.PortalUserId.Value(), "") + } + // body params + if localVarOptionals != nil && localVarOptionals.Body.IsSet() { + + localVarOptionalBody := localVarOptionals.Body.Value() + localVarPostBody = &localVarOptionalBody + } + r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHttpResponse, err := a.client.callAPI(r) + if err != nil || localVarHttpResponse == nil { + return localVarReturnValue, localVarHttpResponse, err + } + + localVarBody, _ := ioutil.ReadAll(localVarHttpResponse.Body) + localVarHttpResponse.Body = ioutil.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHttpResponse, err + } + + if localVarHttpResponse.StatusCode < 300 { + // If we succeed, return the data, otherwise pass on to decode error. + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err == nil { + return localVarReturnValue, localVarHttpResponse, err + } + } + + if localVarHttpResponse.StatusCode >= 300 { + newErr := GenericSwaggerError{ + body: localVarBody, + error: localVarHttpResponse.Status, + } + if localVarHttpResponse.StatusCode == 200 { + var v ClusterDto + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + return localVarReturnValue, localVarHttpResponse, newErr + } + + return localVarReturnValue, localVarHttpResponse, nil +} + +/* +V1ClusterControllerApiService + * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + * @param optional nil or *V1ClusterControllerApiV1ClustersGetOpts - Optional Parameters: + * @param "Filter" (optional.String) - + * @param "Page" (optional.Int32) - + * @param "PageSize" (optional.Int32) - + * @param "PortalUserId" (optional.Int64) - +@return PagingResultDtoClusterDto +*/ + +type V1ClusterControllerApiV1ClustersGetOpts struct { + Filter optional.String + Page optional.Int32 + PageSize optional.Int32 + PortalUserId optional.Int64 +} + +func (a *V1ClusterControllerApiService) V1ClustersGet(ctx context.Context, localVarOptionals *V1ClusterControllerApiV1ClustersGetOpts) (PagingResultDtoClusterDto, *http.Response, error) { + var ( + localVarHttpMethod = strings.ToUpper("Get") + localVarPostBody interface{} + localVarFileName string + localVarFileBytes []byte + localVarReturnValue PagingResultDtoClusterDto + ) + + // create path and map variables + localVarPath := a.client.cfg.BasePath + "/v1/clusters" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + if localVarOptionals != nil && localVarOptionals.Filter.IsSet() { + localVarQueryParams.Add("filter", parameterToString(localVarOptionals.Filter.Value(), "")) + } + if localVarOptionals != nil && localVarOptionals.Page.IsSet() { + localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), "")) + } + if localVarOptionals != nil && localVarOptionals.PageSize.IsSet() { + localVarQueryParams.Add("pageSize", parameterToString(localVarOptionals.PageSize.Value(), "")) + } + // to determine the Content-Type header + localVarHttpContentTypes := []string{} + + // set Content-Type header + localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes) + if localVarHttpContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHttpContentType + } + + // to determine the Accept header + localVarHttpHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts) + if localVarHttpHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHttpHeaderAccept + } + if localVarOptionals != nil && localVarOptionals.PortalUserId.IsSet() { + localVarHeaderParams["portal-user-id"] = parameterToString(localVarOptionals.PortalUserId.Value(), "") + } + r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHttpResponse, err := a.client.callAPI(r) + if err != nil || localVarHttpResponse == nil { + return localVarReturnValue, localVarHttpResponse, err + } + + localVarBody, _ := ioutil.ReadAll(localVarHttpResponse.Body) + localVarHttpResponse.Body = ioutil.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHttpResponse, err + } + + if localVarHttpResponse.StatusCode < 300 { + // If we succeed, return the data, otherwise pass on to decode error. + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err == nil { + return localVarReturnValue, localVarHttpResponse, err + } + } + + if localVarHttpResponse.StatusCode >= 300 { + newErr := GenericSwaggerError{ + body: localVarBody, + error: localVarHttpResponse.Status, + } + if localVarHttpResponse.StatusCode == 200 { + var v PagingResultDtoClusterDto + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + return localVarReturnValue, localVarHttpResponse, newErr + } + + return localVarReturnValue, localVarHttpResponse, nil +} + +/* +V1ClusterControllerApiService + * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + * @param optional nil or *V1ClusterControllerApiV1ClustersPostOpts - Optional Parameters: + * @param "Body" (optional.Interface of CreateClusterComboDto) - + * @param "PortalUserId" (optional.Int64) - + * @param "Poc" (optional.Bool) - +@return ClusterDto +*/ + +type V1ClusterControllerApiV1ClustersPostOpts struct { + Body optional.Interface + PortalUserId optional.Int64 + Poc optional.Bool +} + +func (a *V1ClusterControllerApiService) V1ClustersPost(ctx context.Context, localVarOptionals *V1ClusterControllerApiV1ClustersPostOpts) (ClusterDto, *http.Response, error) { + var ( + localVarHttpMethod = strings.ToUpper("Post") + localVarPostBody interface{} + localVarFileName string + localVarFileBytes []byte + localVarReturnValue ClusterDto + ) + + // create path and map variables + localVarPath := a.client.cfg.BasePath + "/v1/clusters" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + if localVarOptionals != nil && localVarOptionals.Poc.IsSet() { + localVarQueryParams.Add("poc", parameterToString(localVarOptionals.Poc.Value(), "")) + } + // to determine the Content-Type header + localVarHttpContentTypes := []string{"application/json"} + + // set Content-Type header + localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes) + if localVarHttpContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHttpContentType + } + + // to determine the Accept header + localVarHttpHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts) + if localVarHttpHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHttpHeaderAccept + } + if localVarOptionals != nil && localVarOptionals.PortalUserId.IsSet() { + localVarHeaderParams["portal-user-id"] = parameterToString(localVarOptionals.PortalUserId.Value(), "") + } + // body params + if localVarOptionals != nil && localVarOptionals.Body.IsSet() { + + localVarOptionalBody := localVarOptionals.Body.Value() + localVarPostBody = &localVarOptionalBody + } + r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHttpResponse, err := a.client.callAPI(r) + if err != nil || localVarHttpResponse == nil { + return localVarReturnValue, localVarHttpResponse, err + } + + localVarBody, _ := ioutil.ReadAll(localVarHttpResponse.Body) + localVarHttpResponse.Body = ioutil.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHttpResponse, err + } + + if localVarHttpResponse.StatusCode < 300 { + // If we succeed, return the data, otherwise pass on to decode error. + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err == nil { + return localVarReturnValue, localVarHttpResponse, err + } + } + + if localVarHttpResponse.StatusCode >= 300 { + newErr := GenericSwaggerError{ + body: localVarBody, + error: localVarHttpResponse.Status, + } + if localVarHttpResponse.StatusCode == 200 { + var v ClusterDto + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + return localVarReturnValue, localVarHttpResponse, newErr + } + + return localVarReturnValue, localVarHttpResponse, nil +} diff --git a/client/vks/api_v1_node_group_controller.go b/client/vks/api_v1_node_group_controller.go new file mode 100644 index 0000000..dc5fe34 --- /dev/null +++ b/client/vks/api_v1_node_group_controller.go @@ -0,0 +1,641 @@ +/* + * vks-api API + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 1.0-SNAPSHOT + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ +package vks + +import ( + "bytes" + "context" + "fmt" + "github.com/antihax/optional" + "io/ioutil" + "net/http" + "net/url" + "strings" +) + +// Linger please +var ( + _ context.Context +) + +type V1NodeGroupControllerApiService service + +/* +V1NodeGroupControllerApiService + * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + * @param clusterId + * @param optional nil or *V1NodeGroupControllerApiV1ClustersClusterIdNodeGroupsGetOpts - Optional Parameters: + * @param "Page" (optional.Int32) - + * @param "PageSize" (optional.Int32) - + * @param "PortalUserId" (optional.Int64) - +@return PagingResultDtoNodeGroupDto +*/ + +type V1NodeGroupControllerApiV1ClustersClusterIdNodeGroupsGetOpts struct { + Page optional.Int32 + PageSize optional.Int32 + PortalUserId optional.Int64 +} + +func (a *V1NodeGroupControllerApiService) V1ClustersClusterIdNodeGroupsGet(ctx context.Context, clusterId string, localVarOptionals *V1NodeGroupControllerApiV1ClustersClusterIdNodeGroupsGetOpts) (PagingResultDtoNodeGroupDto, *http.Response, error) { + var ( + localVarHttpMethod = strings.ToUpper("Get") + localVarPostBody interface{} + localVarFileName string + localVarFileBytes []byte + localVarReturnValue PagingResultDtoNodeGroupDto + ) + + // create path and map variables + localVarPath := a.client.cfg.BasePath + "/v1/clusters/{clusterId}/node-groups" + localVarPath = strings.Replace(localVarPath, "{"+"clusterId"+"}", fmt.Sprintf("%v", clusterId), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + if localVarOptionals != nil && localVarOptionals.Page.IsSet() { + localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), "")) + } + if localVarOptionals != nil && localVarOptionals.PageSize.IsSet() { + localVarQueryParams.Add("pageSize", parameterToString(localVarOptionals.PageSize.Value(), "")) + } + // to determine the Content-Type header + localVarHttpContentTypes := []string{} + + // set Content-Type header + localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes) + if localVarHttpContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHttpContentType + } + + // to determine the Accept header + localVarHttpHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts) + if localVarHttpHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHttpHeaderAccept + } + if localVarOptionals != nil && localVarOptionals.PortalUserId.IsSet() { + localVarHeaderParams["portal-user-id"] = parameterToString(localVarOptionals.PortalUserId.Value(), "") + } + r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHttpResponse, err := a.client.callAPI(r) + if err != nil || localVarHttpResponse == nil { + return localVarReturnValue, localVarHttpResponse, err + } + + localVarBody, _ := ioutil.ReadAll(localVarHttpResponse.Body) + localVarHttpResponse.Body = ioutil.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHttpResponse, err + } + + if localVarHttpResponse.StatusCode < 300 { + // If we succeed, return the data, otherwise pass on to decode error. + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err == nil { + return localVarReturnValue, localVarHttpResponse, err + } + } + + if localVarHttpResponse.StatusCode >= 300 { + newErr := GenericSwaggerError{ + body: localVarBody, + error: localVarHttpResponse.Status, + } + if localVarHttpResponse.StatusCode == 200 { + var v PagingResultDtoNodeGroupDto + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + return localVarReturnValue, localVarHttpResponse, newErr + } + + return localVarReturnValue, localVarHttpResponse, nil +} + +/* +V1NodeGroupControllerApiService + * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + * @param clusterId + * @param nodeGroupId + * @param optional nil or *V1NodeGroupControllerApiV1ClustersClusterIdNodeGroupsNodeGroupIdDeleteOpts - Optional Parameters: + * @param "PortalUserId" (optional.Int64) - +@return NodeGroupDto +*/ + +type V1NodeGroupControllerApiV1ClustersClusterIdNodeGroupsNodeGroupIdDeleteOpts struct { + PortalUserId optional.Int64 +} + +func (a *V1NodeGroupControllerApiService) V1ClustersClusterIdNodeGroupsNodeGroupIdDelete(ctx context.Context, clusterId string, nodeGroupId string, localVarOptionals *V1NodeGroupControllerApiV1ClustersClusterIdNodeGroupsNodeGroupIdDeleteOpts) (NodeGroupDto, *http.Response, error) { + var ( + localVarHttpMethod = strings.ToUpper("Delete") + localVarPostBody interface{} + localVarFileName string + localVarFileBytes []byte + localVarReturnValue NodeGroupDto + ) + + // create path and map variables + localVarPath := a.client.cfg.BasePath + "/v1/clusters/{clusterId}/node-groups/{nodeGroupId}" + localVarPath = strings.Replace(localVarPath, "{"+"clusterId"+"}", fmt.Sprintf("%v", clusterId), -1) + localVarPath = strings.Replace(localVarPath, "{"+"nodeGroupId"+"}", fmt.Sprintf("%v", nodeGroupId), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHttpContentTypes := []string{} + + // set Content-Type header + localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes) + if localVarHttpContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHttpContentType + } + + // to determine the Accept header + localVarHttpHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts) + if localVarHttpHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHttpHeaderAccept + } + if localVarOptionals != nil && localVarOptionals.PortalUserId.IsSet() { + localVarHeaderParams["portal-user-id"] = parameterToString(localVarOptionals.PortalUserId.Value(), "") + } + r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHttpResponse, err := a.client.callAPI(r) + if err != nil || localVarHttpResponse == nil { + return localVarReturnValue, localVarHttpResponse, err + } + + localVarBody, _ := ioutil.ReadAll(localVarHttpResponse.Body) + localVarHttpResponse.Body = ioutil.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHttpResponse, err + } + + if localVarHttpResponse.StatusCode < 300 { + // If we succeed, return the data, otherwise pass on to decode error. + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err == nil { + return localVarReturnValue, localVarHttpResponse, err + } + } + + if localVarHttpResponse.StatusCode >= 300 { + newErr := GenericSwaggerError{ + body: localVarBody, + error: localVarHttpResponse.Status, + } + if localVarHttpResponse.StatusCode == 200 { + var v NodeGroupDto + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + return localVarReturnValue, localVarHttpResponse, newErr + } + + return localVarReturnValue, localVarHttpResponse, nil +} + +/* +V1NodeGroupControllerApiService + * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + * @param clusterId + * @param nodeGroupId + * @param optional nil or *V1NodeGroupControllerApiV1ClustersClusterIdNodeGroupsNodeGroupIdGetOpts - Optional Parameters: + * @param "PortalUserId" (optional.Int64) - +@return NodeGroupDetailDto +*/ + +type V1NodeGroupControllerApiV1ClustersClusterIdNodeGroupsNodeGroupIdGetOpts struct { + PortalUserId optional.Int64 +} + +func (a *V1NodeGroupControllerApiService) V1ClustersClusterIdNodeGroupsNodeGroupIdGet(ctx context.Context, clusterId string, nodeGroupId string, localVarOptionals *V1NodeGroupControllerApiV1ClustersClusterIdNodeGroupsNodeGroupIdGetOpts) (NodeGroupDetailDto, *http.Response, error) { + var ( + localVarHttpMethod = strings.ToUpper("Get") + localVarPostBody interface{} + localVarFileName string + localVarFileBytes []byte + localVarReturnValue NodeGroupDetailDto + ) + + // create path and map variables + localVarPath := a.client.cfg.BasePath + "/v1/clusters/{clusterId}/node-groups/{nodeGroupId}" + localVarPath = strings.Replace(localVarPath, "{"+"clusterId"+"}", fmt.Sprintf("%v", clusterId), -1) + localVarPath = strings.Replace(localVarPath, "{"+"nodeGroupId"+"}", fmt.Sprintf("%v", nodeGroupId), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHttpContentTypes := []string{} + + // set Content-Type header + localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes) + if localVarHttpContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHttpContentType + } + + // to determine the Accept header + localVarHttpHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts) + if localVarHttpHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHttpHeaderAccept + } + if localVarOptionals != nil && localVarOptionals.PortalUserId.IsSet() { + localVarHeaderParams["portal-user-id"] = parameterToString(localVarOptionals.PortalUserId.Value(), "") + } + r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHttpResponse, err := a.client.callAPI(r) + if err != nil || localVarHttpResponse == nil { + return localVarReturnValue, localVarHttpResponse, err + } + + localVarBody, _ := ioutil.ReadAll(localVarHttpResponse.Body) + localVarHttpResponse.Body = ioutil.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHttpResponse, err + } + + if localVarHttpResponse.StatusCode < 300 { + // If we succeed, return the data, otherwise pass on to decode error. + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err == nil { + return localVarReturnValue, localVarHttpResponse, err + } + } + + if localVarHttpResponse.StatusCode >= 300 { + newErr := GenericSwaggerError{ + body: localVarBody, + error: localVarHttpResponse.Status, + } + if localVarHttpResponse.StatusCode == 200 { + var v NodeGroupDetailDto + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + return localVarReturnValue, localVarHttpResponse, newErr + } + + return localVarReturnValue, localVarHttpResponse, nil +} + +/* +V1NodeGroupControllerApiService + * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + * @param clusterId + * @param nodeGroupId + * @param optional nil or *V1NodeGroupControllerApiV1ClustersClusterIdNodeGroupsNodeGroupIdNodesGetOpts - Optional Parameters: + * @param "Page" (optional.Int32) - + * @param "PageSize" (optional.Int32) - + * @param "PortalUserId" (optional.Int64) - +@return PagingResultDtoNodeDto +*/ + +type V1NodeGroupControllerApiV1ClustersClusterIdNodeGroupsNodeGroupIdNodesGetOpts struct { + Page optional.Int32 + PageSize optional.Int32 + PortalUserId optional.Int64 +} + +func (a *V1NodeGroupControllerApiService) V1ClustersClusterIdNodeGroupsNodeGroupIdNodesGet(ctx context.Context, clusterId string, nodeGroupId string, localVarOptionals *V1NodeGroupControllerApiV1ClustersClusterIdNodeGroupsNodeGroupIdNodesGetOpts) (PagingResultDtoNodeDto, *http.Response, error) { + var ( + localVarHttpMethod = strings.ToUpper("Get") + localVarPostBody interface{} + localVarFileName string + localVarFileBytes []byte + localVarReturnValue PagingResultDtoNodeDto + ) + + // create path and map variables + localVarPath := a.client.cfg.BasePath + "/v1/clusters/{clusterId}/node-groups/{nodeGroupId}/nodes" + localVarPath = strings.Replace(localVarPath, "{"+"clusterId"+"}", fmt.Sprintf("%v", clusterId), -1) + localVarPath = strings.Replace(localVarPath, "{"+"nodeGroupId"+"}", fmt.Sprintf("%v", nodeGroupId), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + if localVarOptionals != nil && localVarOptionals.Page.IsSet() { + localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), "")) + } + if localVarOptionals != nil && localVarOptionals.PageSize.IsSet() { + localVarQueryParams.Add("pageSize", parameterToString(localVarOptionals.PageSize.Value(), "")) + } + // to determine the Content-Type header + localVarHttpContentTypes := []string{} + + // set Content-Type header + localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes) + if localVarHttpContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHttpContentType + } + + // to determine the Accept header + localVarHttpHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts) + if localVarHttpHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHttpHeaderAccept + } + if localVarOptionals != nil && localVarOptionals.PortalUserId.IsSet() { + localVarHeaderParams["portal-user-id"] = parameterToString(localVarOptionals.PortalUserId.Value(), "") + } + r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHttpResponse, err := a.client.callAPI(r) + if err != nil || localVarHttpResponse == nil { + return localVarReturnValue, localVarHttpResponse, err + } + + localVarBody, _ := ioutil.ReadAll(localVarHttpResponse.Body) + localVarHttpResponse.Body = ioutil.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHttpResponse, err + } + + if localVarHttpResponse.StatusCode < 300 { + // If we succeed, return the data, otherwise pass on to decode error. + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err == nil { + return localVarReturnValue, localVarHttpResponse, err + } + } + + if localVarHttpResponse.StatusCode >= 300 { + newErr := GenericSwaggerError{ + body: localVarBody, + error: localVarHttpResponse.Status, + } + if localVarHttpResponse.StatusCode == 200 { + var v PagingResultDtoNodeDto + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + return localVarReturnValue, localVarHttpResponse, newErr + } + + return localVarReturnValue, localVarHttpResponse, nil +} + +/* +V1NodeGroupControllerApiService + * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + * @param clusterId + * @param nodeGroupId + * @param optional nil or *V1NodeGroupControllerApiV1ClustersClusterIdNodeGroupsNodeGroupIdPutOpts - Optional Parameters: + * @param "Body" (optional.Interface of UpdateNodeGroupDto) - + * @param "PortalUserId" (optional.Int64) - +@return NodeGroupDto +*/ + +type V1NodeGroupControllerApiV1ClustersClusterIdNodeGroupsNodeGroupIdPutOpts struct { + Body optional.Interface + PortalUserId optional.Int64 +} + +func (a *V1NodeGroupControllerApiService) V1ClustersClusterIdNodeGroupsNodeGroupIdPut(ctx context.Context, clusterId string, nodeGroupId string, localVarOptionals *V1NodeGroupControllerApiV1ClustersClusterIdNodeGroupsNodeGroupIdPutOpts) (NodeGroupDto, *http.Response, error) { + var ( + localVarHttpMethod = strings.ToUpper("Put") + localVarPostBody interface{} + localVarFileName string + localVarFileBytes []byte + localVarReturnValue NodeGroupDto + ) + + // create path and map variables + localVarPath := a.client.cfg.BasePath + "/v1/clusters/{clusterId}/node-groups/{nodeGroupId}" + localVarPath = strings.Replace(localVarPath, "{"+"clusterId"+"}", fmt.Sprintf("%v", clusterId), -1) + localVarPath = strings.Replace(localVarPath, "{"+"nodeGroupId"+"}", fmt.Sprintf("%v", nodeGroupId), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHttpContentTypes := []string{"application/json"} + + // set Content-Type header + localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes) + if localVarHttpContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHttpContentType + } + + // to determine the Accept header + localVarHttpHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts) + if localVarHttpHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHttpHeaderAccept + } + if localVarOptionals != nil && localVarOptionals.PortalUserId.IsSet() { + localVarHeaderParams["portal-user-id"] = parameterToString(localVarOptionals.PortalUserId.Value(), "") + } + // body params + if localVarOptionals != nil && localVarOptionals.Body.IsSet() { + + localVarOptionalBody := localVarOptionals.Body.Value() + localVarPostBody = &localVarOptionalBody + } + r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHttpResponse, err := a.client.callAPI(r) + if err != nil || localVarHttpResponse == nil { + return localVarReturnValue, localVarHttpResponse, err + } + + localVarBody, _ := ioutil.ReadAll(localVarHttpResponse.Body) + localVarHttpResponse.Body = ioutil.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHttpResponse, err + } + + if localVarHttpResponse.StatusCode < 300 { + // If we succeed, return the data, otherwise pass on to decode error. + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err == nil { + return localVarReturnValue, localVarHttpResponse, err + } + } + + if localVarHttpResponse.StatusCode >= 300 { + newErr := GenericSwaggerError{ + body: localVarBody, + error: localVarHttpResponse.Status, + } + if localVarHttpResponse.StatusCode == 200 { + var v NodeGroupDto + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + return localVarReturnValue, localVarHttpResponse, newErr + } + + return localVarReturnValue, localVarHttpResponse, nil +} + +/* +V1NodeGroupControllerApiService + * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + * @param clusterId + * @param optional nil or *V1NodeGroupControllerApiV1ClustersClusterIdNodeGroupsPostOpts - Optional Parameters: + * @param "Body" (optional.Interface of CreateNodeGroupDto) - + * @param "PortalUserId" (optional.Int64) - +@return NodeGroupDto +*/ + +type V1NodeGroupControllerApiV1ClustersClusterIdNodeGroupsPostOpts struct { + Body optional.Interface + PortalUserId optional.Int64 +} + +func (a *V1NodeGroupControllerApiService) V1ClustersClusterIdNodeGroupsPost(ctx context.Context, clusterId string, localVarOptionals *V1NodeGroupControllerApiV1ClustersClusterIdNodeGroupsPostOpts) (NodeGroupDto, *http.Response, error) { + var ( + localVarHttpMethod = strings.ToUpper("Post") + localVarPostBody interface{} + localVarFileName string + localVarFileBytes []byte + localVarReturnValue NodeGroupDto + ) + + // create path and map variables + localVarPath := a.client.cfg.BasePath + "/v1/clusters/{clusterId}/node-groups" + localVarPath = strings.Replace(localVarPath, "{"+"clusterId"+"}", fmt.Sprintf("%v", clusterId), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHttpContentTypes := []string{"application/json"} + + // set Content-Type header + localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes) + if localVarHttpContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHttpContentType + } + + // to determine the Accept header + localVarHttpHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts) + if localVarHttpHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHttpHeaderAccept + } + if localVarOptionals != nil && localVarOptionals.PortalUserId.IsSet() { + localVarHeaderParams["portal-user-id"] = parameterToString(localVarOptionals.PortalUserId.Value(), "") + } + // body params + if localVarOptionals != nil && localVarOptionals.Body.IsSet() { + + localVarOptionalBody := localVarOptionals.Body.Value() + localVarPostBody = &localVarOptionalBody + } + r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHttpResponse, err := a.client.callAPI(r) + if err != nil || localVarHttpResponse == nil { + return localVarReturnValue, localVarHttpResponse, err + } + + localVarBody, _ := ioutil.ReadAll(localVarHttpResponse.Body) + localVarHttpResponse.Body = ioutil.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHttpResponse, err + } + + if localVarHttpResponse.StatusCode < 300 { + // If we succeed, return the data, otherwise pass on to decode error. + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err == nil { + return localVarReturnValue, localVarHttpResponse, err + } + } + + if localVarHttpResponse.StatusCode >= 300 { + newErr := GenericSwaggerError{ + body: localVarBody, + error: localVarHttpResponse.Status, + } + if localVarHttpResponse.StatusCode == 200 { + var v NodeGroupDto + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + return localVarReturnValue, localVarHttpResponse, newErr + } + + return localVarReturnValue, localVarHttpResponse, nil +} diff --git a/client/vks/api_v1_node_group_image_controller.go b/client/vks/api_v1_node_group_image_controller.go new file mode 100644 index 0000000..9decd0a --- /dev/null +++ b/client/vks/api_v1_node_group_image_controller.go @@ -0,0 +1,110 @@ +/* + * vks-api API + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 1.0-SNAPSHOT + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ +package vks + +import ( + "bytes" + "context" + _ "fmt" + _ "github.com/antihax/optional" + "io/ioutil" + "net/http" + "net/url" + "strings" +) + +// Linger please +var ( + _ context.Context +) + +type V1NodeGroupImageControllerApiService service + +/* +V1NodeGroupImageControllerApiService + * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). +@return []NodeGroupImageDto +*/ +func (a *V1NodeGroupImageControllerApiService) V1NodeGroupImagesGet(ctx context.Context) ([]NodeGroupImageDto, *http.Response, error) { + var ( + localVarHttpMethod = strings.ToUpper("Get") + localVarPostBody interface{} + localVarFileName string + localVarFileBytes []byte + localVarReturnValue []NodeGroupImageDto + ) + + // create path and map variables + localVarPath := a.client.cfg.BasePath + "/v1/node-group-images" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHttpContentTypes := []string{} + + // set Content-Type header + localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes) + if localVarHttpContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHttpContentType + } + + // to determine the Accept header + localVarHttpHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts) + if localVarHttpHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHttpHeaderAccept + } + r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHttpResponse, err := a.client.callAPI(r) + if err != nil || localVarHttpResponse == nil { + return localVarReturnValue, localVarHttpResponse, err + } + + localVarBody, _ := ioutil.ReadAll(localVarHttpResponse.Body) + localVarHttpResponse.Body = ioutil.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHttpResponse, err + } + + if localVarHttpResponse.StatusCode < 300 { + // If we succeed, return the data, otherwise pass on to decode error. + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err == nil { + return localVarReturnValue, localVarHttpResponse, err + } + } + + if localVarHttpResponse.StatusCode >= 300 { + newErr := GenericSwaggerError{ + body: localVarBody, + error: localVarHttpResponse.Status, + } + if localVarHttpResponse.StatusCode == 200 { + var v []NodeGroupImageDto + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + return localVarReturnValue, localVarHttpResponse, newErr + } + + return localVarReturnValue, localVarHttpResponse, nil +} diff --git a/client/vks/api_v1_workspace_controller.go b/client/vks/api_v1_workspace_controller.go new file mode 100644 index 0000000..8dca774 --- /dev/null +++ b/client/vks/api_v1_workspace_controller.go @@ -0,0 +1,306 @@ +/* + * vks-api API + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 1.0-SNAPSHOT + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ +package vks + +import ( + "bytes" + "context" + _ "fmt" + "github.com/antihax/optional" + "io/ioutil" + "net/http" + "net/url" + "strings" +) + +// Linger please +var ( + _ context.Context +) + +type V1WorkspaceControllerApiService service + +/* +V1WorkspaceControllerApiService + * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + * @param optional nil or *V1WorkspaceControllerApiV1WorkspaceGetOpts - Optional Parameters: + * @param "PortalUserId" (optional.Int64) - +@return WorkspaceDto +*/ + +type V1WorkspaceControllerApiV1WorkspaceGetOpts struct { + PortalUserId optional.Int64 +} + +func (a *V1WorkspaceControllerApiService) V1WorkspaceGet(ctx context.Context, localVarOptionals *V1WorkspaceControllerApiV1WorkspaceGetOpts) (WorkspaceDto, *http.Response, error) { + var ( + localVarHttpMethod = strings.ToUpper("Get") + localVarPostBody interface{} + localVarFileName string + localVarFileBytes []byte + localVarReturnValue WorkspaceDto + ) + + // create path and map variables + localVarPath := a.client.cfg.BasePath + "/v1/workspace" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHttpContentTypes := []string{} + + // set Content-Type header + localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes) + if localVarHttpContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHttpContentType + } + + // to determine the Accept header + localVarHttpHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts) + if localVarHttpHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHttpHeaderAccept + } + if localVarOptionals != nil && localVarOptionals.PortalUserId.IsSet() { + localVarHeaderParams["portal-user-id"] = parameterToString(localVarOptionals.PortalUserId.Value(), "") + } + r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHttpResponse, err := a.client.callAPI(r) + if err != nil || localVarHttpResponse == nil { + return localVarReturnValue, localVarHttpResponse, err + } + + localVarBody, _ := ioutil.ReadAll(localVarHttpResponse.Body) + localVarHttpResponse.Body = ioutil.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHttpResponse, err + } + + if localVarHttpResponse.StatusCode < 300 { + // If we succeed, return the data, otherwise pass on to decode error. + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err == nil { + return localVarReturnValue, localVarHttpResponse, err + } + } + + if localVarHttpResponse.StatusCode >= 300 { + newErr := GenericSwaggerError{ + body: localVarBody, + error: localVarHttpResponse.Status, + } + if localVarHttpResponse.StatusCode == 200 { + var v WorkspaceDto + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + return localVarReturnValue, localVarHttpResponse, newErr + } + + return localVarReturnValue, localVarHttpResponse, nil +} + +/* +V1WorkspaceControllerApiService + * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + * @param optional nil or *V1WorkspaceControllerApiV1WorkspacePostOpts - Optional Parameters: + * @param "PortalUserId" (optional.Int64) - +@return WorkspaceDto +*/ + +type V1WorkspaceControllerApiV1WorkspacePostOpts struct { + PortalUserId optional.Int64 +} + +func (a *V1WorkspaceControllerApiService) V1WorkspacePost(ctx context.Context, localVarOptionals *V1WorkspaceControllerApiV1WorkspacePostOpts) (WorkspaceDto, *http.Response, error) { + var ( + localVarHttpMethod = strings.ToUpper("Post") + localVarPostBody interface{} + localVarFileName string + localVarFileBytes []byte + localVarReturnValue WorkspaceDto + ) + + // create path and map variables + localVarPath := a.client.cfg.BasePath + "/v1/workspace" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHttpContentTypes := []string{} + + // set Content-Type header + localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes) + if localVarHttpContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHttpContentType + } + + // to determine the Accept header + localVarHttpHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts) + if localVarHttpHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHttpHeaderAccept + } + if localVarOptionals != nil && localVarOptionals.PortalUserId.IsSet() { + localVarHeaderParams["portal-user-id"] = parameterToString(localVarOptionals.PortalUserId.Value(), "") + } + r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHttpResponse, err := a.client.callAPI(r) + if err != nil || localVarHttpResponse == nil { + return localVarReturnValue, localVarHttpResponse, err + } + + localVarBody, _ := ioutil.ReadAll(localVarHttpResponse.Body) + localVarHttpResponse.Body = ioutil.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHttpResponse, err + } + + if localVarHttpResponse.StatusCode < 300 { + // If we succeed, return the data, otherwise pass on to decode error. + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err == nil { + return localVarReturnValue, localVarHttpResponse, err + } + } + + if localVarHttpResponse.StatusCode >= 300 { + newErr := GenericSwaggerError{ + body: localVarBody, + error: localVarHttpResponse.Status, + } + if localVarHttpResponse.StatusCode == 200 { + var v WorkspaceDto + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + return localVarReturnValue, localVarHttpResponse, newErr + } + + return localVarReturnValue, localVarHttpResponse, nil +} + +/* +V1WorkspaceControllerApiService + * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + * @param optional nil or *V1WorkspaceControllerApiV1WorkspaceResetServiceAccountPostOpts - Optional Parameters: + * @param "PortalUserId" (optional.Int64) - +@return WorkspaceDto +*/ + +type V1WorkspaceControllerApiV1WorkspaceResetServiceAccountPostOpts struct { + PortalUserId optional.Int64 +} + +func (a *V1WorkspaceControllerApiService) V1WorkspaceResetServiceAccountPost(ctx context.Context, localVarOptionals *V1WorkspaceControllerApiV1WorkspaceResetServiceAccountPostOpts) (WorkspaceDto, *http.Response, error) { + var ( + localVarHttpMethod = strings.ToUpper("Post") + localVarPostBody interface{} + localVarFileName string + localVarFileBytes []byte + localVarReturnValue WorkspaceDto + ) + + // create path and map variables + localVarPath := a.client.cfg.BasePath + "/v1/workspace/reset-service-account" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHttpContentTypes := []string{} + + // set Content-Type header + localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes) + if localVarHttpContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHttpContentType + } + + // to determine the Accept header + localVarHttpHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts) + if localVarHttpHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHttpHeaderAccept + } + if localVarOptionals != nil && localVarOptionals.PortalUserId.IsSet() { + localVarHeaderParams["portal-user-id"] = parameterToString(localVarOptionals.PortalUserId.Value(), "") + } + r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHttpResponse, err := a.client.callAPI(r) + if err != nil || localVarHttpResponse == nil { + return localVarReturnValue, localVarHttpResponse, err + } + + localVarBody, _ := ioutil.ReadAll(localVarHttpResponse.Body) + localVarHttpResponse.Body = ioutil.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHttpResponse, err + } + + if localVarHttpResponse.StatusCode < 300 { + // If we succeed, return the data, otherwise pass on to decode error. + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err == nil { + return localVarReturnValue, localVarHttpResponse, err + } + } + + if localVarHttpResponse.StatusCode >= 300 { + newErr := GenericSwaggerError{ + body: localVarBody, + error: localVarHttpResponse.Status, + } + if localVarHttpResponse.StatusCode == 200 { + var v WorkspaceDto + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + return localVarReturnValue, localVarHttpResponse, newErr + } + + return localVarReturnValue, localVarHttpResponse, nil +} diff --git a/client/vks/client.go b/client/vks/client.go new file mode 100644 index 0000000..ef7ded7 --- /dev/null +++ b/client/vks/client.go @@ -0,0 +1,482 @@ +/* + * vks-api API + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 1.0-SNAPSHOT + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ +package vks + +import ( + "bytes" + "context" + "encoding/json" + "encoding/xml" + "errors" + "fmt" + "io" + "mime/multipart" + "net/http" + "net/url" + "os" + "path/filepath" + "reflect" + "regexp" + "strconv" + "strings" + "time" + "unicode/utf8" + + "golang.org/x/oauth2" +) + +var ( + jsonCheck = regexp.MustCompile("(?i:[application|text]/json)") + xmlCheck = regexp.MustCompile("(?i:[application|text]/xml)") +) + +// APIClient manages communication with the vks-api API API v1.0-SNAPSHOT +// In most cases there should be only one, shared, APIClient. +type APIClient struct { + cfg *Configuration + common service // Reuse a single struct instead of allocating one for each service on the heap. + + // API Services + + V1ClusterControllerApi *V1ClusterControllerApiService + + V1NodeGroupControllerApi *V1NodeGroupControllerApiService + + V1NodeGroupImageControllerApi *V1NodeGroupImageControllerApiService + + V1WorkspaceControllerApi *V1WorkspaceControllerApiService +} + +type service struct { + client *APIClient +} + +// NewAPIClient creates a new API client. Requires a userAgent string describing your application. +// optionally a custom http.Client to allow for advanced features such as caching. +func NewAPIClient(cfg *Configuration) *APIClient { + if cfg.HTTPClient == nil { + cfg.HTTPClient = http.DefaultClient + } + + c := &APIClient{} + c.cfg = cfg + c.common.client = c + + // API Services + c.V1ClusterControllerApi = (*V1ClusterControllerApiService)(&c.common) + c.V1NodeGroupControllerApi = (*V1NodeGroupControllerApiService)(&c.common) + c.V1NodeGroupImageControllerApi = (*V1NodeGroupImageControllerApiService)(&c.common) + c.V1WorkspaceControllerApi = (*V1WorkspaceControllerApiService)(&c.common) + + return c +} + +func atoi(in string) (int, error) { + return strconv.Atoi(in) +} + +// selectHeaderContentType select a content type from the available list. +func selectHeaderContentType(contentTypes []string) string { + if len(contentTypes) == 0 { + return "" + } + if contains(contentTypes, "application/json") { + return "application/json" + } + return contentTypes[0] // use the first content type specified in 'consumes' +} + +// selectHeaderAccept join all accept types and return +func selectHeaderAccept(accepts []string) string { + if len(accepts) == 0 { + return "" + } + + if contains(accepts, "application/json") { + return "application/json" + } + + return strings.Join(accepts, ",") +} + +// contains is a case insenstive match, finding needle in a haystack +func contains(haystack []string, needle string) bool { + for _, a := range haystack { + if strings.ToLower(a) == strings.ToLower(needle) { + return true + } + } + return false +} + +// Verify optional parameters are of the correct type. +func typeCheckParameter(obj interface{}, expected string, name string) error { + // Make sure there is an object. + if obj == nil { + return nil + } + + // Check the type is as expected. + if reflect.TypeOf(obj).String() != expected { + return fmt.Errorf("Expected %s to be of type %s but received %s.", name, expected, reflect.TypeOf(obj).String()) + } + return nil +} + +// parameterToString convert interface{} parameters to string, using a delimiter if format is provided. +func parameterToString(obj interface{}, collectionFormat string) string { + var delimiter string + + switch collectionFormat { + case "pipes": + delimiter = "|" + case "ssv": + delimiter = " " + case "tsv": + delimiter = "\t" + case "csv": + delimiter = "," + } + + if reflect.TypeOf(obj).Kind() == reflect.Slice { + return strings.Trim(strings.Replace(fmt.Sprint(obj), " ", delimiter, -1), "[]") + } + + return fmt.Sprintf("%v", obj) +} + +// callAPI do the request. +func (c *APIClient) callAPI(request *http.Request) (*http.Response, error) { + return c.cfg.HTTPClient.Do(request) +} + +// Change base path to allow switching to mocks +func (c *APIClient) ChangeBasePath(path string) { + c.cfg.BasePath = path +} + +// prepareRequest build the request +func (c *APIClient) prepareRequest( + ctx context.Context, + path string, method string, + postBody interface{}, + headerParams map[string]string, + queryParams url.Values, + formParams url.Values, + fileName string, + fileBytes []byte) (localVarRequest *http.Request, err error) { + + var body *bytes.Buffer + + // Detect postBody type and post. + if postBody != nil { + contentType := headerParams["Content-Type"] + if contentType == "" { + contentType = detectContentType(postBody) + headerParams["Content-Type"] = contentType + } + + body, err = setBody(postBody, contentType) + if err != nil { + return nil, err + } + } + + // add form parameters and file if available. + if strings.HasPrefix(headerParams["Content-Type"], "multipart/form-data") && len(formParams) > 0 || (len(fileBytes) > 0 && fileName != "") { + if body != nil { + return nil, errors.New("Cannot specify postBody and multipart form at the same time.") + } + body = &bytes.Buffer{} + w := multipart.NewWriter(body) + + for k, v := range formParams { + for _, iv := range v { + if strings.HasPrefix(k, "@") { // file + err = addFile(w, k[1:], iv) + if err != nil { + return nil, err + } + } else { // form value + w.WriteField(k, iv) + } + } + } + if len(fileBytes) > 0 && fileName != "" { + w.Boundary() + //_, fileNm := filepath.Split(fileName) + part, err := w.CreateFormFile("file", filepath.Base(fileName)) + if err != nil { + return nil, err + } + _, err = part.Write(fileBytes) + if err != nil { + return nil, err + } + // Set the Boundary in the Content-Type + headerParams["Content-Type"] = w.FormDataContentType() + } + + // Set Content-Length + headerParams["Content-Length"] = fmt.Sprintf("%d", body.Len()) + w.Close() + } + + if strings.HasPrefix(headerParams["Content-Type"], "application/x-www-form-urlencoded") && len(formParams) > 0 { + if body != nil { + return nil, errors.New("Cannot specify postBody and x-www-form-urlencoded form at the same time.") + } + body = &bytes.Buffer{} + body.WriteString(formParams.Encode()) + // Set Content-Length + headerParams["Content-Length"] = fmt.Sprintf("%d", body.Len()) + } + + // Setup path and query parameters + url, err := url.Parse(path) + if err != nil { + return nil, err + } + + // Adding Query Param + query := url.Query() + for k, v := range queryParams { + for _, iv := range v { + query.Add(k, iv) + } + } + + // Encode the parameters. + url.RawQuery = query.Encode() + + // Generate a new request + if body != nil { + localVarRequest, err = http.NewRequest(method, url.String(), body) + } else { + localVarRequest, err = http.NewRequest(method, url.String(), nil) + } + if err != nil { + return nil, err + } + + // add header parameters, if any + if len(headerParams) > 0 { + headers := http.Header{} + for h, v := range headerParams { + headers.Set(h, v) + } + localVarRequest.Header = headers + } + + // Override request host, if applicable + if c.cfg.Host != "" { + localVarRequest.Host = c.cfg.Host + } + + // Add the user agent to the request. + localVarRequest.Header.Add("User-Agent", c.cfg.UserAgent) + + if ctx != nil { + // add context to the request + localVarRequest = localVarRequest.WithContext(ctx) + + // Walk through any authentication. + + // OAuth2 authentication + if tok, ok := ctx.Value(ContextOAuth2).(oauth2.TokenSource); ok { + // We were able to grab an oauth2 token from the context + var latestToken *oauth2.Token + if latestToken, err = tok.Token(); err != nil { + return nil, err + } + + latestToken.SetAuthHeader(localVarRequest) + } + + // Basic HTTP Authentication + if auth, ok := ctx.Value(ContextBasicAuth).(BasicAuth); ok { + localVarRequest.SetBasicAuth(auth.UserName, auth.Password) + } + + // AccessToken Authentication + if auth, ok := ctx.Value(ContextAccessToken).(string); ok { + localVarRequest.Header.Add("Authorization", "Bearer "+auth) + } + } + + for header, value := range c.cfg.DefaultHeader { + localVarRequest.Header.Add(header, value) + } + + return localVarRequest, nil +} + +func (c *APIClient) decode(v interface{}, b []byte, contentType string) (err error) { + if strings.Contains(contentType, "application/xml") { + if err = xml.Unmarshal(b, v); err != nil { + return err + } + return nil + } else if strings.Contains(contentType, "application/json") { + if err = json.Unmarshal(b, v); err != nil { + return err + } + return nil + } + return errors.New("undefined response type") +} + +// Add a file to the multipart request +func addFile(w *multipart.Writer, fieldName, path string) error { + file, err := os.Open(path) + if err != nil { + return err + } + defer file.Close() + + part, err := w.CreateFormFile(fieldName, filepath.Base(path)) + if err != nil { + return err + } + _, err = io.Copy(part, file) + + return err +} + +// Prevent trying to import "fmt" +func reportError(format string, a ...interface{}) error { + return fmt.Errorf(format, a...) +} + +// Set request body from an interface{} +func setBody(body interface{}, contentType string) (bodyBuf *bytes.Buffer, err error) { + if bodyBuf == nil { + bodyBuf = &bytes.Buffer{} + } + + if reader, ok := body.(io.Reader); ok { + _, err = bodyBuf.ReadFrom(reader) + } else if b, ok := body.([]byte); ok { + _, err = bodyBuf.Write(b) + } else if s, ok := body.(string); ok { + _, err = bodyBuf.WriteString(s) + } else if s, ok := body.(*string); ok { + _, err = bodyBuf.WriteString(*s) + } else if jsonCheck.MatchString(contentType) { + err = json.NewEncoder(bodyBuf).Encode(body) + } else if xmlCheck.MatchString(contentType) { + xml.NewEncoder(bodyBuf).Encode(body) + } + + if err != nil { + return nil, err + } + + if bodyBuf.Len() == 0 { + err = fmt.Errorf("Invalid body type %s\n", contentType) + return nil, err + } + return bodyBuf, nil +} + +// detectContentType method is used to figure out `Request.Body` content type for request header +func detectContentType(body interface{}) string { + contentType := "text/plain; charset=utf-8" + kind := reflect.TypeOf(body).Kind() + + switch kind { + case reflect.Struct, reflect.Map, reflect.Ptr: + contentType = "application/json; charset=utf-8" + case reflect.String: + contentType = "text/plain; charset=utf-8" + default: + if b, ok := body.([]byte); ok { + contentType = http.DetectContentType(b) + } else if kind == reflect.Slice { + contentType = "application/json; charset=utf-8" + } + } + + return contentType +} + +// Ripped from https://github.com/gregjones/httpcache/blob/master/httpcache.go +type cacheControl map[string]string + +func parseCacheControl(headers http.Header) cacheControl { + cc := cacheControl{} + ccHeader := headers.Get("Cache-Control") + for _, part := range strings.Split(ccHeader, ",") { + part = strings.Trim(part, " ") + if part == "" { + continue + } + if strings.ContainsRune(part, '=') { + keyval := strings.Split(part, "=") + cc[strings.Trim(keyval[0], " ")] = strings.Trim(keyval[1], ",") + } else { + cc[part] = "" + } + } + return cc +} + +// CacheExpires helper function to determine remaining time before repeating a request. +func CacheExpires(r *http.Response) time.Time { + // Figure out when the cache expires. + var expires time.Time + now, err := time.Parse(time.RFC1123, r.Header.Get("date")) + if err != nil { + return time.Now() + } + respCacheControl := parseCacheControl(r.Header) + + if maxAge, ok := respCacheControl["max-age"]; ok { + lifetime, err := time.ParseDuration(maxAge + "s") + if err != nil { + expires = now + } + expires = now.Add(lifetime) + } else { + expiresHeader := r.Header.Get("Expires") + if expiresHeader != "" { + expires, err = time.Parse(time.RFC1123, expiresHeader) + if err != nil { + expires = now + } + } + } + return expires +} + +func strlen(s string) int { + return utf8.RuneCountInString(s) +} + +// GenericSwaggerError Provides access to the body, error and model on returned errors. +type GenericSwaggerError struct { + body []byte + error string + model interface{} +} + +// Error returns non-empty string if there was an error. +func (e GenericSwaggerError) Error() string { + return e.error +} + +// Body returns the raw bytes of the response +func (e GenericSwaggerError) Body() []byte { + return e.body +} + +// Model returns the unpacked model of the error +func (e GenericSwaggerError) Model() interface{} { + return e.model +} diff --git a/client/vks/configuration.go b/client/vks/configuration.go new file mode 100644 index 0000000..8063145 --- /dev/null +++ b/client/vks/configuration.go @@ -0,0 +1,72 @@ +/* + * vks-api API + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 1.0-SNAPSHOT + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ +package vks + +import ( + "net/http" +) + +// contextKeys are used to identify the type of value in the context. +// Since these are string, it is possible to get a short description of the +// context key for logging and debugging using key.String(). + +type contextKey string + +func (c contextKey) String() string { + return "auth " + string(c) +} + +var ( + // ContextOAuth2 takes a oauth2.TokenSource as authentication for the request. + ContextOAuth2 = contextKey("token") + + // ContextBasicAuth takes BasicAuth as authentication for the request. + ContextBasicAuth = contextKey("basic") + + // ContextAccessToken takes a string oauth2 access token as authentication for the request. + ContextAccessToken = contextKey("accesstoken") + + // ContextAPIKey takes an APIKey as authentication for the request + ContextAPIKey = contextKey("apikey") +) + +// BasicAuth provides basic http authentication to a request passed via context using ContextBasicAuth +type BasicAuth struct { + UserName string `json:"userName,omitempty"` + Password string `json:"password,omitempty"` +} + +// APIKey provides API key based authentication to a request passed via context using ContextAPIKey +type APIKey struct { + Key string + Prefix string +} + +type Configuration struct { + BasePath string `json:"basePath,omitempty"` + Host string `json:"host,omitempty"` + Scheme string `json:"scheme,omitempty"` + DefaultHeader map[string]string `json:"defaultHeader,omitempty"` + UserAgent string `json:"userAgent,omitempty"` + HTTPClient *http.Client +} + +func NewConfiguration(BasePath string, HTTPClient *http.Client) *Configuration { + cfg := &Configuration{ + BasePath: BasePath, + DefaultHeader: make(map[string]string), + HTTPClient: HTTPClient, + UserAgent: "terraform", + } + return cfg +} + +func (c *Configuration) AddDefaultHeader(key string, value string) { + c.DefaultHeader[key] = value +} diff --git a/client/vks/docs/ClusterDetailDto.md b/client/vks/docs/ClusterDetailDto.md new file mode 100644 index 0000000..71423b6 --- /dev/null +++ b/client/vks/docs/ClusterDetailDto.md @@ -0,0 +1,24 @@ +# ClusterDetailDto + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Id** | **string** | | [optional] [default to null] +**Name** | **string** | | [optional] [default to null] +**Description** | **string** | | [optional] [default to null] +**Status** | **string** | | [optional] [default to null] +**Version** | **string** | | [optional] [default to null] +**NumNodes** | **int64** | | [optional] [default to null] +**CreatedAt** | **string** | | [optional] [default to null] +**UpdatedAt** | **string** | | [optional] [default to null] +**EnablePrivateCluster** | **bool** | | [optional] [default to null] +**NetworkType** | [***NetworkType**](NetworkType.md) | | [optional] [default to null] +**VpcId** | **string** | | [optional] [default to null] +**SubnetId** | **string** | | [optional] [default to null] +**Cidr** | **string** | | [optional] [default to null] +**EnabledLoadBalancerPlugin** | **bool** | | [optional] [default to null] +**EnabledBlockStoreCsiPlugin** | **bool** | | [optional] [default to null] +**WhitelistNodeCIDRs** | **[]string** | | [optional] [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/client/vks/docs/ClusterDto.md b/client/vks/docs/ClusterDto.md new file mode 100644 index 0000000..43cb02b --- /dev/null +++ b/client/vks/docs/ClusterDto.md @@ -0,0 +1,16 @@ +# ClusterDto + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Id** | **string** | | [optional] [default to null] +**Name** | **string** | | [optional] [default to null] +**Description** | **string** | | [optional] [default to null] +**Status** | **string** | | [optional] [default to null] +**Version** | **string** | | [optional] [default to null] +**NumNodes** | **int64** | | [optional] [default to null] +**CreatedAt** | **string** | | [optional] [default to null] +**UpdatedAt** | **string** | | [optional] [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/client/vks/docs/CreateClusterComboDto.md b/client/vks/docs/CreateClusterComboDto.md new file mode 100644 index 0000000..2e10ddd --- /dev/null +++ b/client/vks/docs/CreateClusterComboDto.md @@ -0,0 +1,19 @@ +# CreateClusterComboDto + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Name** | **string** | | [default to null] +**Description** | **string** | | [optional] [default to null] +**Version** | **string** | | [default to null] +**EnablePrivateCluster** | **bool** | | [default to null] +**NetworkType** | **string** | | [default to null] +**VpcId** | **string** | | [default to null] +**SubnetId** | **string** | | [default to null] +**Cidr** | **string** | | [default to null] +**EnabledLoadBalancerPlugin** | **bool** | | [optional] [default to null] +**EnabledBlockStoreCsiPlugin** | **bool** | | [optional] [default to null] +**NodeGroups** | [**[]CreateNodeGroupDto**](CreateNodeGroupDto.md) | | [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/client/vks/docs/CreateNodeGroupDto.md b/client/vks/docs/CreateNodeGroupDto.md new file mode 100644 index 0000000..a683c1e --- /dev/null +++ b/client/vks/docs/CreateNodeGroupDto.md @@ -0,0 +1,21 @@ +# CreateNodeGroupDto + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Name** | **string** | | [default to null] +**NumNodes** | **int32** | | [default to null] +**AutoScaleConfig** | [***NodeGroupAutoScaleConfigDto**](NodeGroupAutoScaleConfigDto.md) | | [optional] [default to null] +**UpgradeConfig** | [***NodeGroupUpgradeConfigDto**](NodeGroupUpgradeConfigDto.md) | | [default to null] +**ImageId** | **string** | | [default to null] +**FlavorId** | **string** | | [default to null] +**DiskSize** | **int32** | | [default to null] +**DiskType** | **string** | | [default to null] +**EnablePrivateNodes** | **bool** | | [default to null] +**SecurityGroups** | **[]string** | | [default to null] +**SshKeyId** | **string** | | [default to null] +**Labels** | **map[string]string** | | [optional] [default to null] +**Taints** | [**[]NodeGroupTaintDto**](NodeGroupTaintDto.md) | | [optional] [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/client/vks/docs/NetworkType.md b/client/vks/docs/NetworkType.md new file mode 100644 index 0000000..80bd442 --- /dev/null +++ b/client/vks/docs/NetworkType.md @@ -0,0 +1,8 @@ +# NetworkType + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/client/vks/docs/NodeDto.md b/client/vks/docs/NodeDto.md new file mode 100644 index 0000000..37c654e --- /dev/null +++ b/client/vks/docs/NodeDto.md @@ -0,0 +1,14 @@ +# NodeDto + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Id** | **string** | | [optional] [default to null] +**Name** | **string** | | [optional] [default to null] +**Status** | **string** | | [optional] [default to null] +**FloatingIp** | **string** | | [optional] [default to null] +**FixedIp** | **string** | | [optional] [default to null] +**Ready** | **bool** | | [optional] [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/client/vks/docs/NodeGroupAutoScaleConfigDto.md b/client/vks/docs/NodeGroupAutoScaleConfigDto.md new file mode 100644 index 0000000..2c8b1db --- /dev/null +++ b/client/vks/docs/NodeGroupAutoScaleConfigDto.md @@ -0,0 +1,10 @@ +# NodeGroupAutoScaleConfigDto + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**MinSize** | **int32** | | [default to null] +**MaxSize** | **int32** | | [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/client/vks/docs/NodeGroupDetailDto.md b/client/vks/docs/NodeGroupDetailDto.md new file mode 100644 index 0000000..221ff41 --- /dev/null +++ b/client/vks/docs/NodeGroupDetailDto.md @@ -0,0 +1,26 @@ +# NodeGroupDetailDto + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Id** | **string** | | [optional] [default to null] +**ClusterId** | **string** | | [optional] [default to null] +**Name** | **string** | | [optional] [default to null] +**Status** | **string** | | [optional] [default to null] +**NumNodes** | **int64** | | [optional] [default to null] +**ImageId** | **string** | | [optional] [default to null] +**CreatedAt** | **string** | | [optional] [default to null] +**UpdatedAt** | **string** | | [optional] [default to null] +**FlavorId** | **string** | | [optional] [default to null] +**DiskSize** | **int32** | | [optional] [default to null] +**DiskType** | **string** | | [optional] [default to null] +**EnablePrivateNodes** | **bool** | | [optional] [default to null] +**SshKeyId** | **string** | | [optional] [default to null] +**SecurityGroups** | **[]string** | | [optional] [default to null] +**AutoScaleConfig** | [***NodeGroupAutoScaleConfigDto**](NodeGroupAutoScaleConfigDto.md) | | [optional] [default to null] +**UpgradeConfig** | [***NodeGroupUpgradeConfigDto**](NodeGroupUpgradeConfigDto.md) | | [optional] [default to null] +**Labels** | **map[string]string** | | [optional] [default to null] +**Taints** | [**[]NodeGroupTaintDto**](NodeGroupTaintDto.md) | | [optional] [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/client/vks/docs/NodeGroupDto.md b/client/vks/docs/NodeGroupDto.md new file mode 100644 index 0000000..e672005 --- /dev/null +++ b/client/vks/docs/NodeGroupDto.md @@ -0,0 +1,16 @@ +# NodeGroupDto + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Id** | **string** | | [optional] [default to null] +**ClusterId** | **string** | | [optional] [default to null] +**Name** | **string** | | [optional] [default to null] +**Status** | **string** | | [optional] [default to null] +**NumNodes** | **int64** | | [optional] [default to null] +**ImageId** | **string** | | [optional] [default to null] +**CreatedAt** | **string** | | [optional] [default to null] +**UpdatedAt** | **string** | | [optional] [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/client/vks/docs/NodeGroupImageDto.md b/client/vks/docs/NodeGroupImageDto.md new file mode 100644 index 0000000..06e67e8 --- /dev/null +++ b/client/vks/docs/NodeGroupImageDto.md @@ -0,0 +1,12 @@ +# NodeGroupImageDto + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Id** | **string** | | [optional] [default to null] +**Os** | **string** | | [optional] [default to null] +**KubernetesVersion** | **string** | | [optional] [default to null] +**Enable** | **bool** | | [optional] [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/client/vks/docs/NodeGroupTaintDto.md b/client/vks/docs/NodeGroupTaintDto.md new file mode 100644 index 0000000..73bfc68 --- /dev/null +++ b/client/vks/docs/NodeGroupTaintDto.md @@ -0,0 +1,11 @@ +# NodeGroupTaintDto + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Key** | **string** | | [default to null] +**Value** | **string** | | [default to null] +**Effect** | **string** | | [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/client/vks/docs/NodeGroupUpgradeConfigDto.md b/client/vks/docs/NodeGroupUpgradeConfigDto.md new file mode 100644 index 0000000..a719b21 --- /dev/null +++ b/client/vks/docs/NodeGroupUpgradeConfigDto.md @@ -0,0 +1,11 @@ +# NodeGroupUpgradeConfigDto + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Strategy** | **string** | | [default to null] +**MaxSurge** | **int32** | | [optional] [default to null] +**MaxUnavailable** | **int32** | | [optional] [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/client/vks/docs/PagingResultDtoClusterDto.md b/client/vks/docs/PagingResultDtoClusterDto.md new file mode 100644 index 0000000..ac85681 --- /dev/null +++ b/client/vks/docs/PagingResultDtoClusterDto.md @@ -0,0 +1,12 @@ +# PagingResultDtoClusterDto + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Items** | [**[]ClusterDto**](ClusterDto.md) | | [optional] [default to null] +**Total** | **int64** | | [optional] [default to null] +**Page** | **int32** | | [optional] [default to null] +**PageSize** | **int32** | | [optional] [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/client/vks/docs/PagingResultDtoNodeDto.md b/client/vks/docs/PagingResultDtoNodeDto.md new file mode 100644 index 0000000..30c8ceb --- /dev/null +++ b/client/vks/docs/PagingResultDtoNodeDto.md @@ -0,0 +1,12 @@ +# PagingResultDtoNodeDto + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Items** | [**[]NodeDto**](NodeDto.md) | | [optional] [default to null] +**Total** | **int64** | | [optional] [default to null] +**Page** | **int32** | | [optional] [default to null] +**PageSize** | **int32** | | [optional] [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/client/vks/docs/PagingResultDtoNodeGroupDto.md b/client/vks/docs/PagingResultDtoNodeGroupDto.md new file mode 100644 index 0000000..59dc749 --- /dev/null +++ b/client/vks/docs/PagingResultDtoNodeGroupDto.md @@ -0,0 +1,12 @@ +# PagingResultDtoNodeGroupDto + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Items** | [**[]NodeGroupDto**](NodeGroupDto.md) | | [optional] [default to null] +**Total** | **int64** | | [optional] [default to null] +**Page** | **int32** | | [optional] [default to null] +**PageSize** | **int32** | | [optional] [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/client/vks/docs/UpdateClusterDto.md b/client/vks/docs/UpdateClusterDto.md new file mode 100644 index 0000000..b497c4e --- /dev/null +++ b/client/vks/docs/UpdateClusterDto.md @@ -0,0 +1,10 @@ +# UpdateClusterDto + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Version** | **string** | | [default to null] +**WhitelistNodeCIDRs** | **[]string** | | [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/client/vks/docs/UpdateNodeGroupDto.md b/client/vks/docs/UpdateNodeGroupDto.md new file mode 100644 index 0000000..2f84f33 --- /dev/null +++ b/client/vks/docs/UpdateNodeGroupDto.md @@ -0,0 +1,13 @@ +# UpdateNodeGroupDto + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**AutoScaleConfig** | [***NodeGroupAutoScaleConfigDto**](NodeGroupAutoScaleConfigDto.md) | | [optional] [default to null] +**NumNodes** | **int64** | | [optional] [default to null] +**UpgradeConfig** | [***NodeGroupUpgradeConfigDto**](NodeGroupUpgradeConfigDto.md) | | [default to null] +**SecurityGroups** | **[]string** | | [default to null] +**ImageId** | **string** | | [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/client/vks/docs/V1ClusterControllerApi.md b/client/vks/docs/V1ClusterControllerApi.md new file mode 100644 index 0000000..0636480 --- /dev/null +++ b/client/vks/docs/V1ClusterControllerApi.md @@ -0,0 +1,219 @@ +# {{classname}} + +All URIs are relative to */* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**V1ClustersClusterIdDelete**](V1ClusterControllerApi.md#V1ClustersClusterIdDelete) | **Delete** /v1/clusters/{clusterId} | +[**V1ClustersClusterIdGet**](V1ClusterControllerApi.md#V1ClustersClusterIdGet) | **Get** /v1/clusters/{clusterId} | +[**V1ClustersClusterIdKubeconfigGet**](V1ClusterControllerApi.md#V1ClustersClusterIdKubeconfigGet) | **Get** /v1/clusters/{clusterId}/kubeconfig | +[**V1ClustersClusterIdPut**](V1ClusterControllerApi.md#V1ClustersClusterIdPut) | **Put** /v1/clusters/{clusterId} | +[**V1ClustersGet**](V1ClusterControllerApi.md#V1ClustersGet) | **Get** /v1/clusters | +[**V1ClustersPost**](V1ClusterControllerApi.md#V1ClustersPost) | **Post** /v1/clusters | + +# **V1ClustersClusterIdDelete** +> ClusterDto V1ClustersClusterIdDelete(ctx, clusterId, optional) + + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. + **clusterId** | **string**| | + **optional** | ***V1ClusterControllerApiV1ClustersClusterIdDeleteOpts** | optional parameters | nil if no parameters + +### Optional Parameters +Optional parameters are passed through a pointer to a V1ClusterControllerApiV1ClustersClusterIdDeleteOpts struct +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + **portalUserId** | **optional.Int64**| | + +### Return type + +[**ClusterDto**](ClusterDto.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **V1ClustersClusterIdGet** +> ClusterDetailDto V1ClustersClusterIdGet(ctx, clusterId, optional) + + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. + **clusterId** | **string**| | + **optional** | ***V1ClusterControllerApiV1ClustersClusterIdGetOpts** | optional parameters | nil if no parameters + +### Optional Parameters +Optional parameters are passed through a pointer to a V1ClusterControllerApiV1ClustersClusterIdGetOpts struct +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + **portalUserId** | **optional.Int64**| | + +### Return type + +[**ClusterDetailDto**](ClusterDetailDto.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **V1ClustersClusterIdKubeconfigGet** +> string V1ClustersClusterIdKubeconfigGet(ctx, clusterId, optional) + + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. + **clusterId** | **string**| | + **optional** | ***V1ClusterControllerApiV1ClustersClusterIdKubeconfigGetOpts** | optional parameters | nil if no parameters + +### Optional Parameters +Optional parameters are passed through a pointer to a V1ClusterControllerApiV1ClustersClusterIdKubeconfigGetOpts struct +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + **portalUserId** | **optional.Int64**| | + +### Return type + +**string** + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: text/plain + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **V1ClustersClusterIdPut** +> ClusterDto V1ClustersClusterIdPut(ctx, clusterId, optional) + + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. + **clusterId** | **string**| | + **optional** | ***V1ClusterControllerApiV1ClustersClusterIdPutOpts** | optional parameters | nil if no parameters + +### Optional Parameters +Optional parameters are passed through a pointer to a V1ClusterControllerApiV1ClustersClusterIdPutOpts struct +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + **body** | [**optional.Interface of UpdateClusterDto**](UpdateClusterDto.md)| | + **portalUserId** | **optional.**| | + +### Return type + +[**ClusterDto**](ClusterDto.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **V1ClustersGet** +> PagingResultDtoClusterDto V1ClustersGet(ctx, optional) + + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. + **optional** | ***V1ClusterControllerApiV1ClustersGetOpts** | optional parameters | nil if no parameters + +### Optional Parameters +Optional parameters are passed through a pointer to a V1ClusterControllerApiV1ClustersGetOpts struct +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **filter** | **optional.String**| | [default to {}] + **page** | **optional.Int32**| | [default to 0] + **pageSize** | **optional.Int32**| | [default to 10] + **portalUserId** | **optional.Int64**| | + +### Return type + +[**PagingResultDtoClusterDto**](PagingResultDtoClusterDto.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **V1ClustersPost** +> ClusterDto V1ClustersPost(ctx, optional) + + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. + **optional** | ***V1ClusterControllerApiV1ClustersPostOpts** | optional parameters | nil if no parameters + +### Optional Parameters +Optional parameters are passed through a pointer to a V1ClusterControllerApiV1ClustersPostOpts struct +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **body** | [**optional.Interface of CreateClusterComboDto**](CreateClusterComboDto.md)| | + **poc** | **optional.**| | [default to false] + **portalUserId** | **optional.**| | + +### Return type + +[**ClusterDto**](ClusterDto.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/client/vks/docs/V1NodeGroupControllerApi.md b/client/vks/docs/V1NodeGroupControllerApi.md new file mode 100644 index 0000000..e844903 --- /dev/null +++ b/client/vks/docs/V1NodeGroupControllerApi.md @@ -0,0 +1,231 @@ +# {{classname}} + +All URIs are relative to */* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**V1ClustersClusterIdNodeGroupsGet**](V1NodeGroupControllerApi.md#V1ClustersClusterIdNodeGroupsGet) | **Get** /v1/clusters/{clusterId}/node-groups | +[**V1ClustersClusterIdNodeGroupsNodeGroupIdDelete**](V1NodeGroupControllerApi.md#V1ClustersClusterIdNodeGroupsNodeGroupIdDelete) | **Delete** /v1/clusters/{clusterId}/node-groups/{nodeGroupId} | +[**V1ClustersClusterIdNodeGroupsNodeGroupIdGet**](V1NodeGroupControllerApi.md#V1ClustersClusterIdNodeGroupsNodeGroupIdGet) | **Get** /v1/clusters/{clusterId}/node-groups/{nodeGroupId} | +[**V1ClustersClusterIdNodeGroupsNodeGroupIdNodesGet**](V1NodeGroupControllerApi.md#V1ClustersClusterIdNodeGroupsNodeGroupIdNodesGet) | **Get** /v1/clusters/{clusterId}/node-groups/{nodeGroupId}/nodes | +[**V1ClustersClusterIdNodeGroupsNodeGroupIdPut**](V1NodeGroupControllerApi.md#V1ClustersClusterIdNodeGroupsNodeGroupIdPut) | **Put** /v1/clusters/{clusterId}/node-groups/{nodeGroupId} | +[**V1ClustersClusterIdNodeGroupsPost**](V1NodeGroupControllerApi.md#V1ClustersClusterIdNodeGroupsPost) | **Post** /v1/clusters/{clusterId}/node-groups | + +# **V1ClustersClusterIdNodeGroupsGet** +> PagingResultDtoNodeGroupDto V1ClustersClusterIdNodeGroupsGet(ctx, clusterId, optional) + + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. + **clusterId** | **string**| | + **optional** | ***V1NodeGroupControllerApiV1ClustersClusterIdNodeGroupsGetOpts** | optional parameters | nil if no parameters + +### Optional Parameters +Optional parameters are passed through a pointer to a V1NodeGroupControllerApiV1ClustersClusterIdNodeGroupsGetOpts struct +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + **page** | **optional.Int32**| | [default to 0] + **pageSize** | **optional.Int32**| | [default to 10] + **portalUserId** | **optional.Int64**| | + +### Return type + +[**PagingResultDtoNodeGroupDto**](PagingResultDtoNodeGroupDto.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **V1ClustersClusterIdNodeGroupsNodeGroupIdDelete** +> NodeGroupDto V1ClustersClusterIdNodeGroupsNodeGroupIdDelete(ctx, clusterId, nodeGroupId, optional) + + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. + **clusterId** | **string**| | + **nodeGroupId** | **string**| | + **optional** | ***V1NodeGroupControllerApiV1ClustersClusterIdNodeGroupsNodeGroupIdDeleteOpts** | optional parameters | nil if no parameters + +### Optional Parameters +Optional parameters are passed through a pointer to a V1NodeGroupControllerApiV1ClustersClusterIdNodeGroupsNodeGroupIdDeleteOpts struct +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + + **portalUserId** | **optional.Int64**| | + +### Return type + +[**NodeGroupDto**](NodeGroupDto.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **V1ClustersClusterIdNodeGroupsNodeGroupIdGet** +> NodeGroupDetailDto V1ClustersClusterIdNodeGroupsNodeGroupIdGet(ctx, clusterId, nodeGroupId, optional) + + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. + **clusterId** | **string**| | + **nodeGroupId** | **string**| | + **optional** | ***V1NodeGroupControllerApiV1ClustersClusterIdNodeGroupsNodeGroupIdGetOpts** | optional parameters | nil if no parameters + +### Optional Parameters +Optional parameters are passed through a pointer to a V1NodeGroupControllerApiV1ClustersClusterIdNodeGroupsNodeGroupIdGetOpts struct +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + + **portalUserId** | **optional.Int64**| | + +### Return type + +[**NodeGroupDetailDto**](NodeGroupDetailDto.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **V1ClustersClusterIdNodeGroupsNodeGroupIdNodesGet** +> PagingResultDtoNodeDto V1ClustersClusterIdNodeGroupsNodeGroupIdNodesGet(ctx, clusterId, nodeGroupId, optional) + + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. + **clusterId** | **string**| | + **nodeGroupId** | **string**| | + **optional** | ***V1NodeGroupControllerApiV1ClustersClusterIdNodeGroupsNodeGroupIdNodesGetOpts** | optional parameters | nil if no parameters + +### Optional Parameters +Optional parameters are passed through a pointer to a V1NodeGroupControllerApiV1ClustersClusterIdNodeGroupsNodeGroupIdNodesGetOpts struct +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + + **page** | **optional.Int32**| | [default to 0] + **pageSize** | **optional.Int32**| | [default to 10] + **portalUserId** | **optional.Int64**| | + +### Return type + +[**PagingResultDtoNodeDto**](PagingResultDtoNodeDto.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **V1ClustersClusterIdNodeGroupsNodeGroupIdPut** +> NodeGroupDto V1ClustersClusterIdNodeGroupsNodeGroupIdPut(ctx, clusterId, nodeGroupId, optional) + + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. + **clusterId** | **string**| | + **nodeGroupId** | **string**| | + **optional** | ***V1NodeGroupControllerApiV1ClustersClusterIdNodeGroupsNodeGroupIdPutOpts** | optional parameters | nil if no parameters + +### Optional Parameters +Optional parameters are passed through a pointer to a V1NodeGroupControllerApiV1ClustersClusterIdNodeGroupsNodeGroupIdPutOpts struct +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + + **body** | [**optional.Interface of UpdateNodeGroupDto**](UpdateNodeGroupDto.md)| | + **portalUserId** | **optional.**| | + +### Return type + +[**NodeGroupDto**](NodeGroupDto.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **V1ClustersClusterIdNodeGroupsPost** +> NodeGroupDto V1ClustersClusterIdNodeGroupsPost(ctx, clusterId, optional) + + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. + **clusterId** | **string**| | + **optional** | ***V1NodeGroupControllerApiV1ClustersClusterIdNodeGroupsPostOpts** | optional parameters | nil if no parameters + +### Optional Parameters +Optional parameters are passed through a pointer to a V1NodeGroupControllerApiV1ClustersClusterIdNodeGroupsPostOpts struct +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + **body** | [**optional.Interface of CreateNodeGroupDto**](CreateNodeGroupDto.md)| | + **portalUserId** | **optional.**| | + +### Return type + +[**NodeGroupDto**](NodeGroupDto.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/client/vks/docs/V1NodeGroupImageControllerApi.md b/client/vks/docs/V1NodeGroupImageControllerApi.md new file mode 100644 index 0000000..6994b1b --- /dev/null +++ b/client/vks/docs/V1NodeGroupImageControllerApi.md @@ -0,0 +1,30 @@ +# {{classname}} + +All URIs are relative to */* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**V1NodeGroupImagesGet**](V1NodeGroupImageControllerApi.md#V1NodeGroupImagesGet) | **Get** /v1/node-group-images | + +# **V1NodeGroupImagesGet** +> []NodeGroupImageDto V1NodeGroupImagesGet(ctx, ) + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + +[**[]NodeGroupImageDto**](NodeGroupImageDto.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/client/vks/docs/V1WorkspaceControllerApi.md b/client/vks/docs/V1WorkspaceControllerApi.md new file mode 100644 index 0000000..aa1fed4 --- /dev/null +++ b/client/vks/docs/V1WorkspaceControllerApi.md @@ -0,0 +1,106 @@ +# {{classname}} + +All URIs are relative to */* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**V1WorkspaceGet**](V1WorkspaceControllerApi.md#V1WorkspaceGet) | **Get** /v1/workspace | +[**V1WorkspacePost**](V1WorkspaceControllerApi.md#V1WorkspacePost) | **Post** /v1/workspace | +[**V1WorkspaceResetServiceAccountPost**](V1WorkspaceControllerApi.md#V1WorkspaceResetServiceAccountPost) | **Post** /v1/workspace/reset-service-account | + +# **V1WorkspaceGet** +> WorkspaceDto V1WorkspaceGet(ctx, optional) + + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. + **optional** | ***V1WorkspaceControllerApiV1WorkspaceGetOpts** | optional parameters | nil if no parameters + +### Optional Parameters +Optional parameters are passed through a pointer to a V1WorkspaceControllerApiV1WorkspaceGetOpts struct +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **portalUserId** | **optional.Int64**| | + +### Return type + +[**WorkspaceDto**](WorkspaceDto.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **V1WorkspacePost** +> WorkspaceDto V1WorkspacePost(ctx, optional) + + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. + **optional** | ***V1WorkspaceControllerApiV1WorkspacePostOpts** | optional parameters | nil if no parameters + +### Optional Parameters +Optional parameters are passed through a pointer to a V1WorkspaceControllerApiV1WorkspacePostOpts struct +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **portalUserId** | **optional.Int64**| | + +### Return type + +[**WorkspaceDto**](WorkspaceDto.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **V1WorkspaceResetServiceAccountPost** +> WorkspaceDto V1WorkspaceResetServiceAccountPost(ctx, optional) + + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. + **optional** | ***V1WorkspaceControllerApiV1WorkspaceResetServiceAccountPostOpts** | optional parameters | nil if no parameters + +### Optional Parameters +Optional parameters are passed through a pointer to a V1WorkspaceControllerApiV1WorkspaceResetServiceAccountPostOpts struct +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **portalUserId** | **optional.Int64**| | + +### Return type + +[**WorkspaceDto**](WorkspaceDto.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/client/vks/docs/WorkspaceDto.md b/client/vks/docs/WorkspaceDto.md new file mode 100644 index 0000000..9b06751 --- /dev/null +++ b/client/vks/docs/WorkspaceDto.md @@ -0,0 +1,11 @@ +# WorkspaceDto + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**ProjectId** | **string** | | [optional] [default to null] +**ServiceAccountId** | **string** | | [optional] [default to null] +**Status** | **string** | | [optional] [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/client/vks/model_cluster_detail_dto.go b/client/vks/model_cluster_detail_dto.go new file mode 100644 index 0000000..1904714 --- /dev/null +++ b/client/vks/model_cluster_detail_dto.go @@ -0,0 +1,28 @@ +/* + * vks-api API + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 1.0-SNAPSHOT + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ +package vks + +type ClusterDetailDto struct { + Id string `json:"id,omitempty"` + Name string `json:"name,omitempty"` + Description string `json:"description,omitempty"` + Status string `json:"status,omitempty"` + Version string `json:"version,omitempty"` + NumNodes int64 `json:"numNodes,omitempty"` + CreatedAt string `json:"createdAt,omitempty"` + UpdatedAt string `json:"updatedAt,omitempty"` + EnablePrivateCluster bool `json:"enablePrivateCluster,omitempty"` + NetworkType *NetworkType `json:"networkType,omitempty"` + VpcId string `json:"vpcId,omitempty"` + SubnetId string `json:"subnetId,omitempty"` + Cidr string `json:"cidr,omitempty"` + EnabledLoadBalancerPlugin bool `json:"enabledLoadBalancerPlugin,omitempty"` + EnabledBlockStoreCsiPlugin bool `json:"enabledBlockStoreCsiPlugin,omitempty"` + WhitelistNodeCIDRs []string `json:"whitelistNodeCIDRs,omitempty"` +} diff --git a/client/vks/model_cluster_dto.go b/client/vks/model_cluster_dto.go new file mode 100644 index 0000000..bf21819 --- /dev/null +++ b/client/vks/model_cluster_dto.go @@ -0,0 +1,20 @@ +/* + * vks-api API + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 1.0-SNAPSHOT + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ +package vks + +type ClusterDto struct { + Id string `json:"id,omitempty"` + Name string `json:"name,omitempty"` + Description string `json:"description,omitempty"` + Status string `json:"status,omitempty"` + Version string `json:"version,omitempty"` + NumNodes int64 `json:"numNodes,omitempty"` + CreatedAt string `json:"createdAt,omitempty"` + UpdatedAt string `json:"updatedAt,omitempty"` +} diff --git a/client/vks/model_create_cluster_combo_dto.go b/client/vks/model_create_cluster_combo_dto.go new file mode 100644 index 0000000..98c0e92 --- /dev/null +++ b/client/vks/model_create_cluster_combo_dto.go @@ -0,0 +1,23 @@ +/* + * vks-api API + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 1.0-SNAPSHOT + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ +package vks + +type CreateClusterComboDto struct { + Name string `json:"name"` + Description string `json:"description,omitempty"` + Version string `json:"version"` + EnablePrivateCluster bool `json:"enablePrivateCluster"` + NetworkType string `json:"networkType"` + VpcId string `json:"vpcId"` + SubnetId string `json:"subnetId"` + Cidr string `json:"cidr"` + EnabledLoadBalancerPlugin bool `json:"enabledLoadBalancerPlugin"` + EnabledBlockStoreCsiPlugin bool `json:"enabledBlockStoreCsiPlugin"` + NodeGroups []CreateNodeGroupDto `json:"nodeGroups"` +} diff --git a/client/vks/model_create_node_group_dto.go b/client/vks/model_create_node_group_dto.go new file mode 100644 index 0000000..5c636cf --- /dev/null +++ b/client/vks/model_create_node_group_dto.go @@ -0,0 +1,25 @@ +/* + * vks-api API + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 1.0-SNAPSHOT + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ +package vks + +type CreateNodeGroupDto struct { + Name string `json:"name"` + NumNodes int32 `json:"numNodes"` + AutoScaleConfig *NodeGroupAutoScaleConfigDto `json:"autoScaleConfig,omitempty"` + UpgradeConfig NodeGroupUpgradeConfigDto `json:"upgradeConfig,omitempty"` + ImageId string `json:"imageId"` + FlavorId string `json:"flavorId"` + DiskSize int32 `json:"diskSize"` + DiskType string `json:"diskType"` + EnablePrivateNodes bool `json:"enablePrivateNodes"` + SecurityGroups []string `json:"securityGroups"` + SshKeyId string `json:"sshKeyId"` + Labels map[string]string `json:"labels,omitempty"` + Taints []NodeGroupTaintDto `json:"taints,omitempty"` +} diff --git a/client/vks/model_network_type.go b/client/vks/model_network_type.go new file mode 100644 index 0000000..0693921 --- /dev/null +++ b/client/vks/model_network_type.go @@ -0,0 +1,17 @@ +/* + * vks-api API + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 1.0-SNAPSHOT + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ +package vks + +type NetworkType string + +// List of NetworkType +const ( + CALICO_NetworkType NetworkType = "CALICO" + CILIUM_NetworkType NetworkType = "CILIUM" +) diff --git a/client/vks/model_node_dto.go b/client/vks/model_node_dto.go new file mode 100644 index 0000000..e5f9aa1 --- /dev/null +++ b/client/vks/model_node_dto.go @@ -0,0 +1,18 @@ +/* + * vks-api API + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 1.0-SNAPSHOT + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ +package vks + +type NodeDto struct { + Id string `json:"id,omitempty"` + Name string `json:"name,omitempty"` + Status string `json:"status,omitempty"` + FloatingIp string `json:"floatingIp,omitempty"` + FixedIp string `json:"fixedIp,omitempty"` + Ready bool `json:"ready,omitempty"` +} diff --git a/client/vks/model_node_group_auto_scale_config_dto.go b/client/vks/model_node_group_auto_scale_config_dto.go new file mode 100644 index 0000000..cc82757 --- /dev/null +++ b/client/vks/model_node_group_auto_scale_config_dto.go @@ -0,0 +1,14 @@ +/* + * vks-api API + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 1.0-SNAPSHOT + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ +package vks + +type NodeGroupAutoScaleConfigDto struct { + MinSize int32 `json:"minSize"` + MaxSize int32 `json:"maxSize"` +} diff --git a/client/vks/model_node_group_detail_dto.go b/client/vks/model_node_group_detail_dto.go new file mode 100644 index 0000000..e5086a6 --- /dev/null +++ b/client/vks/model_node_group_detail_dto.go @@ -0,0 +1,30 @@ +/* + * vks-api API + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 1.0-SNAPSHOT + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ +package vks + +type NodeGroupDetailDto struct { + Id string `json:"id,omitempty"` + ClusterId string `json:"clusterId,omitempty"` + Name string `json:"name,omitempty"` + Status string `json:"status,omitempty"` + NumNodes int64 `json:"numNodes,omitempty"` + ImageId string `json:"imageId,omitempty"` + CreatedAt string `json:"createdAt,omitempty"` + UpdatedAt string `json:"updatedAt,omitempty"` + FlavorId string `json:"flavorId,omitempty"` + DiskSize int32 `json:"diskSize,omitempty"` + DiskType string `json:"diskType,omitempty"` + EnablePrivateNodes bool `json:"enablePrivateNodes,omitempty"` + SshKeyId string `json:"sshKeyId,omitempty"` + SecurityGroups []string `json:"securityGroups,omitempty"` + AutoScaleConfig *NodeGroupAutoScaleConfigDto `json:"autoScaleConfig,omitempty"` + UpgradeConfig *NodeGroupUpgradeConfigDto `json:"upgradeConfig,omitempty"` + Labels map[string]string `json:"labels,omitempty"` + Taints []NodeGroupTaintDto `json:"taints,omitempty"` +} diff --git a/client/vks/model_node_group_dto.go b/client/vks/model_node_group_dto.go new file mode 100644 index 0000000..5dbb6b7 --- /dev/null +++ b/client/vks/model_node_group_dto.go @@ -0,0 +1,20 @@ +/* + * vks-api API + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 1.0-SNAPSHOT + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ +package vks + +type NodeGroupDto struct { + Id string `json:"id,omitempty"` + ClusterId string `json:"clusterId,omitempty"` + Name string `json:"name,omitempty"` + Status string `json:"status,omitempty"` + NumNodes int64 `json:"numNodes,omitempty"` + ImageId string `json:"imageId,omitempty"` + CreatedAt string `json:"createdAt,omitempty"` + UpdatedAt string `json:"updatedAt,omitempty"` +} diff --git a/client/vks/model_node_group_image_dto.go b/client/vks/model_node_group_image_dto.go new file mode 100644 index 0000000..5ab1b27 --- /dev/null +++ b/client/vks/model_node_group_image_dto.go @@ -0,0 +1,16 @@ +/* + * vks-api API + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 1.0-SNAPSHOT + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ +package vks + +type NodeGroupImageDto struct { + Id string `json:"id,omitempty"` + Os string `json:"os,omitempty"` + KubernetesVersion string `json:"kubernetesVersion,omitempty"` + Enable bool `json:"enable,omitempty"` +} diff --git a/client/vks/model_node_group_taint_dto.go b/client/vks/model_node_group_taint_dto.go new file mode 100644 index 0000000..ff66f30 --- /dev/null +++ b/client/vks/model_node_group_taint_dto.go @@ -0,0 +1,15 @@ +/* + * vks-api API + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 1.0-SNAPSHOT + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ +package vks + +type NodeGroupTaintDto struct { + Key string `json:"key"` + Value string `json:"value"` + Effect string `json:"effect"` +} diff --git a/client/vks/model_node_group_upgrade_config_dto.go b/client/vks/model_node_group_upgrade_config_dto.go new file mode 100644 index 0000000..69e4203 --- /dev/null +++ b/client/vks/model_node_group_upgrade_config_dto.go @@ -0,0 +1,15 @@ +/* + * vks-api API + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 1.0-SNAPSHOT + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ +package vks + +type NodeGroupUpgradeConfigDto struct { + Strategy string `json:"strategy"` + MaxSurge int32 `json:"maxSurge"` + MaxUnavailable int32 `json:"maxUnavailable"` +} diff --git a/client/vks/model_paging_result_dto_cluster_dto.go b/client/vks/model_paging_result_dto_cluster_dto.go new file mode 100644 index 0000000..6b90e2b --- /dev/null +++ b/client/vks/model_paging_result_dto_cluster_dto.go @@ -0,0 +1,16 @@ +/* + * vks-api API + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 1.0-SNAPSHOT + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ +package vks + +type PagingResultDtoClusterDto struct { + Items []ClusterDto `json:"items,omitempty"` + Total int64 `json:"total,omitempty"` + Page int32 `json:"page,omitempty"` + PageSize int32 `json:"pageSize,omitempty"` +} diff --git a/client/vks/model_paging_result_dto_node_dto.go b/client/vks/model_paging_result_dto_node_dto.go new file mode 100644 index 0000000..11a84ba --- /dev/null +++ b/client/vks/model_paging_result_dto_node_dto.go @@ -0,0 +1,16 @@ +/* + * vks-api API + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 1.0-SNAPSHOT + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ +package vks + +type PagingResultDtoNodeDto struct { + Items []NodeDto `json:"items,omitempty"` + Total int64 `json:"total,omitempty"` + Page int32 `json:"page,omitempty"` + PageSize int32 `json:"pageSize,omitempty"` +} diff --git a/client/vks/model_paging_result_dto_node_group_dto.go b/client/vks/model_paging_result_dto_node_group_dto.go new file mode 100644 index 0000000..20c2b3c --- /dev/null +++ b/client/vks/model_paging_result_dto_node_group_dto.go @@ -0,0 +1,16 @@ +/* + * vks-api API + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 1.0-SNAPSHOT + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ +package vks + +type PagingResultDtoNodeGroupDto struct { + Items []NodeGroupDto `json:"items,omitempty"` + Total int64 `json:"total,omitempty"` + Page int32 `json:"page,omitempty"` + PageSize int32 `json:"pageSize,omitempty"` +} diff --git a/client/vks/model_update_cluster_dto.go b/client/vks/model_update_cluster_dto.go new file mode 100644 index 0000000..bcf8f8d --- /dev/null +++ b/client/vks/model_update_cluster_dto.go @@ -0,0 +1,14 @@ +/* + * vks-api API + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 1.0-SNAPSHOT + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ +package vks + +type UpdateClusterDto struct { + Version string `json:"version"` + WhitelistNodeCIDRs []string `json:"whitelistNodeCIDRs"` +} diff --git a/client/vks/model_update_node_group_dto.go b/client/vks/model_update_node_group_dto.go new file mode 100644 index 0000000..264bfc5 --- /dev/null +++ b/client/vks/model_update_node_group_dto.go @@ -0,0 +1,17 @@ +/* + * vks-api API + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 1.0-SNAPSHOT + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ +package vks + +type UpdateNodeGroupDto struct { + AutoScaleConfig *NodeGroupAutoScaleConfigDto `json:"autoScaleConfig,omitempty"` + NumNodes int64 `json:"numNodes,omitempty"` + UpgradeConfig *NodeGroupUpgradeConfigDto `json:"upgradeConfig"` + SecurityGroups []string `json:"securityGroups"` + ImageId string `json:"imageId"` +} diff --git a/client/vks/model_workspace_dto.go b/client/vks/model_workspace_dto.go new file mode 100644 index 0000000..790dc76 --- /dev/null +++ b/client/vks/model_workspace_dto.go @@ -0,0 +1,15 @@ +/* + * vks-api API + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 1.0-SNAPSHOT + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ +package vks + +type WorkspaceDto struct { + ProjectId string `json:"projectId,omitempty"` + ServiceAccountId string `json:"serviceAccountId,omitempty"` + Status string `json:"status,omitempty"` +} diff --git a/client/vks/response.go b/client/vks/response.go new file mode 100644 index 0000000..3cf4000 --- /dev/null +++ b/client/vks/response.go @@ -0,0 +1,42 @@ +/* + * vks-api API + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 1.0-SNAPSHOT + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ +package vks + +import ( + "net/http" +) + +type APIResponse struct { + *http.Response `json:"-"` + Message string `json:"message,omitempty"` + // Operation is the name of the swagger operation. + Operation string `json:"operation,omitempty"` + // RequestURL is the request URL. This value is always available, even if the + // embedded *http.Response is nil. + RequestURL string `json:"url,omitempty"` + // Method is the HTTP method used for the request. This value is always + // available, even if the embedded *http.Response is nil. + Method string `json:"method,omitempty"` + // Payload holds the contents of the response body (which may be nil or empty). + // This is provided here as the raw response.Body() reader will have already + // been drained. + Payload []byte `json:"-"` +} + +func NewAPIResponse(r *http.Response) *APIResponse { + + response := &APIResponse{Response: r} + return response +} + +func NewAPIResponseWithError(errorMessage string) *APIResponse { + + response := &APIResponse{Message: errorMessage} + return response +} diff --git a/provider/provider.go b/provider/provider.go index 619f655..7c649a0 100644 --- a/provider/provider.go +++ b/provider/provider.go @@ -1,6 +1,7 @@ package provider import ( + "github.com/vngcloud/terraform-provider-vngcloud/resource/vks" "log" "github.com/vngcloud/terraform-provider-vngcloud/resource/vdb" @@ -60,6 +61,7 @@ func Provider() *schema.Provider { "vngcloud_vserver_network_interface": vserver.ResourceNetworkInterface(), "vngcloud_vserver_external_interface_attach": vserver.ResourceAttachExternalInterface(), "vngcloud_vserver_internal_interface_attach": vserver.ResourceAttachInternalInterface(), + "vngcloud_vks_cluster": vks.ResourceCluster(), }, Schema: map[string]*schema.Schema{ "token_url": { @@ -92,6 +94,12 @@ func Provider() *schema.Provider { DefaultFunc: schema.EnvDefaultFunc("VLB_BASE_URL", ""), Description: "endpoint to connection with provider resource", }, + "vks_base_url": { + Type: schema.TypeString, + Optional: true, + DefaultFunc: schema.EnvDefaultFunc("VKS_BASE_URL", ""), + Description: "endpoint to connection with provider resource", + }, }, ConfigureFunc: providerConfigure, } @@ -115,5 +123,11 @@ func providerConfigure(d *schema.ResourceData) (interface{}, error) { } clientID := d.Get("client_id").(string) clientSecret := d.Get("client_secret").(string) - return client.NewClientV2(vserverBaseURL, vlbBaseURL, clientID, clientSecret, tokenURL) + + vksBaseURL := "https://vks.api.vngcloud.vn" + _, hasVksBaseUrl := d.GetOk("vks_base_url") + if hasVksBaseUrl { + vksBaseURL = d.Get("vks_base_url").(string) + } + return client.NewClientV2(vserverBaseURL, vlbBaseURL, vksBaseURL, clientID, clientSecret, tokenURL) } diff --git a/resource/vks/config.go b/resource/vks/config.go new file mode 100644 index 0000000..8bc8e1c --- /dev/null +++ b/resource/vks/config.go @@ -0,0 +1,11 @@ +package vks + +var ( + CREATING = []string{"CREATING"} + ERROR = []string{"ERROR"} + DELETING = []string{"DELETING"} + ACTIVE = []string{"ACTIVE"} + UPDATING = []string{"UPDATING"} + DEGRADED = []string{"DEGRADED"} + DELETED = []string{"DELETED"} +) diff --git a/resource/vks/resource_cluster.go b/resource/vks/resource_cluster.go new file mode 100644 index 0000000..fe8a75e --- /dev/null +++ b/resource/vks/resource_cluster.go @@ -0,0 +1,505 @@ +package vks + +import ( + "context" + "encoding/json" + "fmt" + "github.com/antihax/optional" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/vngcloud/terraform-provider-vngcloud/client" + "github.com/vngcloud/terraform-provider-vngcloud/client/vks" + "log" + "net/http" + "time" +) + +func ResourceCluster() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + MigrateState: resourceClusterMigrateState, + //StateUpgraders: []schema.StateUpgrader{ + // { + // Type: resourceContainerClusterResourceV1().CoreConfigSchema().ImpliedType(), + // Upgrade: ResourceContainerClusterUpgradeV1, + // Version: 1, + // }, + //}, + + Create: resourceClusterCreate, + Read: resourceClusterRead, + Update: resourceClusterUpdate, + Delete: resourceClusterDelete, + //Importer: &schema.ResourceImporter{ + // State: func(d *schema.ResourceData, m interface{}) ([]*schema.ResourceData, error) { + // idParts := strings.Split(d.Id(), ":") + // if len(idParts) != 2 || idParts[0] == "" || idParts[1] == "" { + // return nil, fmt.Errorf("Unexpected format of ID (%q), expected ProjectID:VolumeID", d.Id()) + // } + // projectID := idParts[0] + // volumeID := idParts[1] + // d.SetId(volumeID) + // d.Set("project_id", projectID) + // return []*schema.ResourceData{d}, nil + // }, + //}, + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "config": { + Type: schema.TypeString, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + "version": { + Type: schema.TypeString, + Optional: true, + DefaultFunc: func() (interface{}, error) { + return "v1.29.1", nil + }, + }, + "white_list_node_cidr": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "enable_private_cluster": { + Type: schema.TypeBool, + Optional: true, + ForceNew: true, + DefaultFunc: func() (interface{}, error) { + return false, nil + }, + }, + "network_type": { + Type: schema.TypeString, + Optional: true, + Default: "CALICO", + ForceNew: true, + }, + "vpc_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "subnet_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "cidr": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "enabled_load_balancer_plugin": { + Type: schema.TypeBool, + Optional: true, + ForceNew: true, + Default: true, + }, + "enabled_block_store_csi_plugin": { + Type: schema.TypeBool, + Optional: true, + ForceNew: true, + Default: true, + }, + "node_group": { + Type: schema.TypeList, + Optional: true, + Computed: true, + ForceNew: true, + Elem: &schema.Resource{ + Schema: schemaNodeGroup, + }, + }, + }, + } +} +func resourceClusterStateRefreshFunc(cli *client.Client, clusterID string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + resp, httpResponse, _ := cli.VksClient.V1ClusterControllerApi.V1ClustersClusterIdGet(context.TODO(), clusterID, nil) + if httpResponse.StatusCode != http.StatusOK { + return nil, "", fmt.Errorf("Error : %s", GetResponseBody(httpResponse)) + } + respJSON, _ := json.Marshal(resp) + log.Printf("-------------------------------------\n") + log.Printf("%s\n", string(respJSON)) + log.Printf("-------------------------------------\n") + cluster := resp + return cluster, cluster.Status, nil + } +} +func resourceClusterCreate(d *schema.ResourceData, m interface{}) error { + nodeGroupsJson, _ := json.Marshal(d.Get("node_group").([]interface{})) + log.Printf("xxxxx-------------------------------------\n") + log.Printf("%s\n", string(nodeGroupsJson)) + log.Printf("-------------------------------------\n") + createNodeGroupRequests := expandNodeGroupForCreating(d.Get("node_group").([]interface{})) + nodeGroupsJson, _ = json.Marshal(createNodeGroupRequests) + log.Printf("------------------node_group_request-------------------\n") + log.Printf("%s\n", string(nodeGroupsJson)) + log.Printf("-------------------------------------\n") + createClusterRequest := vks.CreateClusterComboDto{ + Name: d.Get("name").(string), + Description: d.Get("description").(string), + Version: d.Get("version").(string), + EnablePrivateCluster: d.Get("enable_private_cluster").(bool), + NetworkType: d.Get("network_type").(string), + VpcId: d.Get("vpc_id").(string), + SubnetId: d.Get("subnet_id").(string), + Cidr: d.Get("cidr").(string), + EnabledLoadBalancerPlugin: d.Get("enabled_load_balancer_plugin").(bool), + EnabledBlockStoreCsiPlugin: d.Get("enabled_block_store_csi_plugin").(bool), + NodeGroups: createNodeGroupRequests, + } + cli := m.(*client.Client) + request := vks.V1ClusterControllerApiV1ClustersPostOpts{ + Body: optional.NewInterface(createClusterRequest), + } + resp, httpResponse, _ := cli.VksClient.V1ClusterControllerApi.V1ClustersPost(context.TODO(), &request) + + if CheckErrorResponse(httpResponse) { + responseBody := GetResponseBody(httpResponse) + errResponse := fmt.Errorf("request fail with errMsg: %s", responseBody) + return errResponse + } + respJSON, _ := json.Marshal(resp) + log.Printf("-------------------------------------\n") + log.Printf("%s\n", string(respJSON)) + log.Printf("-------------------------------------\n") + + stateConf := &resource.StateChangeConf{ + Pending: CREATING, + Target: ACTIVE, + Refresh: resourceClusterStateRefreshFunc(cli, resp.Id), + Timeout: 180 * time.Minute, + Delay: 10 * time.Second, + MinTimeout: 1 * time.Second, + } + _, err := stateConf.WaitForState() + if err != nil { + return fmt.Errorf("error waiting for create cluster (%s) %s", resp.Id, err) + } + if len(createNodeGroupRequests) > 0 { + stateConf = &resource.StateChangeConf{ + Pending: CREATING, + Target: ACTIVE, + Refresh: resourceNodeGroupForClusterStateRefreshFunc(cli, resp.Id), + Timeout: 180 * time.Minute, + Delay: 10 * time.Second, + MinTimeout: 1 * time.Second, + } + log.Printf("Node group size >0.................") + _, err := stateConf.WaitForState() + if err != nil { + return fmt.Errorf("error waiting for create cluster (%s) %s", resp.Id, err) + } + updateNodeGroupData(cli, d, resp.Id) + } + d.SetId(resp.Id) + + return resourceClusterRead(d, m) +} + +func updateNodeGroupData(cli *client.Client, d *schema.ResourceData, clusterId string) error { + nodeGroups := d.Get("node_group").([]interface{}) + updatedNodeGroups := make([]interface{}, len(nodeGroups)) + resp, httpResponse, _ := cli.VksClient.V1NodeGroupControllerApi.V1ClustersClusterIdNodeGroupsGet(context.TODO(), clusterId, nil) + if httpResponse.StatusCode != http.StatusOK { + return fmt.Errorf("Error : %s", GetResponseBody(httpResponse)) + } + respJSON, _ := json.Marshal(resp) + log.Printf("-------------------------------------\n") + log.Printf("%s\n", string(respJSON)) + log.Printf("-------------------------------------\n") + clusterNodeGroups := resp.Items + for i, ng := range nodeGroups { + nodeGroup := ng.(map[string]interface{}) + clusterNodeGroup := clusterNodeGroups[i] + // Set the value for a specific field + upgradeConfig := nodeGroup["upgrade_config"].([]interface{}) + if len(upgradeConfig) == 0 { + clusterNodeGroupDetail, httpResponse, _ := cli.VksClient.V1NodeGroupControllerApi.V1ClustersClusterIdNodeGroupsNodeGroupIdGet(context.TODO(), clusterId, clusterNodeGroup.Id, nil) + if httpResponse.StatusCode != http.StatusOK { + return fmt.Errorf("Error : %s", GetResponseBody(httpResponse)) + } + defaultConfig := []interface{}{ + map[string]interface{}{ + "strategy": clusterNodeGroupDetail.UpgradeConfig.Strategy, + "max_surge": clusterNodeGroupDetail.UpgradeConfig.MaxSurge, + "max_unavailable": clusterNodeGroupDetail.UpgradeConfig.MaxUnavailable, + }, + } + nodeGroup["upgrade_config"] = defaultConfig + } + + updatedNodeGroups[i] = nodeGroup + } + + // Update the node_group field with the modified values + if err := d.Set("node_group", updatedNodeGroups); err != nil { + return fmt.Errorf("error setting node_group: %s", err) + } + + return nil +} + +func expandNodeGroupForCreating(node_group []interface{}) []vks.CreateNodeGroupDto { + if len(node_group) == 0 { + log.Printf("node_group 0\n") + return []vks.CreateNodeGroupDto{} + } else if node_group[0] == nil { + log.Printf("node_group nil\n") + return []vks.CreateNodeGroupDto{} + } + nodeGroupsJson, _ := json.Marshal(node_group) + log.Printf("aaaaa-------------------------------------\n") + log.Printf("%s\n", string(nodeGroupsJson)) + createNodeGroupRequests := make([]vks.CreateNodeGroupDto, len(node_group)) + for i, ng := range node_group { + nodeGroup, ok := ng.(map[string]interface{}) + if !ok { + log.Fatalf("Element at index %d is not a map", i) + } + nodeGroupsJson, _ := json.Marshal(nodeGroup) + log.Printf("bbbbb-------------------------------------\n") + log.Printf("%s\n", string(nodeGroupsJson)) + createNodeGroupRequest := getCreateNodeGroupReuqest(nodeGroup) + createNodeGroupRequests[i] = createNodeGroupRequest + } + //tfMap, ok := node_group[0].(map[string]interface{}) + //if !ok { + //} + + //createHealthMonitor := &vloadbalancing.CreateHealthMonitorRequest{} + //if v, ok := tfMap["health_check_method"]; ok && v != "" { + // createHealthMonitor.HealthCheckMethod = new(string) + // *createHealthMonitor.HealthCheckMethod = v.(string) + //} + //if v, ok := tfMap["health_check_path"]; ok && v != "" { + // createHealthMonitor.HealthCheckPath = new(string) + // *createHealthMonitor.HealthCheckPath = v.(string) + //} + //if vHealthCheckProtocol, ok := tfMap["health_check_protocol"]; ok { + // createHealthMonitor.HealthCheckProtocol = vHealthCheckProtocol.(string) + //} + //if v, ok := tfMap["healthy_threshold"]; ok { + // createHealthMonitor.HealthyThreshold = int64(v.(int)) + //} + //if vUnhealthyThreshold, ok := tfMap["unhealthy_threshold"]; ok { + // createHealthMonitor.UnhealthyThreshold = int64(vUnhealthyThreshold.(int)) + //} + //if v, ok := tfMap["interval"]; ok { + // createHealthMonitor.Interval = int64(v.(int)) + //} + //if v, ok := tfMap["timeout"]; ok { + // createHealthMonitor.Timeout = int64(v.(int)) + //} + //if v, ok := tfMap["success_code"]; ok && v != "" { + // createHealthMonitor.SuccessCode = new(string) + // *createHealthMonitor.SuccessCode = v.(string) + //} + // + //if v, ok := tfMap["http_version"]; ok && v != "" { + // createHealthMonitor.HttpVersion = new(string) + // *createHealthMonitor.HttpVersion = v.(string) + //} + // + //if v, ok := tfMap["domain_name"]; ok && v != "" { + // createHealthMonitor.DomainName = new(string) + // *createHealthMonitor.DomainName = v.(string) + //} + // + return createNodeGroupRequests +} + +func resourceClusterRead(d *schema.ResourceData, m interface{}) error { + clusterID := d.Id() + cli := m.(*client.Client) + resp, httpResponse, _ := cli.VksClient.V1ClusterControllerApi.V1ClustersClusterIdGet(context.TODO(), clusterID, nil) + if CheckErrorResponse(httpResponse) { + responseBody := GetResponseBody(httpResponse) + errorResponse := fmt.Errorf("request fail with errMsg : %s", responseBody) + return errorResponse + } + respJSON, _ := json.Marshal(resp) + log.Printf("-------------------------------------\n") + log.Printf("%s\n", string(respJSON)) + log.Printf("-------------------------------------\n") + cluster := resp + d.Set("version", cluster.Version) + whiteListNodeCIDRRequest := d.Get("white_list_node_cidr").([]interface{}) + var whiteListNodeCIDR []string + for _, s := range whiteListNodeCIDRRequest { + whiteListNodeCIDR = append(whiteListNodeCIDR, s.(string)) + } + var whiteListCIDRCluster []string + for _, whiteList := range cluster.WhitelistNodeCIDRs { + whiteListCIDRCluster = append(whiteListCIDRCluster, whiteList) + } + if !CheckListStringEqual(whiteListNodeCIDR, whiteListCIDRCluster) { + d.Set("white_list_node_cidr", whiteListCIDRCluster) + } + log.Printf("GetConfig\n") + configResp, httpResponse, _ := cli.VksClient.V1ClusterControllerApi.V1ClustersClusterIdKubeconfigGet(context.TODO(), clusterID, nil) + if !CheckErrorResponse(httpResponse) { + log.Printf("SetConfig\n") + d.Set("config", configResp) + } + return nil +} + +func resourceClusterUpdate(d *schema.ResourceData, m interface{}) error { + if d.HasChange("white_list_node_cidr") || d.HasChange("version") { + return changeWhiteListNodeOrVersion(d, m) + } + if d.HasChange("node_group") { + return changeNodeGroup(d, m) + } + return resourceClusterRead(d, m) +} + +func changeWhiteListNodeOrVersion(d *schema.ResourceData, m interface{}) error { + whiteListCIDRsInterface := d.Get("white_list_node_cidr").([]interface{}) + var whiteListCIDR []string + for _, s := range whiteListCIDRsInterface { + whiteListCIDR = append(whiteListCIDR, s.(string)) + } + if len(whiteListCIDR) == 0 { + return fmt.Errorf(`The argument "white_list_node_cidr" must not be empty.`) + } + updateCluster := vks.UpdateClusterDto{ + Version: d.Get("version").(string), + WhitelistNodeCIDRs: whiteListCIDR, + } + cli := m.(*client.Client) + request := vks.V1ClusterControllerApiV1ClustersClusterIdPutOpts{ + Body: optional.NewInterface(updateCluster), + } + resp, httpResponse, err := cli.VksClient.V1ClusterControllerApi.V1ClustersClusterIdPut(context.TODO(), d.Id(), &request) + if CheckErrorResponse(httpResponse) { + responseBody := GetResponseBody(httpResponse) + errorResponse := fmt.Errorf("request fail with errMsg : %s", responseBody) + oldVersion, _ := d.GetChange("version") + oldWhiteListNodeCIDR, _ := d.GetChange("white_list_node_cidr") + d.Set("version", oldVersion) + d.Set("white_list_node_cidr", oldWhiteListNodeCIDR) + return errorResponse + } + respJSON, _ := json.Marshal(resp) + log.Printf("-------------------------------------\n") + log.Printf("%s\n", string(respJSON)) + log.Printf("-------------------------------------\n") + stateConf := &resource.StateChangeConf{ + Pending: UPDATING, + Target: ACTIVE, + Refresh: resourceClusterStateRefreshFunc(cli, d.Id()), + Timeout: d.Timeout(schema.TimeoutUpdate), + Delay: 10 * time.Second, + MinTimeout: 1 * time.Second, + } + _, err = stateConf.WaitForState() + if err != nil { + return fmt.Errorf("Error waiting for instance (%s) to be created: %s", d.Id(), err) + } + return resourceClusterRead(d, m) +} + +func changeNodeGroup(d *schema.ResourceData, m interface{}) error { + return resourceClusterRead(d, m) +} + +func resourceClusterDelete(d *schema.ResourceData, m interface{}) error { + cli := m.(*client.Client) + resp, httpResponse, err := cli.VksClient.V1ClusterControllerApi.V1ClustersClusterIdDelete(context.TODO(), d.Id(), nil) + if CheckErrorResponse(httpResponse) { + responseBody := GetResponseBody(httpResponse) + errorResponse := fmt.Errorf("request fail with errMsg : %s", responseBody) + return errorResponse + } + respJSON, _ := json.Marshal(resp) + log.Printf("-------------------------------------\n") + log.Printf("%s\n", string(respJSON)) + log.Printf("-------------------------------------\n") + stateConf := &resource.StateChangeConf{ + Pending: DELETING, + Target: DELETED, + Refresh: resourceClusterDeleteStateRefreshFunc(cli, d.Id()), + Timeout: d.Timeout(schema.TimeoutCreate), + Delay: 10 * time.Second, + MinTimeout: 1 * time.Second, + } + _, err = stateConf.WaitForState() + if err != nil { + return fmt.Errorf("Error waiting for instance (%s) to be created: %s", d.Id(), err) + } + d.SetId("") + return nil +} + +func resourceClusterDeleteStateRefreshFunc(cli *client.Client, clusterId string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + resp, httpResponse, _ := cli.VksClient.V1ClusterControllerApi.V1ClustersClusterIdGet(context.TODO(), clusterId, nil) + if httpResponse.StatusCode != http.StatusOK { + if httpResponse.StatusCode == http.StatusNotFound { + return vks.ClusterDto{Status: "DELETED"}, "DELETED", nil + } else { + return nil, "", fmt.Errorf("Error describing instance: %s", GetResponseBody(httpResponse)) + } + } + respJSON, _ := json.Marshal(resp) + log.Printf("-------------------------------------\n") + log.Printf("%s\n", string(respJSON)) + log.Printf("-------------------------------------\n") + return resp, resp.Status, nil + } +} + +func resourceClusterMigrateState( + v int, is *terraform.InstanceState, meta interface{}) (*terraform.InstanceState, error) { + if is.Empty() { + log.Println("[DEBUG] Empty InstanceState; nothing to migrate.") + return is, nil + } + switch v { + case 1: + log.Println("[INFO] Found Cluster State v1 in legacy migration function; returning as non-op") + return is, nil + default: + return is, fmt.Errorf("Unexpected schema version: %d", v) + } +} + +func resourceNodeGroupForClusterStateRefreshFunc(cli *client.Client, clusterID string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + resp, httpResponse, _ := cli.VksClient.V1NodeGroupControllerApi.V1ClustersClusterIdNodeGroupsGet(context.TODO(), clusterID, nil) + if httpResponse.StatusCode != http.StatusOK { + return nil, "", fmt.Errorf("Error : %s", GetResponseBody(httpResponse)) + } + respJSON, _ := json.Marshal(resp) + log.Printf("-------------------------------------\n") + log.Printf("%s\n", string(respJSON)) + log.Printf("-------------------------------------\n") + clusterNodeGroups := resp.Items + var status string + for _, clusterNodeGroup := range clusterNodeGroups { + status = clusterNodeGroup.Status + if clusterNodeGroup.Status != "ACTIVE" { + break + } + } + return clusterNodeGroups, status, nil + } +} diff --git a/resource/vks/resrouce_cluster_node_group.go b/resource/vks/resrouce_cluster_node_group.go new file mode 100644 index 0000000..c8fa474 --- /dev/null +++ b/resource/vks/resrouce_cluster_node_group.go @@ -0,0 +1,291 @@ +package vks + +import ( + "context" + "encoding/json" + "fmt" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + "github.com/vngcloud/terraform-provider-vngcloud/client" + "github.com/vngcloud/terraform-provider-vngcloud/client/vks" + "log" + "net/http" +) + +var schemaNodeGroup = map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "num_nodes": { + Type: schema.TypeInt, + Optional: true, + Default: 1, + }, + "auto_scale_config": { + Type: schema.TypeList, + MaxItems: 1, + Optional: true, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "min_size": { + Type: schema.TypeInt, + Optional: true, + Default: 1, + }, + "max_size": { + Type: schema.TypeInt, + Optional: true, + Default: 10, + }, + }, + }, + DefaultFunc: func() (interface{}, error) { + return []interface{}{ + map[string]interface{}{ + "max_size": 10, + "min_size": 1, + }, + }, nil + }, + }, + "upgrade_config": { + Type: schema.TypeList, + MaxItems: 1, + Optional: true, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "strategy": { + Type: schema.TypeString, + Optional: true, + Default: "SURGE", + }, + "max_surge": { + Type: schema.TypeInt, + Optional: true, + Default: 1, + }, + "max_unavailable": { + Type: schema.TypeInt, + Optional: true, + Default: 0, + }, + }, + }, + DefaultFunc: func() (interface{}, error) { + return []interface{}{ + map[string]interface{}{ + "strategy": "SURGE", + "max_surge": 1, + "max_unavailable": 0, + }, + }, nil + }, + }, + "image_id": { + Type: schema.TypeString, + Optional: true, + DefaultFunc: func() (interface{}, error) { + return "img-108b3a77-ab58-4000-9b3e-190d0b4b07fc", nil + }, + }, + "flavor_id": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + DefaultFunc: func() (interface{}, error) { + return "flav-152e00ea-5412-44c5-868f-0b30e37e4f90", nil + }, + }, + "disk_size": { + Type: schema.TypeInt, + Optional: true, + ForceNew: true, + DefaultFunc: func() (interface{}, error) { + return 20, nil + }, + }, + "disk_type": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + DefaultFunc: func() (interface{}, error) { + return "vtype-4b437071-da9c-4e1b-a2c0-839fb89e5182", nil + }, + }, + "enable_private_nodes": { + Type: schema.TypeBool, + Optional: true, + ForceNew: true, + DefaultFunc: func() (interface{}, error) { + return false, nil + }, + }, + "security_groups": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "ssh_key_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "labels": { + Type: schema.TypeMap, + Optional: true, + ForceNew: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Description: `The map of Kubernetes labels (key/value pairs) to be applied to each node. These will added in addition to any default label(s) that Kubernetes may apply to the node.`, + }, + "taint": { + Type: schema.TypeList, + Optional: true, + ForceNew: true, + Description: `List of Kubernetes taints to be applied to each node.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "key": { + Type: schema.TypeString, + Required: true, + Description: `Key for taint.`, + }, + "value": { + Type: schema.TypeString, + Required: true, + Description: `Value for taint.`, + }, + "effect": { + Type: schema.TypeString, + Optional: true, + Default: "NoSchedule", + ValidateFunc: validation.StringInSlice([]string{"NoSchedule", "PreferNoSchedule", "NoExecute"}, false), + Description: `Effect for taint.`, + }, + }, + }, + }, +} + +func getCreateNodeGroupReuqest(nodeGroup map[string]interface{}) vks.CreateNodeGroupDto { + taintsInput, ok := nodeGroup["taints"].([]interface{}) + var tains []vks.NodeGroupTaintDto + if ok { + tains = getTaints(taintsInput) + } else { + tains = nil + } + return vks.CreateNodeGroupDto{ + Name: nodeGroup["name"].(string), + NumNodes: int32(nodeGroup["num_nodes"].(int)), + ImageId: nodeGroup["image_id"].(string), + FlavorId: nodeGroup["flavor_id"].(string), + DiskSize: int32(nodeGroup["disk_size"].(int)), + DiskType: nodeGroup["disk_type"].(string), + EnablePrivateNodes: nodeGroup["enable_private_nodes"].(bool), + SshKeyId: nodeGroup["ssh_key_id"].(string), + Labels: getLabels(nodeGroup["labels"].(map[string]interface{})), + Taints: tains, + SecurityGroups: getSecurityGroups(nodeGroup["security_groups"].([]interface{})), + UpgradeConfig: getUpgradeConfig(nodeGroup["upgrade_config"].([]interface{})), + AutoScaleConfig: getAutoScaleConfig(nodeGroup["auto_scale_config"].([]interface{})), + } +} + +func getSecurityGroups(input []interface{}) []string { + + securityGroups := make([]string, len(input)) + + for i, v := range input { + str, ok := v.(string) + if !ok { + return []string{} + } + securityGroups[i] = str + } + + return securityGroups +} + +func getUpgradeConfig(input []interface{}) vks.NodeGroupUpgradeConfigDto { + if len(input) == 0 { + return vks.NodeGroupUpgradeConfigDto{ + MaxUnavailable: 0, + MaxSurge: 1, + Strategy: "SURGE", + } + } + upgradeConfig, ok := input[0].(map[string]interface{}) + if !ok { + log.Fatalf("Element at index %d is not a map", 0) + } + + return vks.NodeGroupUpgradeConfigDto{ + Strategy: upgradeConfig["strategy"].(string), + MaxSurge: int32(upgradeConfig["max_surge"].(int)), + MaxUnavailable: int32(upgradeConfig["max_unavailable"].(int)), + } +} + +func getAutoScaleConfig(input []interface{}) *vks.NodeGroupAutoScaleConfigDto { + if len(input) == 0 { + return nil + } + autoScaleConfig := input[0].(map[string]interface{}) + + return &vks.NodeGroupAutoScaleConfigDto{ + MaxSize: int32(autoScaleConfig["max_size"].(int)), + MinSize: int32(autoScaleConfig["min_size"].(int)), + } +} + +func getLabels(input map[string]interface{}) map[string]string { + labels := make(map[string]string, len(input)) + + for k, v := range input { + str, ok := v.(string) + if !ok { + return nil + } + labels[k] = str + } + + return labels +} + +func getTaints(input []interface{}) []vks.NodeGroupTaintDto { + taints := make([]vks.NodeGroupTaintDto, len(input)) + + for i, rawTaint := range input { + taint := rawTaint.(map[string]interface{}) + taintDto := vks.NodeGroupTaintDto{ + Key: taint["key"].(string), + Value: taint["value"].(string), + Effect: taint["effect"].(string), + } + taints[i] = taintDto + } + + return taints +} + +func resourceClusterNodeGroupStateRefreshFunc(cli *client.Client, clusterID string, clusterNodeGroupID string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + resp, httpResponse, _ := cli.VksClient.V1NodeGroupControllerApi.V1ClustersClusterIdNodeGroupsNodeGroupIdNodesGet(context.TODO(), clusterID, clusterNodeGroupID, nil) + if httpResponse.StatusCode != http.StatusOK { + return nil, "", fmt.Errorf("Error : %s", GetResponseBody(httpResponse)) + } + respJSON, _ := json.Marshal(resp) + log.Printf("-------------------------------------\n") + log.Printf("%s\n", string(respJSON)) + log.Printf("-------------------------------------\n") + clusterNodeGroup := resp + return clusterNodeGroup, clusterNodeGroup.Items[0].Status, nil + } +} diff --git a/resource/vks/util.go b/resource/vks/util.go new file mode 100644 index 0000000..f97b9e8 --- /dev/null +++ b/resource/vks/util.go @@ -0,0 +1,44 @@ +package vks + +import ( + "fmt" + "io" + "net/http" +) + +func CheckErrorResponse(httpResponse *http.Response) bool { + if httpResponse.StatusCode < 200 || httpResponse.StatusCode > 299 { + return true + } + return false +} + +func GetResponseBody(httpResponse *http.Response) string { + localVarBody, _ := io.ReadAll(httpResponse.Body) + responseMessage := string(localVarBody) + if httpResponse.StatusCode == 403 { + responseMessage = "You don't have permission to do this action" + } + return fmt.Sprint("Status Code: ", httpResponse.StatusCode, ", ", responseMessage) +} + +func CheckContainString(list []string, findElement string) bool { + for _, element := range list { + if element == findElement { + return true + } + } + return false +} + +func CheckListStringEqual(firstList []string, secondList []string) bool { + if len(firstList) == len(secondList) { + for _, element := range firstList { + if !CheckContainString(secondList, element) { + return false + } + } + return true + } + return false +} diff --git a/terraform_run_with_debug.sh b/terraform_run_with_debug.sh deleted file mode 100755 index ce6fa72..0000000 --- a/terraform_run_with_debug.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -#cd terraform/examples -cd ./examples || exit - -# Set the log level to debug -export TF_LOG=debug - -#verbose logging -export TF_LOG_PROVIDERS=debug - -# Run the terraform command with the specified arguments -terraform "$@" - -#running ./terraform-debug.sh apply -auto-approve -#running ./terraform-debug.sh init && terraform apply --auto-approve From c1fc0492fb81d874bdb7ead00a3c431b6f21372e Mon Sep 17 00:00:00 2001 From: tunm4 <8-tunm4_2@users.noreply.git.vngcloud.dev> Date: Mon, 27 May 2024 19:06:08 +0700 Subject: [PATCH 02/14] update --- client/vks/model_update_node_group_dto.go | 2 +- provider/provider.go | 1 + resource/vks/config.go | 5 +- resource/vks/resource_cluster.go | 137 +++++--- resource/vks/resrouce_cluster_node_group.go | 338 +++++++++++++++++--- resource/vks/util.go | 49 +++ 6 files changed, 441 insertions(+), 91 deletions(-) diff --git a/client/vks/model_update_node_group_dto.go b/client/vks/model_update_node_group_dto.go index 264bfc5..43b02fb 100644 --- a/client/vks/model_update_node_group_dto.go +++ b/client/vks/model_update_node_group_dto.go @@ -10,7 +10,7 @@ package vks type UpdateNodeGroupDto struct { AutoScaleConfig *NodeGroupAutoScaleConfigDto `json:"autoScaleConfig,omitempty"` - NumNodes int64 `json:"numNodes,omitempty"` + NumNodes int32 `json:"numNodes,omitempty"` UpgradeConfig *NodeGroupUpgradeConfigDto `json:"upgradeConfig"` SecurityGroups []string `json:"securityGroups"` ImageId string `json:"imageId"` diff --git a/provider/provider.go b/provider/provider.go index 7c649a0..916842c 100644 --- a/provider/provider.go +++ b/provider/provider.go @@ -62,6 +62,7 @@ func Provider() *schema.Provider { "vngcloud_vserver_external_interface_attach": vserver.ResourceAttachExternalInterface(), "vngcloud_vserver_internal_interface_attach": vserver.ResourceAttachInternalInterface(), "vngcloud_vks_cluster": vks.ResourceCluster(), + "vngcloud_vks_cluster_node_group": vks.ResourceClusterNodeGroup(), }, Schema: map[string]*schema.Schema{ "token_url": { diff --git a/resource/vks/config.go b/resource/vks/config.go index 8bc8e1c..0558914 100644 --- a/resource/vks/config.go +++ b/resource/vks/config.go @@ -1,11 +1,10 @@ package vks var ( - CREATING = []string{"CREATING"} + CREATING = []string{"CREATING", "DEGRADED"} ERROR = []string{"ERROR"} DELETING = []string{"DELETING"} ACTIVE = []string{"ACTIVE"} - UPDATING = []string{"UPDATING"} - DEGRADED = []string{"DEGRADED"} + UPDATING = []string{"UPDATING", "DEGRADED"} DELETED = []string{"DELETED"} ) diff --git a/resource/vks/resource_cluster.go b/resource/vks/resource_cluster.go index fe8a75e..7403a7e 100644 --- a/resource/vks/resource_cluster.go +++ b/resource/vks/resource_cluster.go @@ -63,7 +63,7 @@ func ResourceCluster() *schema.Resource { Type: schema.TypeString, Optional: true, DefaultFunc: func() (interface{}, error) { - return "v1.29.1", nil + return fetchByKey("k8s_version") }, }, "white_list_node_cidr": { @@ -121,7 +121,14 @@ func ResourceCluster() *schema.Resource { Computed: true, ForceNew: true, Elem: &schema.Resource{ - Schema: schemaNodeGroup, + Schema: MergeSchemas( + schemaNodeGroup, + map[string]*schema.Schema{ + "node_group_id": { + Type: schema.TypeString, + Computed: true, + }, + }), }, }, }, @@ -235,14 +242,15 @@ func updateNodeGroupData(cli *client.Client, d *schema.ResourceData, clusterId s if httpResponse.StatusCode != http.StatusOK { return fmt.Errorf("Error : %s", GetResponseBody(httpResponse)) } - defaultConfig := []interface{}{ + upgradeConfig := []interface{}{ map[string]interface{}{ "strategy": clusterNodeGroupDetail.UpgradeConfig.Strategy, "max_surge": clusterNodeGroupDetail.UpgradeConfig.MaxSurge, "max_unavailable": clusterNodeGroupDetail.UpgradeConfig.MaxUnavailable, }, } - nodeGroup["upgrade_config"] = defaultConfig + nodeGroup["upgrade_config"] = upgradeConfig + nodeGroup["node_group_id"] = clusterNodeGroupDetail.Id } updatedNodeGroups[i] = nodeGroup @@ -276,52 +284,9 @@ func expandNodeGroupForCreating(node_group []interface{}) []vks.CreateNodeGroupD nodeGroupsJson, _ := json.Marshal(nodeGroup) log.Printf("bbbbb-------------------------------------\n") log.Printf("%s\n", string(nodeGroupsJson)) - createNodeGroupRequest := getCreateNodeGroupReuqest(nodeGroup) + createNodeGroupRequest := getCreateNodeGroupRequestForCluster(nodeGroup) createNodeGroupRequests[i] = createNodeGroupRequest } - //tfMap, ok := node_group[0].(map[string]interface{}) - //if !ok { - //} - - //createHealthMonitor := &vloadbalancing.CreateHealthMonitorRequest{} - //if v, ok := tfMap["health_check_method"]; ok && v != "" { - // createHealthMonitor.HealthCheckMethod = new(string) - // *createHealthMonitor.HealthCheckMethod = v.(string) - //} - //if v, ok := tfMap["health_check_path"]; ok && v != "" { - // createHealthMonitor.HealthCheckPath = new(string) - // *createHealthMonitor.HealthCheckPath = v.(string) - //} - //if vHealthCheckProtocol, ok := tfMap["health_check_protocol"]; ok { - // createHealthMonitor.HealthCheckProtocol = vHealthCheckProtocol.(string) - //} - //if v, ok := tfMap["healthy_threshold"]; ok { - // createHealthMonitor.HealthyThreshold = int64(v.(int)) - //} - //if vUnhealthyThreshold, ok := tfMap["unhealthy_threshold"]; ok { - // createHealthMonitor.UnhealthyThreshold = int64(vUnhealthyThreshold.(int)) - //} - //if v, ok := tfMap["interval"]; ok { - // createHealthMonitor.Interval = int64(v.(int)) - //} - //if v, ok := tfMap["timeout"]; ok { - // createHealthMonitor.Timeout = int64(v.(int)) - //} - //if v, ok := tfMap["success_code"]; ok && v != "" { - // createHealthMonitor.SuccessCode = new(string) - // *createHealthMonitor.SuccessCode = v.(string) - //} - // - //if v, ok := tfMap["http_version"]; ok && v != "" { - // createHealthMonitor.HttpVersion = new(string) - // *createHealthMonitor.HttpVersion = v.(string) - //} - // - //if v, ok := tfMap["domain_name"]; ok && v != "" { - // createHealthMonitor.DomainName = new(string) - // *createHealthMonitor.DomainName = v.(string) - //} - // return createNodeGroupRequests } @@ -418,6 +383,57 @@ func changeWhiteListNodeOrVersion(d *schema.ResourceData, m interface{}) error { } func changeNodeGroup(d *schema.ResourceData, m interface{}) error { + cli := m.(*client.Client) + nodeGroups := d.Get("node_group").([]interface{}) + for _, ng := range nodeGroups { + nodeGroup := ng.(map[string]interface{}) + + securityGroupsRequest := nodeGroup["security_groups"].([]interface{}) + var securityGroups []string + for _, s := range securityGroupsRequest { + securityGroups = append(securityGroups, s.(string)) + } + if securityGroups == nil { + securityGroups = make([]string, 0) + } + autoScaleConfig := getAutoScaleConfig(nodeGroup["auto_scale_config"].([]interface{})) + upgradeConfig := getUpgradeConfig(nodeGroup["upgrade_config"].([]interface{})) + numNodes := int32(nodeGroup["num_nodes"].(int)) + imageId := nodeGroup["image_id"].(string) + updateNodeGroupRequest := vks.UpdateNodeGroupDto{ + AutoScaleConfig: autoScaleConfig, + NumNodes: numNodes, + UpgradeConfig: &upgradeConfig, + SecurityGroups: securityGroups, + ImageId: imageId, + } + requestPutOpts := vks.V1NodeGroupControllerApiV1ClustersClusterIdNodeGroupsNodeGroupIdPutOpts{ + Body: optional.NewInterface(updateNodeGroupRequest), + } + resp, httpResponse, _ := cli.VksClient.V1NodeGroupControllerApi.V1ClustersClusterIdNodeGroupsNodeGroupIdPut(context.TODO(), d.Id(), nodeGroup["node_group_id"].(string), &requestPutOpts) + if CheckErrorResponse(httpResponse) { + responseBody := GetResponseBody(httpResponse) + errResponse := fmt.Errorf("request fail with errMsg: %s", responseBody) + return errResponse + } + respJSON, _ := json.Marshal(resp) + log.Printf("-------------------------------------\n") + log.Printf("%s\n", string(respJSON)) + log.Printf("-------------------------------------\n") + + stateConf := &resource.StateChangeConf{ + Pending: UPDATING, + Target: ACTIVE, + Refresh: resourceClusterNodeGroupStateRefreshFunc(cli, d.Id(), nodeGroup["node_group_id"].(string)), + Timeout: 180 * time.Minute, + Delay: 10 * time.Second, + MinTimeout: 1 * time.Second, + } + _, err := stateConf.WaitForState() + if err != nil { + return fmt.Errorf("error waiting for update cluster node group (%s) %s", resp.Id, err) + } + } return resourceClusterRead(d, m) } @@ -503,3 +519,28 @@ func resourceNodeGroupForClusterStateRefreshFunc(cli *client.Client, clusterID s return clusterNodeGroups, status, nil } } + +func getCreateNodeGroupRequestForCluster(nodeGroup map[string]interface{}) vks.CreateNodeGroupDto { + taintsInput, ok := nodeGroup["taints"].([]interface{}) + var tains []vks.NodeGroupTaintDto + if ok { + tains = getTaints(taintsInput) + } else { + tains = nil + } + return vks.CreateNodeGroupDto{ + Name: nodeGroup["name"].(string), + NumNodes: int32(nodeGroup["initial_node_count"].(int)), + ImageId: nodeGroup["image_id"].(string), + FlavorId: nodeGroup["flavor_id"].(string), + DiskSize: int32(nodeGroup["disk_size"].(int)), + DiskType: nodeGroup["disk_type"].(string), + EnablePrivateNodes: nodeGroup["enable_private_nodes"].(bool), + SshKeyId: nodeGroup["ssh_key_id"].(string), + Labels: getLabels(nodeGroup["labels"].(map[string]interface{})), + Taints: tains, + SecurityGroups: getSecurityGroups(nodeGroup["security_groups"].([]interface{})), + UpgradeConfig: getUpgradeConfig(nodeGroup["upgrade_config"].([]interface{})), + AutoScaleConfig: getAutoScaleConfig(nodeGroup["auto_scale_config"].([]interface{})), + } +} diff --git a/resource/vks/resrouce_cluster_node_group.go b/resource/vks/resrouce_cluster_node_group.go index c8fa474..e7e303d 100644 --- a/resource/vks/resrouce_cluster_node_group.go +++ b/resource/vks/resrouce_cluster_node_group.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "fmt" + "github.com/antihax/optional" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" @@ -11,8 +12,51 @@ import ( "github.com/vngcloud/terraform-provider-vngcloud/client/vks" "log" "net/http" + "time" ) +func ResourceClusterNodeGroup() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + //MigrateState: resourceClusterNodeGroupMigrateState, + //StateUpgraders: []schema.StateUpgrader{ + // { + // Type: resourceContainerClusterResourceV1().CoreConfigSchema().ImpliedType(), + // Upgrade: ResourceContainerClusterUpgradeV1, + // Version: 1, + // }, + //}, + + Create: resourceClusterNodeGroupCreate, + Read: resourceClusterNodeGroupRead, + Update: resourceClusterNodeGroupUpdate, + Delete: resourceClusterNodeGroupDelete, + //Importer: &schema.ResourceImporter{ + // State: func(d *schema.ResourceData, m interface{}) ([]*schema.ResourceData, error) { + // idParts := strings.Split(d.Id(), ":") + // if len(idParts) != 2 || idParts[0] == "" || idParts[1] == "" { + // return nil, fmt.Errorf("Unexpected format of ID (%q), expected ProjectID:VolumeID", d.Id()) + // } + // projectID := idParts[0] + // volumeID := idParts[1] + // d.SetId(volumeID) + // d.Set("project_id", projectID) + // return []*schema.ResourceData{d}, nil + // }, + //}, + Schema: MergeSchemas( + schemaNodeGroup, + map[string]*schema.Schema{ + "cluster_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + }, + ), + } +} + var schemaNodeGroup = map[string]*schema.Schema{ "name": { Type: schema.TypeString, @@ -22,13 +66,17 @@ var schemaNodeGroup = map[string]*schema.Schema{ "num_nodes": { Type: schema.TypeInt, Optional: true, + }, + "initial_node_count": { + Type: schema.TypeInt, + Optional: true, + ForceNew: true, Default: 1, }, "auto_scale_config": { Type: schema.TypeList, MaxItems: 1, Optional: true, - Computed: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "min_size": { @@ -43,14 +91,6 @@ var schemaNodeGroup = map[string]*schema.Schema{ }, }, }, - DefaultFunc: func() (interface{}, error) { - return []interface{}{ - map[string]interface{}{ - "max_size": 10, - "min_size": 1, - }, - }, nil - }, }, "upgrade_config": { Type: schema.TypeList, @@ -90,7 +130,7 @@ var schemaNodeGroup = map[string]*schema.Schema{ Type: schema.TypeString, Optional: true, DefaultFunc: func() (interface{}, error) { - return "img-108b3a77-ab58-4000-9b3e-190d0b4b07fc", nil + return fetchByKey("image_id") }, }, "flavor_id": { @@ -98,7 +138,7 @@ var schemaNodeGroup = map[string]*schema.Schema{ Optional: true, ForceNew: true, DefaultFunc: func() (interface{}, error) { - return "flav-152e00ea-5412-44c5-868f-0b30e37e4f90", nil + return fetchByKey("flavor_id") }, }, "disk_size": { @@ -114,7 +154,7 @@ var schemaNodeGroup = map[string]*schema.Schema{ Optional: true, ForceNew: true, DefaultFunc: func() (interface{}, error) { - return "vtype-4b437071-da9c-4e1b-a2c0-839fb89e5182", nil + return fetchByKey("volume_type_id") }, }, "enable_private_nodes": { @@ -173,31 +213,6 @@ var schemaNodeGroup = map[string]*schema.Schema{ }, } -func getCreateNodeGroupReuqest(nodeGroup map[string]interface{}) vks.CreateNodeGroupDto { - taintsInput, ok := nodeGroup["taints"].([]interface{}) - var tains []vks.NodeGroupTaintDto - if ok { - tains = getTaints(taintsInput) - } else { - tains = nil - } - return vks.CreateNodeGroupDto{ - Name: nodeGroup["name"].(string), - NumNodes: int32(nodeGroup["num_nodes"].(int)), - ImageId: nodeGroup["image_id"].(string), - FlavorId: nodeGroup["flavor_id"].(string), - DiskSize: int32(nodeGroup["disk_size"].(int)), - DiskType: nodeGroup["disk_type"].(string), - EnablePrivateNodes: nodeGroup["enable_private_nodes"].(bool), - SshKeyId: nodeGroup["ssh_key_id"].(string), - Labels: getLabels(nodeGroup["labels"].(map[string]interface{})), - Taints: tains, - SecurityGroups: getSecurityGroups(nodeGroup["security_groups"].([]interface{})), - UpgradeConfig: getUpgradeConfig(nodeGroup["upgrade_config"].([]interface{})), - AutoScaleConfig: getAutoScaleConfig(nodeGroup["auto_scale_config"].([]interface{})), - } -} - func getSecurityGroups(input []interface{}) []string { securityGroups := make([]string, len(input)) @@ -277,7 +292,7 @@ func getTaints(input []interface{}) []vks.NodeGroupTaintDto { func resourceClusterNodeGroupStateRefreshFunc(cli *client.Client, clusterID string, clusterNodeGroupID string) resource.StateRefreshFunc { return func() (interface{}, string, error) { - resp, httpResponse, _ := cli.VksClient.V1NodeGroupControllerApi.V1ClustersClusterIdNodeGroupsNodeGroupIdNodesGet(context.TODO(), clusterID, clusterNodeGroupID, nil) + resp, httpResponse, _ := cli.VksClient.V1NodeGroupControllerApi.V1ClustersClusterIdNodeGroupsNodeGroupIdGet(context.TODO(), clusterID, clusterNodeGroupID, nil) if httpResponse.StatusCode != http.StatusOK { return nil, "", fmt.Errorf("Error : %s", GetResponseBody(httpResponse)) } @@ -286,6 +301,251 @@ func resourceClusterNodeGroupStateRefreshFunc(cli *client.Client, clusterID stri log.Printf("%s\n", string(respJSON)) log.Printf("-------------------------------------\n") clusterNodeGroup := resp - return clusterNodeGroup, clusterNodeGroup.Items[0].Status, nil + return clusterNodeGroup, clusterNodeGroup.Status, nil + } +} + +func resourceClusterNodeGroupRead(d *schema.ResourceData, m interface{}) error { + clusterID := d.Get("cluster_id").(string) + cli := m.(*client.Client) + resp, httpResponse, _ := cli.VksClient.V1NodeGroupControllerApi.V1ClustersClusterIdNodeGroupsNodeGroupIdGet(context.TODO(), clusterID, d.Id(), nil) + if CheckErrorResponse(httpResponse) { + responseBody := GetResponseBody(httpResponse) + errorResponse := fmt.Errorf("request fail with errMsg : %s", responseBody) + return errorResponse + } + respJSON, _ := json.Marshal(resp) + log.Printf("-------------------------------------\n") + log.Printf("%s\n", string(respJSON)) + log.Printf("-------------------------------------\n") + upgradeConfig := []interface{}{ + map[string]interface{}{ + "strategy": resp.UpgradeConfig.Strategy, + "max_surge": resp.UpgradeConfig.MaxSurge, + "max_unavailable": resp.UpgradeConfig.MaxUnavailable, + }, + } + d.Set("upgrade_config", upgradeConfig) + if resp.AutoScaleConfig != nil { + autoScaleConfig := []interface{}{ + map[string]interface{}{ + "min_size": resp.AutoScaleConfig.MinSize, + "max_size": resp.AutoScaleConfig.MaxSize, + }, + } + d.Set("auto_scale_config", autoScaleConfig) + } else { + d.Set("auto_scale_config", nil) + } + if d.Get("num_nodes") != nil && int32(d.Get("num_nodes").(int)) != 0 { + d.Set("num_nodes", resp.NumNodes) + } + d.Set("image_id", resp.ImageId) + if !checkSecurityGroupsSame(d, resp) { + d.Set("security_groups", resp.SecurityGroups) + } + return nil +} + +func resourceClusterNodeGroupCreate(d *schema.ResourceData, m interface{}) error { + + createNodeGroupRequest := getCreateNodeGroupRequest(d) + cli := m.(*client.Client) + request := vks.V1NodeGroupControllerApiV1ClustersClusterIdNodeGroupsPostOpts{ + Body: optional.NewInterface(createNodeGroupRequest), + } + resp, httpResponse, _ := cli.VksClient.V1NodeGroupControllerApi.V1ClustersClusterIdNodeGroupsPost(context.TODO(), d.Get("cluster_id").(string), &request) + + if CheckErrorResponse(httpResponse) { + responseBody := GetResponseBody(httpResponse) + errResponse := fmt.Errorf("request fail with errMsg: %s", responseBody) + return errResponse + } + respJSON, _ := json.Marshal(resp) + log.Printf("-------------------------------------\n") + log.Printf("%s\n", string(respJSON)) + log.Printf("-------------------------------------\n") + + stateConf := &resource.StateChangeConf{ + Pending: CREATING, + Target: ACTIVE, + Refresh: resourceClusterNodeGroupStateRefreshFunc(cli, d.Get("cluster_id").(string), resp.Id), + Timeout: 180 * time.Minute, + Delay: 10 * time.Second, + MinTimeout: 1 * time.Second, + } + _, err := stateConf.WaitForState() + if err != nil { + return fmt.Errorf("error waiting for create cluster node group (%s) %s", resp.Id, err) + } + //upgradeConfig := d.Get("upgrade_config").([]interface{}) + //if len(upgradeConfig) == 0 { + // clusterNodeGroupDetail, httpResponse, _ := cli.VksClient.V1NodeGroupControllerApi.V1ClustersClusterIdNodeGroupsNodeGroupIdGet(context.TODO(), clusterId, clusterNodeGroup.Id, nil) + // if httpResponse.StatusCode != http.StatusOK { + // return fmt.Errorf("Error : %s", GetResponseBody(httpResponse)) + // } + // upgradeConfig := []interface{}{ + // map[string]interface{}{ + // "strategy": clusterNodeGroupDetail.UpgradeConfig.Strategy, + // "max_surge": clusterNodeGroupDetail.UpgradeConfig.MaxSurge, + // "max_unavailable": clusterNodeGroupDetail.UpgradeConfig.MaxUnavailable, + // }, + // } + // d.Set("upgrade_config", upgradeConfig) + //} + d.SetId(resp.Id) + + return resourceClusterNodeGroupRead(d, m) +} + +func getCreateNodeGroupRequest(d *schema.ResourceData) vks.CreateNodeGroupDto { + taintsInput, ok := d.Get("taints").([]interface{}) + var tains []vks.NodeGroupTaintDto + if ok { + tains = getTaints(taintsInput) + } else { + tains = nil + } + return vks.CreateNodeGroupDto{ + Name: d.Get("name").(string), + NumNodes: int32(d.Get("initial_node_count").(int)), + ImageId: d.Get("image_id").(string), + FlavorId: d.Get("flavor_id").(string), + DiskSize: int32(d.Get("disk_size").(int)), + DiskType: d.Get("disk_type").(string), + EnablePrivateNodes: d.Get("enable_private_nodes").(bool), + SshKeyId: d.Get("ssh_key_id").(string), + Labels: getLabels(d.Get("labels").(map[string]interface{})), + Taints: tains, + SecurityGroups: getSecurityGroups(d.Get("security_groups").([]interface{})), + UpgradeConfig: getUpgradeConfig(d.Get("upgrade_config").([]interface{})), + AutoScaleConfig: getAutoScaleConfig(d.Get("auto_scale_config").([]interface{})), + } +} + +func resourceClusterNodeGroupUpdate(d *schema.ResourceData, m interface{}) error { + hasChangeSecurityGroups := false + cli := m.(*client.Client) + clusterId := d.Get("cluster_id").(string) + clusterNodeGroupId := d.Id() + if d.HasChange("security_groups") { + resp, httpResponse, _ := cli.VksClient.V1NodeGroupControllerApi.V1ClustersClusterIdNodeGroupsNodeGroupIdGet(context.TODO(), clusterId, clusterNodeGroupId, nil) + if CheckErrorResponse(httpResponse) { + responseBody := GetResponseBody(httpResponse) + errorResponse := fmt.Errorf("request fail with errMsg : %s", responseBody) + return errorResponse + } + if checkSecurityGroupsSame(d, resp) { + return resourceClusterRead(d, m) + } else { + hasChangeSecurityGroups = true + } + } + if hasChangeSecurityGroups || d.HasChange("auto_scale_config") || d.HasChange("num_nodes") || d.HasChange("upgrade_config") || d.HasChange("image_id") { + securityGroupsRequest := d.Get("security_groups").([]interface{}) + var securityGroups []string + for _, s := range securityGroupsRequest { + securityGroups = append(securityGroups, s.(string)) + } + if securityGroups == nil { + securityGroups = make([]string, 0) + } + autoScaleConfig := getAutoScaleConfig(d.Get("auto_scale_config").([]interface{})) + upgradeConfig := getUpgradeConfig(d.Get("upgrade_config").([]interface{})) + numNodes := int32(d.Get("num_nodes").(int)) + imageId := d.Get("image_id").(string) + updateNodeGroupRequest := vks.UpdateNodeGroupDto{ + AutoScaleConfig: autoScaleConfig, + NumNodes: numNodes, + UpgradeConfig: &upgradeConfig, + SecurityGroups: securityGroups, + ImageId: imageId, + } + requestPutOpts := vks.V1NodeGroupControllerApiV1ClustersClusterIdNodeGroupsNodeGroupIdPutOpts{ + Body: optional.NewInterface(updateNodeGroupRequest), + } + resp, httpResponse, _ := cli.VksClient.V1NodeGroupControllerApi.V1ClustersClusterIdNodeGroupsNodeGroupIdPut(context.TODO(), clusterId, clusterNodeGroupId, &requestPutOpts) + if CheckErrorResponse(httpResponse) { + responseBody := GetResponseBody(httpResponse) + errResponse := fmt.Errorf("request fail with errMsg: %s", responseBody) + return errResponse + } + respJSON, _ := json.Marshal(resp) + log.Printf("-------------------------------------\n") + log.Printf("%s\n", string(respJSON)) + log.Printf("-------------------------------------\n") + + stateConf := &resource.StateChangeConf{ + Pending: UPDATING, + Target: ACTIVE, + Refresh: resourceClusterNodeGroupStateRefreshFunc(cli, clusterId, d.Id()), + Timeout: 180 * time.Minute, + Delay: 10 * time.Second, + MinTimeout: 1 * time.Second, + } + _, err := stateConf.WaitForState() + if err != nil { + return fmt.Errorf("error waiting for update cluster node group (%s) %s", resp.Id, err) + } + } + return resourceClusterNodeGroupRead(d, m) +} + +func resourceClusterNodeGroupDelete(d *schema.ResourceData, m interface{}) error { + cli := m.(*client.Client) + resp, httpResponse, err := cli.VksClient.V1NodeGroupControllerApi.V1ClustersClusterIdNodeGroupsNodeGroupIdDelete(context.TODO(), d.Get("cluster_id").(string), d.Id(), nil) + if CheckErrorResponse(httpResponse) { + responseBody := GetResponseBody(httpResponse) + errorResponse := fmt.Errorf("request fail with errMsg : %s", responseBody) + return errorResponse + } + respJSON, _ := json.Marshal(resp) + log.Printf("-------------------------------------\n") + log.Printf("%s\n", string(respJSON)) + log.Printf("-------------------------------------\n") + stateConf := &resource.StateChangeConf{ + Pending: DELETING, + Target: DELETED, + Refresh: resourceClusterNodeGroupDeleteStateRefreshFunc(cli, d.Get("cluster_id").(string), d.Id()), + Timeout: d.Timeout(schema.TimeoutCreate), + Delay: 10 * time.Second, + MinTimeout: 1 * time.Second, + } + _, err = stateConf.WaitForState() + if err != nil { + return fmt.Errorf("Error waiting for instance (%s) to be created: %s", d.Id(), err) + } + d.SetId("") + return nil +} + +func resourceClusterNodeGroupDeleteStateRefreshFunc(cli *client.Client, clusterId string, clusterNodeGroupId string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + resp, httpResponse, _ := cli.VksClient.V1NodeGroupControllerApi.V1ClustersClusterIdNodeGroupsNodeGroupIdGet(context.TODO(), clusterId, clusterNodeGroupId, nil) + if httpResponse.StatusCode != http.StatusOK { + if httpResponse.StatusCode == http.StatusNotFound { + return vks.ClusterDto{Status: "DELETED"}, "DELETED", nil + } else { + return nil, "", fmt.Errorf("Error describing instance: %s", GetResponseBody(httpResponse)) + } + } + respJSON, _ := json.Marshal(resp) + log.Printf("-------------------------------------\n") + log.Printf("%s\n", string(respJSON)) + log.Printf("-------------------------------------\n") + return resp, resp.Status, nil + } +} + +func checkSecurityGroupsSame(d *schema.ResourceData, clusterNodeGroup vks.NodeGroupDetailDto) bool { + securityGroupsRequest := d.Get("security_groups").([]interface{}) + var securityGroups []string + for _, s := range securityGroupsRequest { + securityGroups = append(securityGroups, s.(string)) + } + var securityGroupsCluster []string + for _, securityGroup := range clusterNodeGroup.SecurityGroups { + securityGroupsCluster = append(securityGroupsCluster, securityGroup) } + return CheckListStringEqual(securityGroups, securityGroupsCluster) } diff --git a/resource/vks/util.go b/resource/vks/util.go index f97b9e8..fb3984e 100644 --- a/resource/vks/util.go +++ b/resource/vks/util.go @@ -1,8 +1,11 @@ package vks import ( + "encoding/json" "fmt" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "io" + "io/ioutil" "net/http" ) @@ -42,3 +45,49 @@ func CheckListStringEqual(firstList []string, secondList []string) bool { } return false } + +func MergeSchemas(a, b map[string]*schema.Schema) map[string]*schema.Schema { + merged := make(map[string]*schema.Schema) + + for k, v := range a { + merged[k] = v + } + + for k, v := range b { + merged[k] = v + } + + return merged +} + +func fetchByKey(key string) (interface{}, error) { + url := "https://zjtp0dw6ouobj.vcdn.cloud/config.json" + + resp, err := http.Get(url) + if err != nil { + return nil, fmt.Errorf("failed to make HTTP request: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("received non-200 response: %d", resp.StatusCode) + } + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, fmt.Errorf("failed to read response body: %v", err) + } + + var result map[string]interface{} + err = json.Unmarshal(body, &result) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal JSON: %v", err) + } + + response, ok := result[key].(string) + if !ok { + return nil, fmt.Errorf("%s not found in response", key) + } + + return response, nil +} From da0d9db75d04652250bcf2a7ccffaf265f3c6b74 Mon Sep 17 00:00:00 2001 From: tunm4 <8-tunm4_2@users.noreply.git.vngcloud.dev> Date: Tue, 28 May 2024 15:01:12 +0700 Subject: [PATCH 03/14] update --- docs/resources/vks_cluster.md | 1409 +++++++++++++++++++ docs/resources/vks_cluster_node_group.md | 328 +++++ resource/vks/resource_cluster.go | 40 +- resource/vks/resrouce_cluster_node_group.go | 45 +- 4 files changed, 1792 insertions(+), 30 deletions(-) create mode 100644 docs/resources/vks_cluster.md create mode 100644 docs/resources/vks_cluster_node_group.md diff --git a/docs/resources/vks_cluster.md b/docs/resources/vks_cluster.md new file mode 100644 index 0000000..d5f7140 --- /dev/null +++ b/docs/resources/vks_cluster.md @@ -0,0 +1,1409 @@ +--- +subcategory: "Kubernetes Service" +description: |- + Creates a VNGCloud Kubernetes Service (VKS) cluster. +--- + +# vngcloud_vks_cluster + +Manages a Google Kubernetes Engine (GKE) cluster. + +To get more information about GKE clusters, see: +* [The API reference](https://cloud.google.com/kubernetes-engine/docs/reference/rest/v1beta1/projects.locations.clusters) +* How-to guides + * [GKE overview](https://cloud.google.com/kubernetes-engine/docs/concepts/kubernetes-engine-overview) + * [About cluster configuration choices](https://cloud.google.com/kubernetes-engine/docs/concepts/types-of-clusters) +* Terraform guidance + * [Using GKE with Terraform](/docs/providers/google/guides/using_gke_with_terraform.html) + * [Provision a GKE Cluster (Google Cloud) Learn tutorial](https://learn.hashicorp.com/tutorials/terraform/gke?in=terraform/kubernetes&utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) + +-> On version 5.0.0+ of the provider, you must explicitly set `deletion_protection = false` +and run `terraform apply` to write the field to state in order to destroy a cluster. + +~> All arguments and attributes (including certificate outputs) will be stored in the raw state as +plaintext. [Read more about sensitive data in state](https://www.terraform.io/language/state/sensitive-data). + +## Example Usage - with a separately managed node pool (recommended) + +```hcl +resource "vngcloud_vks_cluster" "primary" { + name = "my-vks-cluster" + cidr = "172.16.0.0/16" + vpc_id = "net-xxxxxxxx-xxxx-xxxxx-xxxx-xxxxxxxxxxxx" + subnet_id = "sub-xxxxxxxx-xxxx-xxxxx-xxxx-xxxxxxxxxxxx" +} + +resource "vngcloud_vks_cluster_node_group" "primary" { + name= "my-vks-node-group" + ssh_key_id= "ssh-xxxxxxxx-xxxx-xxxxx-xxxx-xxxxxxxxxxxx" + cluster_id= vngcloud_vks_cluster.primary.id +} +``` + +~> **Note:** It is recommended that node pools be created and managed as separate resources as in the example above. +This allows node pools to be added and removed without recreating the cluster. Node pools defined directly in the +`google_container_cluster` resource cannot be removed without re-creating the cluster. + +## Example Usage - with the default node pool + +```hcl +resource "vngcloud_vks_cluster" "primary" { + name = "my-vks-cluster" + cidr = "172.16.0.0/16" + vpc_id = "net-xxxxxxxx-xxxx-xxxxx-xxxx-xxxxxxxxxxxx" + subnet_id = "sub-xxxxxxxx-xxxx-xxxxx-xxxx-xxxxxxxxxxxx" + node_group { + name= "my-vks-node-group" + ssh_key_id= "ssh-xxxxxxxx-xxxx-xxxxx-xxxx-xxxxxxxxxxxx" + } +} +``` + +## Argument Reference + +* `name` - (Required) The name of the cluster, unique within the project and + location. + +- - - + +* `location` - (Optional) The location (region or zone) in which the cluster + master will be created, as well as the default node location. If you specify a + zone (such as `us-central1-a`), the cluster will be a zonal cluster with a + single cluster master. If you specify a region (such as `us-west1`), the + cluster will be a regional cluster with multiple masters spread across zones in + the region, and with default node locations in those zones as well + +* `node_locations` - (Optional) The list of zones in which the cluster's nodes + are located. Nodes must be in the region of their regional cluster or in the + same region as their cluster's zone for zonal clusters. If this is specified for + a zonal cluster, omit the cluster's zone. + +-> A "multi-zonal" cluster is a zonal cluster with at least one additional zone +defined; in a multi-zonal cluster, the cluster master is only present in a +single zone while nodes are present in each of the primary zone and the node +locations. In contrast, in a regional cluster, cluster master nodes are present +in multiple zones in the region. For that reason, regional clusters should be +preferred. + +* `deletion_protection` - (Optional) Whether or not to allow Terraform to destroy + the cluster. Unless this field is set to false in Terraform state, a + `terraform destroy` or `terraform apply` that would delete the cluster will fail. + +* `addons_config` - (Optional) The configuration for addons supported by GKE. + Structure is [documented below](#nested_addons_config). + +* `allow_net_admin` - (Optional) Enable NET_ADMIN for the cluster. Defaults to + `false`. This field should only be enabled for Autopilot clusters (`enable_autopilot` + set to `true`). + +* `cluster_ipv4_cidr` - (Optional) The IP address range of the Kubernetes pods + in this cluster in CIDR notation (e.g. `10.96.0.0/14`). Leave blank to have one + automatically chosen or specify a `/14` block in `10.0.0.0/8`. This field will + default a new cluster to routes-based, where `ip_allocation_policy` is not defined. + +* `cluster_autoscaling` - (Optional) + Per-cluster configuration of Node Auto-Provisioning with Cluster Autoscaler to + automatically adjust the size of the cluster and create/delete node pools based + on the current needs of the cluster's workload. See the + [guide to using Node Auto-Provisioning](https://cloud.google.com/kubernetes-engine/docs/how-to/node-auto-provisioning) + for more details. Structure is [documented below](#nested_cluster_autoscaling). + +* `binary_authorization` - (Optional) Configuration options for the Binary + Authorization feature. Structure is [documented below](#nested_binary_authorization). + +* `service_external_ips_config` - (Optional) + Structure is [documented below](#nested_service_external_ips_config). + +* `mesh_certificates` - (Optional) + Structure is [documented below](#nested_mesh_encryption). + +* `database_encryption` - (Optional) + Structure is [documented below](#nested_database_encryption). + +* `description` - (Optional) Description of the cluster. + +* `default_max_pods_per_node` - (Optional) The default maximum number of pods + per node in this cluster. This doesn't work on "routes-based" clusters, clusters + that don't have IP Aliasing enabled. See the [official documentation](https://cloud.google.com/kubernetes-engine/docs/how-to/flexible-pod-cidr) + for more information. + +* `enable_kubernetes_alpha` - (Optional) Whether to enable Kubernetes Alpha features for + this cluster. Note that when this option is enabled, the cluster cannot be upgraded + and will be automatically deleted after 30 days. + +* `enable_k8s_beta_apis` - (Optional) Configuration for Kubernetes Beta APIs. + Structure is [documented below](#nested_enable_k8s_beta_apis). + +* `enable_tpu` - (Optional) Whether to enable Cloud TPU resources in this cluster. + See the [official documentation](https://cloud.google.com/tpu/docs/kubernetes-engine-setup). + +* `enable_legacy_abac` - (Optional) Whether the ABAC authorizer is enabled for this cluster. + When enabled, identities in the system, including service accounts, nodes, and controllers, + will have statically granted permissions beyond those provided by the RBAC configuration or IAM. + Defaults to `false` + +* `enable_shielded_nodes` - (Optional) Enable Shielded Nodes features on all nodes in this cluster. Defaults to `true`. + +* `enable_autopilot` - (Optional) Enable Autopilot for this cluster. Defaults to `false`. + Note that when this option is enabled, certain features of Standard GKE are not available. + See the [official documentation](https://cloud.google.com/kubernetes-engine/docs/concepts/autopilot-overview#comparison) + for available features. + +* `initial_node_count` - (Optional) The number of nodes to create in this + cluster's default node pool. In regional or multi-zonal clusters, this is the + number of nodes per zone. Must be set if `node_pool` is not set. If you're using + `google_container_node_pool` objects with no default node pool, you'll need to + set this to a value of at least `1`, alongside setting + `remove_default_node_pool` to `true`. + +* `ip_allocation_policy` - (Optional) Configuration of cluster IP allocation for + VPC-native clusters. If this block is unset during creation, it will be set by the GKE backend. + Structure is [documented below](#nested_ip_allocation_policy). + +* `networking_mode` - (Optional) Determines whether alias IPs or routes will be used for pod IPs in the cluster. + Options are `VPC_NATIVE` or `ROUTES`. `VPC_NATIVE` enables [IP aliasing](https://cloud.google.com/kubernetes-engine/docs/how-to/ip-aliases). Newly created clusters will default to `VPC_NATIVE`. + +* `logging_config` - (Optional) Logging configuration for the cluster. + Structure is [documented below](#nested_logging_config). + +* `logging_service` - (Optional) The logging service that the cluster should + write logs to. Available options include `logging.googleapis.com`(Legacy Stackdriver), + `logging.googleapis.com/kubernetes`(Stackdriver Kubernetes Engine Logging), and `none`. Defaults to `logging.googleapis.com/kubernetes` + +* `maintenance_policy` - (Optional) The maintenance policy to use for the cluster. Structure is + [documented below](#nested_maintenance_policy). + +* `master_auth` - (Optional) The authentication information for accessing the + Kubernetes master. Some values in this block are only returned by the API if + your service account has permission to get credentials for your GKE cluster. If + you see an unexpected diff unsetting your client cert, ensure you have the + `container.clusters.getCredentials` permission. + Structure is [documented below](#nested_master_auth). + +* `master_authorized_networks_config` - (Optional) The desired + configuration options for master authorized networks. Omit the + nested `cidr_blocks` attribute to disallow external access (except + the cluster node IPs, which GKE automatically whitelists). + Structure is [documented below](#nested_master_authorized_networks_config). + +* `min_master_version` - (Optional) The minimum version of the master. GKE + will auto-update the master to new versions, so this does not guarantee the + current master version--use the read-only `master_version` field to obtain that. + If unset, the cluster's version will be set by GKE to the version of the most recent + official release (which is not necessarily the latest version). Most users will find + the `google_container_engine_versions` data source useful - it indicates which versions + are available, and can be use to approximate fuzzy versions in a + Terraform-compatible way. If you intend to specify versions manually, + [the docs](https://cloud.google.com/kubernetes-engine/versioning-and-upgrades#specifying_cluster_version) + describe the various acceptable formats for this field. + +-> If you are using the `google_container_engine_versions` datasource with a regional cluster, ensure that you have provided a `location` +to the datasource. A region can have a different set of supported versions than its corresponding zones, and not all zones in a +region are guaranteed to support the same version. + +* `monitoring_config` - (Optional) Monitoring configuration for the cluster. + Structure is [documented below](#nested_monitoring_config). + +* `monitoring_service` - (Optional) The monitoring service that the cluster + should write metrics to. + Automatically send metrics from pods in the cluster to the Google Cloud Monitoring API. + VM metrics will be collected by Google Compute Engine regardless of this setting + Available options include + `monitoring.googleapis.com`(Legacy Stackdriver), `monitoring.googleapis.com/kubernetes`(Stackdriver Kubernetes Engine Monitoring), and `none`. + Defaults to `monitoring.googleapis.com/kubernetes` + +* `network` - (Optional) The name or self_link of the Google Compute Engine + network to which the cluster is connected. For Shared VPC, set this to the self link of the + shared network. + +* `network_policy` - (Optional) Configuration options for the + [NetworkPolicy](https://kubernetes.io/docs/concepts/services-networking/networkpolicies/) + feature. Structure is [documented below](#nested_network_policy). + +* `node_config` - (Optional) Parameters used in creating the default node pool. + Generally, this field should not be used at the same time as a + `google_container_node_pool` or a `node_pool` block; this configuration + manages the default node pool, which isn't recommended to be used with + Terraform. Structure is [documented below](#nested_node_config). + +* `node_pool` - (Optional) List of node pools associated with this cluster. + See [google_container_node_pool](container_node_pool.html) for schema. + **Warning:** node pools defined inside a cluster can't be changed (or added/removed) after + cluster creation without deleting and recreating the entire cluster. Unless you absolutely need the ability + to say "these are the _only_ node pools associated with this cluster", use the + [google_container_node_pool](container_node_pool.html) resource instead of this property. + +* `node_pool_auto_config` - (Optional) Node pool configs that apply to auto-provisioned node pools in + [autopilot](https://cloud.google.com/kubernetes-engine/docs/concepts/autopilot-overview#comparison) clusters and + [node auto-provisioning](https://cloud.google.com/kubernetes-engine/docs/how-to/node-auto-provisioning)-enabled clusters. Structure is [documented below](#nested_node_pool_auto_config). + +* `node_pool_defaults` - (Optional) Default NodePool settings for the entire cluster. These settings are overridden if specified on the specific NodePool object. Structure is [documented below](#nested_node_pool_defaults). + +* `node_version` - (Optional) The Kubernetes version on the nodes. Must either be unset + or set to the same value as `min_master_version` on create. Defaults to the default + version set by GKE which is not necessarily the latest version. This only affects + nodes in the default node pool. While a fuzzy version can be specified, it's + recommended that you specify explicit versions as Terraform will see spurious diffs + when fuzzy versions are used. See the `google_container_engine_versions` data source's + `version_prefix` field to approximate fuzzy versions in a Terraform-compatible way. + To update nodes in other node pools, use the `version` attribute on the node pool. + +* `notification_config` - (Optional) Configuration for the [cluster upgrade notifications](https://cloud.google.com/kubernetes-engine/docs/how-to/cluster-upgrade-notifications) feature. Structure is [documented below](#nested_notification_config). + +* `confidential_nodes` - Configuration for [Confidential Nodes](https://cloud.google.com/kubernetes-engine/docs/how-to/confidential-gke-nodes) feature. Structure is documented below [documented below](#nested_confidential_nodes). + +* `pod_security_policy_config` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) Configuration for the + [PodSecurityPolicy](https://cloud.google.com/kubernetes-engine/docs/how-to/pod-security-policies) feature. + Structure is [documented below](#nested_pod_security_policy_config). + +* `authenticator_groups_config` - (Optional) Configuration for the + [Google Groups for GKE](https://cloud.google.com/kubernetes-engine/docs/how-to/role-based-access-control#groups-setup-gsuite) feature. + Structure is [documented below](#nested_authenticator_groups_config). + +* `private_cluster_config` - (Optional) Configuration for [private clusters](https://cloud.google.com/kubernetes-engine/docs/how-to/private-clusters), + clusters with private nodes. Structure is [documented below](#nested_private_cluster_config). + +* `cluster_telemetry` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) Configuration for + [ClusterTelemetry](https://cloud.google.com/monitoring/kubernetes-engine/installing#controlling_the_collection_of_application_logs) feature, + Structure is [documented below](#nested_cluster_telemetry). + +* `project` - (Optional) The ID of the project in which the resource belongs. If it + is not provided, the provider project is used. + +* `release_channel` - (Optional) + Configuration options for the [Release channel](https://cloud.google.com/kubernetes-engine/docs/concepts/release-channels) + feature, which provide more control over automatic upgrades of your GKE clusters. + When updating this field, GKE imposes specific version requirements. See + [Selecting a new release channel](https://cloud.google.com/kubernetes-engine/docs/concepts/release-channels#selecting_a_new_release_channel) + for more details; the `google_container_engine_versions` datasource can provide + the default version for a channel. Note that removing the `release_channel` + field from your config will cause Terraform to stop managing your cluster's + release channel, but will not unenroll it. Instead, use the `"UNSPECIFIED"` + channel. Structure is [documented below](#nested_release_channel). + +* `remove_default_node_pool` - (Optional) If `true`, deletes the default node + pool upon cluster creation. If you're using `google_container_node_pool` + resources with no default node pool, this should be set to `true`, alongside + setting `initial_node_count` to at least `1`. + +* `resource_labels` - (Optional) The GCE resource labels (a map of key/value pairs) to be applied to the cluster. + +* `cost_management_config` - (Optional) Configuration for the + [Cost Allocation](https://cloud.google.com/kubernetes-engine/docs/how-to/cost-allocations) feature. + Structure is [documented below](#nested_cost_management_config). + +* `resource_usage_export_config` - (Optional) Configuration for the + [ResourceUsageExportConfig](https://cloud.google.com/kubernetes-engine/docs/how-to/cluster-usage-metering) feature. + Structure is [documented below](#nested_resource_usage_export_config). + +* `subnetwork` - (Optional) The name or self_link of the Google Compute Engine + subnetwork in which the cluster's instances are launched. + +* `vertical_pod_autoscaling` - (Optional) + Vertical Pod Autoscaling automatically adjusts the resources of pods controlled by it. + Structure is [documented below](#nested_vertical_pod_autoscaling). + +* `workload_identity_config` - (Optional) + Workload Identity allows Kubernetes service accounts to act as a user-managed + [Google IAM Service Account](https://cloud.google.com/iam/docs/service-accounts#user-managed_service_accounts). + Structure is [documented below](#nested_workload_identity_config). + +* `identity_service_config` - (Optional). Structure is [documented below](#nested_identity_service_config). + +* `enable_intranode_visibility` - (Optional) + Whether Intra-node visibility is enabled for this cluster. This makes same node pod to pod traffic visible for VPC network. + +* `enable_l4_ilb_subsetting` - (Optional) + Whether L4ILB Subsetting is enabled for this cluster. + +* `enable_multi_networking` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) + Whether multi-networking is enabled for this cluster. + +* `enable_fqdn_network_policy` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) + Whether FQDN Network Policy is enabled on this cluster. Users who enable this feature for existing Standard clusters must restart the GKE Dataplane V2 `anetd` DaemonSet after enabling it. See the [Enable FQDN Network Policy in an existing cluster](https://cloud.google.com/kubernetes-engine/docs/how-to/fqdn-network-policies#enable_fqdn_network_policy_in_an_existing_cluster) for more information. + +* `private_ipv6_google_access` - (Optional) + The desired state of IPv6 connectivity to Google Services. By default, no private IPv6 access to or from Google Services (all access will be via IPv4). + +* `datapath_provider` - (Optional) + The desired datapath provider for this cluster. This is set to `LEGACY_DATAPATH` by default, which uses the IPTables-based kube-proxy implementation. Set to `ADVANCED_DATAPATH` to enable Dataplane v2. + +* `enable_cilium_clusterwide_network_policy` - (Optional) + Whether CiliumClusterWideNetworkPolicy is enabled on this cluster. Defaults to false. + +* `default_snat_status` - (Optional) + [GKE SNAT](https://cloud.google.com/kubernetes-engine/docs/how-to/ip-masquerade-agent#how_ipmasq_works) DefaultSnatStatus contains the desired state of whether default sNAT should be disabled on the cluster, [API doc](https://cloud.google.com/kubernetes-engine/docs/reference/rest/v1beta1/projects.locations.clusters#networkconfig). Structure is [documented below](#nested_default_snat_status) + +* `dns_config` - (Optional) + Configuration for [Using Cloud DNS for GKE](https://cloud.google.com/kubernetes-engine/docs/how-to/cloud-dns). Structure is [documented below](#nested_dns_config). + +* `gateway_api_config` - (Optional) + Configuration for [GKE Gateway API controller](https://cloud.google.com/kubernetes-engine/docs/concepts/gateway-api). Structure is [documented below](#nested_gateway_api_config). + +* `protect_config` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) + Enable/Disable Protect API features for the cluster. Structure is [documented below](#nested_protect_config). + +* `security_posture_config` - (Optional) + Enable/Disable Security Posture API features for the cluster. Structure is [documented below](#nested_security_posture_config). + +* `fleet` - (Optional) + Fleet configuration for the cluster. Structure is [documented below](#nested_fleet). + +* `workload_alts_config` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) + Configuration for [direct-path (via ALTS) with workload identity.](https://cloud.google.com/kubernetes-engine/docs/reference/rest/v1beta1/projects.locations.clusters#workloadaltsconfig). Structure is [documented below](#nested_workload_alts_config). + +The `default_snat_status` block supports + +* `disabled` - (Required) Whether the cluster disables default in-node sNAT rules. In-node sNAT rules will be disabled when defaultSnatStatus is disabled.When disabled is set to false, default IP masquerade rules will be applied to the nodes to prevent sNAT on cluster internal traffic + +The `cluster_telemetry` block supports +* `type` - Telemetry integration for the cluster. Supported values (`ENABLED, DISABLED, SYSTEM_ONLY`); + `SYSTEM_ONLY` (Only system components are monitored and logged) is only available in GKE versions 1.15 and later. + +The `addons_config` block supports: + +* `horizontal_pod_autoscaling` - (Optional) The status of the Horizontal Pod Autoscaling + addon, which increases or decreases the number of replica pods a replication controller + has based on the resource usage of the existing pods. + It is enabled by default; + set `disabled = true` to disable. + +* `http_load_balancing` - (Optional) The status of the HTTP (L7) load balancing + controller addon, which makes it easy to set up HTTP load balancers for services in a + cluster. It is enabled by default; set `disabled = true` to disable. + +* `network_policy_config` - (Optional) Whether we should enable the network policy addon + for the master. This must be enabled in order to enable network policy for the nodes. + To enable this, you must also define a [`network_policy`](#network_policy) block, + otherwise nothing will happen. + It can only be disabled if the nodes already do not have network policies enabled. + Defaults to disabled; set `disabled = false` to enable. + +* `gcp_filestore_csi_driver_config` - (Optional) The status of the Filestore CSI driver addon, + which allows the usage of filestore instance as volumes. + It is disabled by default; set `enabled = true` to enable. + +* `gcs_fuse_csi_driver_config` - (Optional) The status of the GCSFuse CSI driver addon, + which allows the usage of a gcs bucket as volumes. + It is disabled by default for Standard clusters; set `enabled = true` to enable. + It is enabled by default for Autopilot clusters with version 1.24 or later; set `enabled = true` to enable it explicitly. + See [Enable the Cloud Storage FUSE CSI driver](https://cloud.google.com/kubernetes-engine/docs/how-to/persistent-volumes/cloud-storage-fuse-csi-driver#enable) for more information. + +* `cloudrun_config` - (Optional). Structure is [documented below](#nested_cloudrun_config). + +* `istio_config` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)). + Structure is [documented below](#nested_istio_config). + +* `dns_cache_config` - (Optional). + The status of the NodeLocal DNSCache addon. It is disabled by default. + Set `enabled = true` to enable. + + **Enabling/Disabling NodeLocal DNSCache in an existing cluster is a disruptive operation. + All cluster nodes running GKE 1.15 and higher are recreated.** + +* `gce_persistent_disk_csi_driver_config` - (Optional). + Whether this cluster should enable the Google Compute Engine Persistent Disk Container Storage Interface (CSI) Driver. Set `enabled = true` to enable. + + **Note:** The Compute Engine persistent disk CSI Driver is enabled by default on newly created clusters for the following versions: Linux clusters: GKE version 1.18.10-gke.2100 or later, or 1.19.3-gke.2100 or later. + +* `gke_backup_agent_config` - (Optional). + The status of the Backup for GKE agent addon. It is disabled by default; Set `enabled = true` to enable. + +* `kalm_config` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)). + Configuration for the KALM addon, which manages the lifecycle of k8s. It is disabled by default; Set `enabled = true` to enable. + +* `config_connector_config` - (Optional). + The status of the ConfigConnector addon. It is disabled by default; Set `enabled = true` to enable. + +* `stateful_ha_config` - (Optional). + The status of the Stateful HA addon, which provides automatic configurable failover for stateful applications. + It is disabled by default for Standard clusters. Set `enabled = true` to enable. + +This example `addons_config` disables two addons: + +```hcl +addons_config { + http_load_balancing { + disabled = true + } + + horizontal_pod_autoscaling { + disabled = true + } +} +``` +The `binary_authorization` block supports: + +* `enabled` - (DEPRECATED) Enable Binary Authorization for this cluster. Deprecated in favor of `evaluation_mode`. + +* `evaluation_mode` - (Optional) Mode of operation for Binary Authorization policy evaluation. Valid values are `DISABLED` + and `PROJECT_SINGLETON_POLICY_ENFORCE`. + +The `service_external_ips_config` block supports: + +* `enabled` - (Required) Controls whether external ips specified by a service will be allowed. It is enabled by default. + +The `mesh_certificates` block supports: + +* `enable_certificates` - (Required) Controls the issuance of workload mTLS certificates. It is enabled by default. Workload Identity is required, see [workload_config](#nested_workload_identity_config). + +The `database_encryption` block supports: + +* `state` - (Required) `ENCRYPTED` or `DECRYPTED` + +* `key_name` - (Required) the key to use to encrypt/decrypt secrets. See the [DatabaseEncryption definition](https://cloud.google.com/kubernetes-engine/docs/reference/rest/v1beta1/projects.locations.clusters#Cluster.DatabaseEncryption) for more information. + +The `enable_k8s_beta_apis` block supports: + +* `enabled_apis` - (Required) Enabled Kubernetes Beta APIs. To list a Beta API resource, use the representation {group}/{version}/{resource}. The version must be a Beta version. Note that you cannot disable beta APIs that are already enabled on a cluster without recreating it. See the [Configure beta APIs](https://cloud.google.com/kubernetes-engine/docs/how-to/use-beta-apis#configure-beta-apis) for more information. + +The `cloudrun_config` block supports: + +* `disabled` - (Optional) The status of the CloudRun addon. It is disabled by default. Set `disabled=false` to enable. + +* `load_balancer_type` - (Optional) The load balancer type of CloudRun ingress service. It is external load balancer by default. + Set `load_balancer_type=LOAD_BALANCER_TYPE_INTERNAL` to configure it as internal load balancer. + +The `identity_service_config` block supports: + +* `enabled` - (Optional) Whether to enable the Identity Service component. It is disabled by default. Set `enabled=true` to enable. + +The `istio_config` block supports: + +* `disabled` - (Optional) The status of the Istio addon, which makes it easy to set up Istio for services in a + cluster. It is disabled by default. Set `disabled = false` to enable. + +* `auth` - (Optional) The authentication type between services in Istio. Available options include `AUTH_MUTUAL_TLS`. + +The `cluster_autoscaling` block supports: + +* `enabled` - (Optional) Whether node auto-provisioning is enabled. Must be supplied for GKE Standard clusters, `true` is implied + for autopilot clusters. Resource limits for `cpu` and `memory` must be defined to enable node auto-provisioning for GKE Standard. + +* `resource_limits` - (Optional) Global constraints for machine resources in the + cluster. Configuring the `cpu` and `memory` types is required if node + auto-provisioning is enabled. These limits will apply to node pool autoscaling + in addition to node auto-provisioning. Structure is [documented below](#nested_resource_limits). + +* `auto_provisioning_defaults` - (Optional) Contains defaults for a node pool created by NAP. A subset of fields also apply to + GKE Autopilot clusters. + Structure is [documented below](#nested_auto_provisioning_defaults). + +* `autoscaling_profile` - (Optional) Configuration + options for the [Autoscaling profile](https://cloud.google.com/kubernetes-engine/docs/concepts/cluster-autoscaler#autoscaling_profiles) + feature, which lets you choose whether the cluster autoscaler should optimize for resource utilization or resource availability + when deciding to remove nodes from a cluster. Can be `BALANCED` or `OPTIMIZE_UTILIZATION`. Defaults to `BALANCED`. + +The `resource_limits` block supports: + +* `resource_type` - (Required) The type of the resource. For example, `cpu` and + `memory`. See the [guide to using Node Auto-Provisioning](https://cloud.google.com/kubernetes-engine/docs/how-to/node-auto-provisioning) + for a list of types. + +* `minimum` - (Optional) Minimum amount of the resource in the cluster. + +* `maximum` - (Optional) Maximum amount of the resource in the cluster. + +The `auto_provisioning_defaults` block supports: + +* `min_cpu_platform` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) + Minimum CPU platform to be used for NAP created node pools. The instance may be scheduled on the + specified or newer CPU platform. Applicable values are the friendly names of CPU platforms, such + as "Intel Haswell" or "Intel Sandy Bridge". + +* `oauth_scopes` - (Optional) Scopes that are used by NAP and GKE Autopilot when creating node pools. Use the "https://www.googleapis.com/auth/cloud-platform" scope to grant access to all APIs. It is recommended that you set `service_account` to a non-default service account and grant IAM roles to that service account for only the resources that it needs. + +-> `monitoring.write` is always enabled regardless of user input. `monitoring` and `logging.write` may also be enabled depending on the values for `monitoring_service` and `logging_service`. + +* `service_account` - (Optional) The Google Cloud Platform Service Account to be used by the node VMs created by GKE Autopilot or NAP. + +* `boot_disk_kms_key` - (Optional) The Customer Managed Encryption Key used to encrypt the boot disk attached to each node in the node pool. This should be of the form projects/[KEY_PROJECT_ID]/locations/[LOCATION]/keyRings/[RING_NAME]/cryptoKeys/[KEY_NAME]. For more information about protecting resources with Cloud KMS Keys please see: https://cloud.google.com/compute/docs/disks/customer-managed-encryption + +* `disk_size` - (Optional) Size of the disk attached to each node, specified in GB. The smallest allowed disk size is 10GB. Defaults to `100` + +* `disk_type` - (Optional) Type of the disk attached to each node (e.g. 'pd-standard', 'pd-ssd' or 'pd-balanced'). Defaults to `pd-standard` + +* `image_type` - (Optional) The default image type used by NAP once a new node pool is being created. Please note that according to the [official documentation](https://cloud.google.com/kubernetes-engine/docs/how-to/node-auto-provisioning#default-image-type) the value must be one of the [COS_CONTAINERD, COS, UBUNTU_CONTAINERD, UBUNTU]. __NOTE__ : COS AND UBUNTU are deprecated as of `GKE 1.24` + +* `shielded_instance_config` - (Optional) Shielded Instance options. Structure is [documented below](#nested_shielded_instance_config). + +* `management` - (Optional) NodeManagement configuration for this NodePool. Structure is [documented below](#nested_management). + +The `management` block supports: + +* `auto_upgrade` - (Optional) Specifies whether node auto-upgrade is enabled for the node pool. If enabled, node auto-upgrade helps keep the nodes in your node pool up to date with the latest release version of Kubernetes. + +* `auto_repair` - (Optional) Specifies whether the node auto-repair is enabled for the node pool. If enabled, the nodes in this node pool will be monitored and, if they fail health checks too many times, an automatic repair action will be triggered. + +This block also contains several computed attributes, documented below. + +* `upgrade_settings` - (Optional) Specifies the upgrade settings for NAP created node pools. Structure is [documented below](#nested_upgrade_settings). + +The `upgrade_settings` block supports: + +* `strategy` - (Optional) Strategy used for node pool update. Strategy can only be one of BLUE_GREEN or SURGE. The default is value is SURGE. + +* `max_surge` - (Optional) The maximum number of nodes that can be created beyond the current size of the node pool during the upgrade process. To be used when strategy is set to SURGE. Default is 0. + +* `max_unavailable` - (Optional) The maximum number of nodes that can be simultaneously unavailable during the upgrade process. To be used when strategy is set to SURGE. Default is 0. + +* `blue_green_settings` - (Optional) Settings for blue-green upgrade strategy. To be specified when strategy is set to BLUE_GREEN. Structure is [documented below](#nested_blue_green_settings). + +The `blue_green_settings` block supports: + +* `node_pool_soak_duration` - (Optional) Time needed after draining entire blue pool. After this period, blue pool will be cleaned up. A duration in seconds with up to nine fractional digits, ending with 's'. Example: "3.5s". + +* `standard_rollout_policy`: (Optional) Standard policy for the blue-green upgrade. To be specified when strategy is set to BLUE_GREEN. Structure is [documented below](#nested_standard_rollout_policy). + +The `standard_rollout_policy` block supports: + +* `batch_percentage`: (Optional) Percentage of the bool pool nodes to drain in a batch. The range of this field should be (0.0, 1.0). Only one of the batch_percentage or batch_node_count can be specified. + +* `batch_node_count` - (Optional) Number of blue nodes to drain in a batch. Only one of the batch_percentage or batch_node_count can be specified. + +* `batch_soak_duration` - (Optional) Soak time after each batch gets drained. A duration in seconds with up to nine fractional digits, ending with 's'. Example: "3.5s".`. + +The `authenticator_groups_config` block supports: + +* `security_group` - (Required) The name of the RBAC security group for use with Google security groups in Kubernetes RBAC. Group name must be in format `gke-security-groups@yourdomain.com`. + +The `logging_config` block supports: + +* `enable_components` - (Required) The GKE components exposing logs. Supported values include: + `SYSTEM_COMPONENTS`, `APISERVER`, `CONTROLLER_MANAGER`, `SCHEDULER`, and `WORKLOADS`. + +The `monitoring_config` block supports: + +* `enable_components` - (Optional) The GKE components exposing metrics. Supported values include: `SYSTEM_COMPONENTS`, `APISERVER`, `SCHEDULER`, `CONTROLLER_MANAGER`, `STORAGE`, `HPA`, `POD`, `DAEMONSET`, `DEPLOYMENT`, `STATEFULSET`, `KUBELET` and `CADVISOR`. In beta provider, `WORKLOADS` is supported on top of those 12 values. (`WORKLOADS` is deprecated and removed in GKE 1.24.) `KUBELET` and `CADVISOR` are only supported in GKE 1.29.3-gke.1093000 and above. + +* `managed_prometheus` - (Optional) Configuration for Managed Service for Prometheus. Structure is [documented below](#nested_managed_prometheus). + +* `advanced_datapath_observability_config` - (Optional) Configuration for Advanced Datapath Monitoring. Structure is [documented below](#nested_advanced_datapath_observability_config). + +The `managed_prometheus` block supports: + +* `enabled` - (Required) Whether or not the managed collection is enabled. + +The `advanced_datapath_observability_config` block supports: + +* `enable_metrics` - (Required) Whether or not to enable advanced datapath metrics. +* `enable_relay` - (Optional) Whether or not Relay is enabled. +* `relay_mode` - (Optional) Mode used to make Relay available. + +The `maintenance_policy` block supports: +* `daily_maintenance_window` - (Optional) structure documented below. +* `recurring_window` - (Optional) structure documented below +* `maintenance_exclusion` - (Optional) structure documented below + +In beta, one or the other of `recurring_window` and `daily_maintenance_window` is required if a `maintenance_policy` block is supplied. + +* `daily_maintenance_window` - Time window specified for daily maintenance operations. + Specify `start_time` in [RFC3339](https://www.ietf.org/rfc/rfc3339.txt) format "HH:MM”, + where HH : \[00-23\] and MM : \[00-59\] GMT. For example: + +Examples: +```hcl +maintenance_policy { + daily_maintenance_window { + start_time = "03:00" + } +} +``` + +* `recurring_window` - Time window for recurring maintenance operations. + +Specify `start_time` and `end_time` in [RFC3339](https://www.ietf.org/rfc/rfc3339.txt) "Zulu" date format. The start time's date is +the initial date that the window starts, and the end time is used for calculating duration. Specify `recurrence` in +[RFC5545](https://tools.ietf.org/html/rfc5545#section-3.8.5.3) RRULE format, to specify when this recurs. +Note that GKE may accept other formats, but will return values in UTC, causing a permanent diff. + +Examples: +``` +maintenance_policy { + recurring_window { + start_time = "2019-08-01T02:00:00Z" + end_time = "2019-08-01T06:00:00Z" + recurrence = "FREQ=DAILY" + } +} +``` + +``` +maintenance_policy { + recurring_window { + start_time = "2019-01-01T09:00:00Z" + end_time = "2019-01-01T17:00:00Z" + recurrence = "FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR" + } +} +``` + +* `maintenance_exclusion` - Exceptions to maintenance window. Non-emergency maintenance should not occur in these windows. A cluster can have up to 20 maintenance exclusions at a time [Maintenance Window and Exclusions](https://cloud.google.com/kubernetes-engine/docs/concepts/maintenance-windows-and-exclusions) + +The `maintenance_exclusion` block supports: +* `exclusion_options` - (Optional) MaintenanceExclusionOptions provides maintenance exclusion related options. + + +The `exclusion_options` block supports: +* `scope` - (Required) The scope of automatic upgrades to restrict in the exclusion window. One of: **NO_UPGRADES | NO_MINOR_UPGRADES | NO_MINOR_OR_NODE_UPGRADES** + +Specify `start_time` and `end_time` in [RFC3339](https://www.ietf.org/rfc/rfc3339.txt) "Zulu" date format. The start time's date is +the initial date that the window starts, and the end time is used for calculating duration.Specify `recurrence` in +[RFC5545](https://tools.ietf.org/html/rfc5545#section-3.8.5.3) RRULE format, to specify when this recurs. +Note that GKE may accept other formats, but will return values in UTC, causing a permanent diff. + +Examples: + +``` +maintenance_policy { + recurring_window { + start_time = "2019-01-01T00:00:00Z" + end_time = "2019-01-02T00:00:00Z" + recurrence = "FREQ=DAILY" + } + maintenance_exclusion{ + exclusion_name = "batch job" + start_time = "2019-01-01T00:00:00Z" + end_time = "2019-01-02T00:00:00Z" + exclusion_options { + scope = "NO_UPGRADES" + } + } + maintenance_exclusion{ + exclusion_name = "holiday data load" + start_time = "2019-05-01T00:00:00Z" + end_time = "2019-05-02T00:00:00Z" + exclusion_options { + scope = "NO_MINOR_UPGRADES" + } + } +} +``` + +The `ip_allocation_policy` block supports: + +* `cluster_secondary_range_name` - (Optional) The name of the existing secondary + range in the cluster's subnetwork to use for pod IP addresses. Alternatively, + `cluster_ipv4_cidr_block` can be used to automatically create a GKE-managed one. + +* `services_secondary_range_name` - (Optional) The name of the existing + secondary range in the cluster's subnetwork to use for service `ClusterIP`s. + Alternatively, `services_ipv4_cidr_block` can be used to automatically create a + GKE-managed one. + +* `cluster_ipv4_cidr_block` - (Optional) The IP address range for the cluster pod IPs. + Set to blank to have a range chosen with the default size. Set to /netmask (e.g. /14) + to have a range chosen with a specific netmask. Set to a CIDR notation (e.g. 10.96.0.0/14) + from the RFC-1918 private networks (e.g. 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) to + pick a specific range to use. + +* `services_ipv4_cidr_block` - (Optional) The IP address range of the services IPs in this cluster. + Set to blank to have a range chosen with the default size. Set to /netmask (e.g. /14) + to have a range chosen with a specific netmask. Set to a CIDR notation (e.g. 10.96.0.0/14) + from the RFC-1918 private networks (e.g. 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) to + pick a specific range to use. + +* `stack_type` - (Optional) The IP Stack Type of the cluster. + Default value is `IPV4`. + Possible values are `IPV4` and `IPV4_IPV6`. + +* `additional_pod_ranges_config` - (Optional) The configuration for additional pod secondary ranges at + the cluster level. Used for Autopilot clusters and Standard clusters with which control of the + secondary Pod IP address assignment to node pools isn't needed. Structure is [documented below](#nested_additional_pod_ranges_config). + + +The `additional_pod_ranges_config` block supports: + +* `pod_range_names` - (Required) The names of the Pod ranges to add to the cluster. + + +The `master_auth` block supports: + +* `client_certificate_config` - (Required) Whether client certificate authorization is enabled for this cluster. For example: + +```hcl +master_auth { + client_certificate_config { + issue_client_certificate = false + } +} +``` + +This block also contains several computed attributes, documented below. + +The `master_authorized_networks_config` block supports: + +* `cidr_blocks` - (Optional) External networks that can access the + Kubernetes cluster master through HTTPS. + +* `gcp_public_cidrs_access_enabled` - (Optional) Whether Kubernetes master is + accessible via Google Compute Engine Public IPs. + +The `master_authorized_networks_config.cidr_blocks` block supports: + +* `cidr_block` - (Optional) External network that can access Kubernetes master through HTTPS. + Must be specified in CIDR notation. + +* `display_name` - (Optional) Field for users to identify CIDR blocks. + +The `network_policy` block supports: + +* `provider` - (Optional) The selected network policy provider. Defaults to PROVIDER_UNSPECIFIED. + +* `enabled` - (Required) Whether network policy is enabled on the cluster. + +The `node_config` block supports: + +* `disk_size_gb` - (Optional) Size of the disk attached to each node, specified + in GB. The smallest allowed disk size is 10GB. Defaults to 100GB. + +* `disk_type` - (Optional) Type of the disk attached to each node + (e.g. 'pd-standard', 'pd-balanced' or 'pd-ssd'). If unspecified, the default disk type is 'pd-standard' + +* `enable_confidential_storage` - (Optional) Enabling Confidential Storage will create boot disk with confidential mode. It is disabled by default. + +* `ephemeral_storage_config` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) Parameters for the ephemeral storage filesystem. If unspecified, ephemeral storage is backed by the boot disk. Structure is [documented below](#nested_ephemeral_storage_config). + +```hcl +ephemeral_storage_config { + local_ssd_count = 2 +} +``` +* `ephemeral_storage_local_ssd_config` - (Optional) Parameters for the ephemeral storage filesystem. If unspecified, ephemeral storage is backed by the boot disk. Structure is [documented below](#nested_ephemeral_storage_local_ssd_config). + +```hcl +ephemeral_storage_local_ssd_config { + local_ssd_count = 2 +} +``` +* `fast_socket` - (Optional) Parameters for the NCCL Fast Socket feature. If unspecified, NCCL Fast Socket will not be enabled on the node pool. + Node Pool must enable gvnic. + GKE version 1.25.2-gke.1700 or later. + Structure is [documented below](#nested_fast_socket). + +* `local_nvme_ssd_block_config` - (Optional) Parameters for the local NVMe SSDs. Structure is [documented below](#nested_local_nvme_ssd_block_config). + +* `logging_variant` (Optional) Parameter for specifying the type of logging agent used in a node pool. This will override any [cluster-wide default value](#nested_node_pool_defaults). Valid values include DEFAULT and MAX_THROUGHPUT. See [Increasing logging agent throughput](https://cloud.google.com/stackdriver/docs/solutions/gke/managing-logs#throughput) for more information. + +* `secondary_boot_disks` - (Optional) Parameters for secondary boot disks to preload container images and data on new nodes. Structure is [documented below](#nested_secondary_boot_disks). `gcfs_config` must be `enabled=true` for this feature to work. `min_master_version` must also be set to use GKE 1.28.3-gke.106700 or later versions. + +* `gcfs_config` - (Optional) Parameters for the Google Container Filesystem (GCFS). + If unspecified, GCFS will not be enabled on the node pool. When enabling this feature you must specify `image_type = "COS_CONTAINERD"` and `node_version` from GKE versions 1.19 or later to use it. + For GKE versions 1.19, 1.20, and 1.21, the recommended minimum `node_version` would be 1.19.15-gke.1300, 1.20.11-gke.1300, and 1.21.5-gke.1300 respectively. + A `machine_type` that has more than 16 GiB of memory is also recommended. + GCFS must be enabled in order to use [image streaming](https://cloud.google.com/kubernetes-engine/docs/how-to/image-streaming). + Structure is [documented below](#nested_gcfs_config). + +```hcl +gcfs_config { + enabled = true +} +``` + + +* `gvnic` - (Optional) Google Virtual NIC (gVNIC) is a virtual network interface. + Installing the gVNIC driver allows for more efficient traffic transmission across the Google network infrastructure. + gVNIC is an alternative to the virtIO-based ethernet driver. GKE nodes must use a Container-Optimized OS node image. + GKE node version 1.15.11-gke.15 or later + Structure is [documented below](#nested_gvnic). + + +```hcl +gvnic { + enabled = true +} +``` + +* `guest_accelerator` - (Optional) List of the type and count of accelerator cards attached to the instance. + Structure [documented below](#nested_guest_accelerator). + To support removal of guest_accelerators in Terraform 0.12 this field is an + [Attribute as Block](/docs/configuration/attr-as-blocks.html) + +* `image_type` - (Optional) The image type to use for this node. Note that changing the image type + will delete and recreate all nodes in the node pool. + +* `labels` - (Optional) The Kubernetes labels (key/value pairs) to be applied to each node. The kubernetes.io/ and k8s.io/ prefixes are + reserved by Kubernetes Core components and cannot be specified. + +* `resource_labels` - (Optional) The GCP labels (key/value pairs) to be applied to each node. Refer [here](https://cloud.google.com/kubernetes-engine/docs/how-to/creating-managing-labels) + for how these labels are applied to clusters, node pools and nodes. + +* `local_ssd_count` - (Optional) The amount of local SSD disks that will be + attached to each cluster node. Defaults to 0. + +* `machine_type` - (Optional) The name of a Google Compute Engine machine type. + Defaults to `e2-medium`. To create a custom machine type, value should be set as specified + [here](https://cloud.google.com/compute/docs/reference/latest/instances#machineType). + +* `metadata` - (Optional) The metadata key/value pairs assigned to instances in + the cluster. From GKE `1.12` onwards, `disable-legacy-endpoints` is set to + `true` by the API; if `metadata` is set but that default value is not + included, Terraform will attempt to unset the value. To avoid this, set the + value in your config. + +* `min_cpu_platform` - (Optional) Minimum CPU platform to be used by this instance. + The instance may be scheduled on the specified or newer CPU platform. Applicable + values are the friendly names of CPU platforms, such as `Intel Haswell`. See the + [official documentation](https://cloud.google.com/compute/docs/instances/specify-min-cpu-platform) + for more information. + +* `oauth_scopes` - (Optional) The set of Google API scopes to be made available + on all of the node VMs under the "default" service account. + Use the "https://www.googleapis.com/auth/cloud-platform" scope to grant access to all APIs. It is recommended that you set `service_account` to a non-default service account and grant IAM roles to that service account for only the resources that it needs. + + See the [official documentation](https://cloud.google.com/kubernetes-engine/docs/how-to/access-scopes) for information on migrating off of legacy access scopes. + +* `preemptible` - (Optional) A boolean that represents whether or not the underlying node VMs + are preemptible. See the [official documentation](https://cloud.google.com/container-engine/docs/preemptible-vm) + for more information. Defaults to false. + +* `reservation_affinity` (Optional) The configuration of the desired reservation which instances could take capacity from. Structure is [documented below](#nested_reservation_affinity). + +* `spot` - (Optional) A boolean that represents whether the underlying node VMs are spot. + See the [official documentation](https://cloud.google.com/kubernetes-engine/docs/concepts/spot-vms) + for more information. Defaults to false. + +* `sandbox_config` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) [GKE Sandbox](https://cloud.google.com/kubernetes-engine/docs/how-to/sandbox-pods) configuration. When enabling this feature you must specify `image_type = "COS_CONTAINERD"` and `node_version = "1.12.7-gke.17"` or later to use it. + Structure is [documented below](#nested_sandbox_config). + +* `boot_disk_kms_key` - (Optional) The Customer Managed Encryption Key used to encrypt the boot disk attached to each node in the node pool. This should be of the form projects/[KEY_PROJECT_ID]/locations/[LOCATION]/keyRings/[RING_NAME]/cryptoKeys/[KEY_NAME]. For more information about protecting resources with Cloud KMS Keys please see: https://cloud.google.com/compute/docs/disks/customer-managed-encryption + +* `service_account` - (Optional) The service account to be used by the Node VMs. + If not specified, the "default" service account is used. + +* `shielded_instance_config` - (Optional) Shielded Instance options. Structure is [documented below](#nested_shielded_instance_config). + +* `tags` - (Optional) The list of instance tags applied to all nodes. Tags are used to identify + valid sources or targets for network firewalls. + +* `resource_manager_tags` - (Optional) A map of resource manager tag keys and values to be attached to the nodes for managing Compute Engine firewalls using Network Firewall Policies. Tags must be according to specifications found [here](https://cloud.google.com/vpc/docs/tags-firewalls-overview#specifications). A maximum of 5 tag key-value pairs can be specified. Existing tags will be replaced with new values. Tags must be in one of the following formats ([KEY]=[VALUE]) 1. `tagKeys/{tag_key_id}=tagValues/{tag_value_id}` 2. `{org_id}/{tag_key_name}={tag_value_name}` 3. `{project_id}/{tag_key_name}={tag_value_name}`. + +* `taint` - (Optional) A list of + [Kubernetes taints](https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/) + to apply to nodes. This field will only report drift on taint keys that are + already managed with Terraform, use `effective_taints` to view the list of + GKE-managed taints on the node pool from all sources. Importing this resource + will not record any taints as being Terraform-managed, and will cause drift with + any configured taints. Structure is [documented below](#nested_taint). + +* `workload_metadata_config` - (Optional) Metadata configuration to expose to workloads on the node pool. + Structure is [documented below](#nested_workload_metadata_config). + +* `kubelet_config` - (Optional) + Kubelet configuration, currently supported attributes can be found [here](https://cloud.google.com/sdk/gcloud/reference/beta/container/node-pools/create#--system-config-from-file). + Structure is [documented below](#nested_kubelet_config). + +``` +kubelet_config { + cpu_manager_policy = "static" + cpu_cfs_quota = true + cpu_cfs_quota_period = "100us" + pod_pids_limit = 1024 +} +``` + +* `linux_node_config` - (Optional) Parameters that can be configured on Linux nodes. Structure is [documented below](#nested_linux_node_config). + +* `containerd_config` - (Optional) Parameters to customize containerd runtime. Structure is [documented below](#nested_containerd_config). + +* `node_group` - (Optional) Setting this field will assign instances of this pool to run on the specified node group. This is useful for running workloads on [sole tenant nodes](https://cloud.google.com/compute/docs/nodes/sole-tenant-nodes). + +* `sole_tenant_config` (Optional) Allows specifying multiple [node affinities](https://cloud.google.com/compute/docs/nodes/sole-tenant-nodes#node_affinity_and_anti-affinity) useful for running workloads on [sole tenant nodes](https://cloud.google.com/kubernetes-engine/docs/how-to/sole-tenancy). `node_affinity` structure is [documented below](#nested_node_affinity). + +```hcl +sole_tenant_config { + node_affinity { + key = "compute.googleapis.com/node-group-name" + operator = "IN" + values = ["node-group-name"] + } +} +``` + +* `advanced_machine_features` - (Optional) Specifies options for controlling + advanced machine features. Structure is [documented below](#nested_advanced_machine_features). + +The `node_affinity` block supports: + +* `key` (Required) - The default or custom node affinity label key name. + +* `operator` (Required) - Specifies affinity or anti-affinity. Accepted values are `"IN"` or `"NOT_IN"` + +* `values` (Required) - List of node affinity label values as strings. + +The `advanced_machine_features` block supports: + +* `threads_per_core` - (Required) The number of threads per physical core. To disable simultaneous multithreading (SMT) set this to 1. If unset, the maximum number of threads supported per core by the underlying processor is assumed. + +* `enable_nested_virtualization`- (Optional) Defines whether the instance should have nested virtualization enabled. Defaults to false. + +* `network_performance_config` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) Network bandwidth tier configuration. + +The `network_performance_config` block supports: + +* `total_egress_bandwidth_tier` (Required) - Specifies the total network bandwidth tier for the NodePool. + +The `ephemeral_storage_config` block supports: + +* `local_ssd_count` (Required) - Number of local SSDs to use to back ephemeral storage. Uses NVMe interfaces. Each local SSD is 375 GB in size. If zero, it means to disable using local SSDs as ephemeral storage. + +The `ephemeral_storage_local_ssd_config` block supports: + +* `local_ssd_count` (Required) - Number of local SSDs to use to back ephemeral storage. Uses NVMe interfaces. Each local SSD is 375 GB in size. If zero, it means to disable using local SSDs as ephemeral storage. + +The `fast_socket` block supports: + +* `enabled` (Required) - Whether or not the NCCL Fast Socket is enabled + +The `local_nvme_ssd_block_config` block supports: + +* `local_ssd_count` (Required) - Number of raw-block local NVMe SSD disks to be attached to the node. Each local SSD is 375 GB in size. If zero, it means no raw-block local NVMe SSD disks to be attached to the node. + -> Note: Local NVMe SSD storage available in GKE versions v1.25.3-gke.1800 and later. + +The `secondary_boot_disks` block supports: + +* `disk_image` (Required) - Path to disk image to create the secondary boot disk from. After using the [gke-disk-image-builder](https://github.com/GoogleCloudPlatform/ai-on-gke/tree/main/tools/gke-disk-image-builder), this argument should be `global/images/DISK_IMAGE_NAME`. +* `mode` (Optional) - Mode for how the secondary boot disk is used. An example mode is `CONTAINER_IMAGE_CACHE`. + + +The `gcfs_config` block supports: + +* `enabled` (Required) - Whether or not the Google Container Filesystem (GCFS) is enabled + +The `gvnic` block supports: + +* `enabled` (Required) - Whether or not the Google Virtual NIC (gVNIC) is enabled + +The `guest_accelerator` block supports: + +* `type` (Required) - The accelerator type resource to expose to this instance. E.g. `nvidia-tesla-k80`. + +* `count` (Required) - The number of the guest accelerator cards exposed to this instance. + +* `gpu_driver_installation_config` (Optional) - Configuration for auto installation of GPU driver. Structure is [documented below](#nested_gpu_driver_installation_config). + +* `gpu_partition_size` (Optional) - Size of partitions to create on the GPU. Valid values are described in the NVIDIA mig [user guide](https://docs.nvidia.com/datacenter/tesla/mig-user-guide/#partitioning). + +* `gpu_sharing_config` (Optional) - Configuration for GPU sharing. Structure is [documented below](#nested_gpu_sharing_config). + +The `gpu_driver_installation_config` block supports: + +* `gpu_driver_version` (Required) - Mode for how the GPU driver is installed. + Accepted values are: + * `"GPU_DRIVER_VERSION_UNSPECIFIED"`: Default value is to not install any GPU driver. + * `"INSTALLATION_DISABLED"`: Disable GPU driver auto installation and needs manual installation. + * `"DEFAULT"`: "Default" GPU driver in COS and Ubuntu. + * `"LATEST"`: "Latest" GPU driver in COS. + +The `gpu_sharing_config` block supports: + +* `gpu_sharing_strategy` (Required) - The type of GPU sharing strategy to enable on the GPU node. + Accepted values are: + * `"TIME_SHARING"`: Allow multiple containers to have [time-shared](https://cloud.google.com/kubernetes-engine/docs/concepts/timesharing-gpus) access to a single GPU device. + * `"MPS"`: Enable co-operative multi-process CUDA workloads to run concurrently on a single GPU device with [MPS](https://cloud.google.com/kubernetes-engine/docs/how-to/nvidia-mps-gpus) + +* `max_shared_clients_per_gpu` (Required) - The maximum number of containers that can share a GPU. + + The `workload_identity_config` block supports: + +* `workload_pool` (Optional) - The workload pool to attach all Kubernetes service accounts to. + +```hcl +workload_identity_config { + workload_pool = "${data.google_project.project.project_id}.svc.id.goog" +} +``` + +The `node_pool_auto_config` block supports: + +* `resource_manager_tags` - (Optional) A map of resource manager tag keys and values to be attached to the nodes for managing Compute Engine firewalls using Network Firewall Policies. Tags must be according to specifications found [here](https://cloud.google.com/vpc/docs/tags-firewalls-overview#specifications). A maximum of 5 tag key-value pairs can be specified. Existing tags will be replaced with new values. Tags must be in one of the following formats ([KEY]=[VALUE]) 1. `tagKeys/{tag_key_id}=tagValues/{tag_value_id}` 2. `{org_id}/{tag_key_name}={tag_value_name}` 3. `{project_id}/{tag_key_name}={tag_value_name}`. + +* `network_tags` (Optional) - The network tag config for the cluster's automatically provisioned node pools. + +The `network_tags` block supports: + +* `tags` (Optional) - List of network tags applied to auto-provisioned node pools. + +```hcl +node_pool_auto_config { + network_tags { + tags = ["foo", "bar"] + } +} +``` + +The `node_pool_defaults` block supports: +* `node_config_defaults` (Optional) - Subset of NodeConfig message that has defaults. + +The `node_config_defaults` block supports: + +* `logging_variant` (Optional) The type of logging agent that is deployed by default for newly created node pools in the cluster. Valid values include DEFAULT and MAX_THROUGHPUT. See [Increasing logging agent throughput](https://cloud.google.com/stackdriver/docs/solutions/gke/managing-logs#throughput) for more information. + +* `gcfs_config` (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) The default Google Container Filesystem (GCFS) configuration at the cluster level. e.g. enable [image streaming](https://cloud.google.com/kubernetes-engine/docs/how-to/image-streaming) across all the node pools within the cluster. Structure is [documented below](#nested_gcfs_config). + +The `notification_config` block supports: + +* `pubsub` (Required) - The pubsub config for the cluster's upgrade notifications. + +The `pubsub` block supports: + +* `enabled` (Required) - Whether or not the notification config is enabled + +* `topic` (Optional) - The pubsub topic to push upgrade notifications to. Must be in the same project as the cluster. Must be in the format: `projects/{project}/topics/{topic}`. + +* `filter` (Optional) - Choose what type of notifications you want to receive. If no filters are applied, you'll receive all notification types. Structure is [documented below](#nested_notification_filter). + +```hcl +notification_config { + pubsub { + enabled = true + topic = google_pubsub_topic.notifications.id + } +} +``` + + The `filter` block supports: + +* `event_type` (Optional) - Can be used to filter what notifications are sent. Accepted values are `UPGRADE_AVAILABLE_EVENT`, `UPGRADE_EVENT` and `SECURITY_BULLETIN_EVENT`. See [Filtering notifications](https://cloud.google.com/kubernetes-engine/docs/concepts/cluster-notifications#filtering) for more details. + + The `confidential_nodes` block supports: + +* `enabled` (Required) - Enable Confidential GKE Nodes for this cluster, to + enforce encryption of data in-use. + +The `pod_security_policy_config` block supports: + +* `enabled` (Required) - Enable the PodSecurityPolicy controller for this cluster. + If enabled, pods must be valid under a PodSecurityPolicy to be created. + +The `private_cluster_config` block supports: + +* `enable_private_nodes` (Optional) - Enables the private cluster feature, + creating a private endpoint on the cluster. In a private cluster, nodes only + have RFC 1918 private addresses and communicate with the master's private + endpoint via private networking. + +* `enable_private_endpoint` (Optional) - When `true`, the cluster's private + endpoint is used as the cluster endpoint and access through the public endpoint + is disabled. When `false`, either endpoint can be used. This field only applies + to private clusters, when `enable_private_nodes` is `true`. + +* `master_ipv4_cidr_block` (Optional) - The IP range in CIDR notation to use for + the hosted master network. This range will be used for assigning private IP + addresses to the cluster master(s) and the ILB VIP. This range must not overlap + with any other ranges in use within the cluster's network, and it must be a /28 + subnet. See [Private Cluster Limitations](https://cloud.google.com/kubernetes-engine/docs/how-to/private-clusters#req_res_lim) + for more details. This field only applies to private clusters, when + `enable_private_nodes` is `true`. + +* `private_endpoint_subnetwork` - (Optional) Subnetwork in cluster's network where master's endpoint will be provisioned. + +* `master_global_access_config` (Optional) - Controls cluster master global + access settings. If unset, Terraform will no longer manage this field and will + not modify the previously-set value. Structure is [documented below](#nested_master_global_access_config). + +In addition, the `private_cluster_config` allows access to the following read-only fields: + +* `peering_name` - The name of the peering between this cluster and the Google owned VPC. + +* `private_endpoint` - The internal IP address of this cluster's master endpoint. + +* `public_endpoint` - The external IP address of this cluster's master endpoint. + +!> The Google provider is unable to validate certain configurations of +`private_cluster_config` when `enable_private_nodes` is `false`. It's +recommended that you omit the block entirely if the field is not set to `true`. + +The `private_cluster_config.master_global_access_config` block supports: + +* `enabled` (Optional) - Whether the cluster master is accessible globally or + not. + +The `reservation_affinity` block supports: + +* `consume_reservation_type` (Required) The type of reservation consumption + Accepted values are: + + * `"UNSPECIFIED"`: Default value. This should not be used. + * `"NO_RESERVATION"`: Do not consume from any reserved capacity. + * `"ANY_RESERVATION"`: Consume any reservation available. + * `"SPECIFIC_RESERVATION"`: Must consume from a specific reservation. Must specify key value fields for specifying the reservations. +* `key` (Optional) The label key of a reservation resource. To target a SPECIFIC_RESERVATION by name, specify "compute.googleapis.com/reservation-name" as the key and specify the name of your reservation as its value. +* `values` (Optional) The list of label values of reservation resources. For example: the name of the specific reservation when using a key of "compute.googleapis.com/reservation-name" + + +The `sandbox_config` block supports: + +* `sandbox_type` (Required) Which sandbox to use for pods in the node pool. + Accepted values are: + + * `"gvisor"`: Pods run within a gVisor sandbox. + +The `release_channel` block supports: + +* `channel` - (Required) The selected release channel. + Accepted values are: + * UNSPECIFIED: Not set. + * RAPID: Weekly upgrade cadence; Early testers and developers who requires new features. + * REGULAR: Multiple per month upgrade cadence; Production users who need features not yet offered in the Stable channel. + * STABLE: Every few months upgrade cadence; Production users who need stability above all else, and for whom frequent upgrades are too risky. + +The `cost_management_config` block supports: + +* `enabled` (Optional) - Whether to enable the [cost allocation](https://cloud.google.com/kubernetes-engine/docs/how-to/cost-allocations) feature. + +The `resource_usage_export_config` block supports: + +* `enable_network_egress_metering` (Optional) - Whether to enable network egress metering for this cluster. If enabled, a daemonset will be created + in the cluster to meter network egress traffic. + +* `enable_resource_consumption_metering` (Optional) - Whether to enable resource + consumption metering on this cluster. When enabled, a table will be created in + the resource export BigQuery dataset to store resource consumption data. The + resulting table can be joined with the resource usage table or with BigQuery + billing export. Defaults to `true`. + +* `bigquery_destination` (Required) - Parameters for using BigQuery as the destination of resource usage export. + +* `bigquery_destination.dataset_id` (Required) - The ID of a BigQuery Dataset. For Example: + +```hcl +resource_usage_export_config { + enable_network_egress_metering = false + enable_resource_consumption_metering = true + + bigquery_destination { + dataset_id = "cluster_resource_usage" + } +} +``` + +The `shielded_instance_config` block supports: + +* `enable_secure_boot` (Optional) - Defines if the instance has Secure Boot enabled. + +Secure Boot helps ensure that the system only runs authentic software by verifying the digital signature of all boot components, and halting the boot process if signature verification fails. Defaults to `false`. + +* `enable_integrity_monitoring` (Optional) - Defines if the instance has integrity monitoring enabled. + +Enables monitoring and attestation of the boot integrity of the instance. The attestation is performed against the integrity policy baseline. This baseline is initially derived from the implicitly trusted boot image when the instance is created. Defaults to `true`. + +The `taint` block supports: + +* `key` (Required) Key for taint. + +* `value` (Required) Value for taint. + +* `effect` (Required) Effect for taint. Accepted values are `NO_SCHEDULE`, `PREFER_NO_SCHEDULE`, and `NO_EXECUTE`. + +The `workload_metadata_config` block supports: + +* `mode` (Required) How to expose the node metadata to the workload running on the node. + Accepted values are: + * MODE_UNSPECIFIED: Not Set + * GCE_METADATA: Expose all Compute Engine metadata to pods. + * GKE_METADATA: Run the GKE Metadata Server on this node. The GKE Metadata Server exposes a metadata API to workloads that is compatible with the V1 Compute Metadata APIs exposed by the Compute Engine and App Engine Metadata Servers. This feature can only be enabled if [workload identity](https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity) is enabled at the cluster level. + +The `kubelet_config` block supports: + +* `cpu_manager_policy` - (Required) The CPU management policy on the node. See + [K8S CPU Management Policies](https://kubernetes.io/docs/tasks/administer-cluster/cpu-management-policies/). + One of `"none"` or `"static"`. Defaults to `none` when `kubelet_config` is unset. + +* `cpu_cfs_quota` - (Optional) If true, enables CPU CFS quota enforcement for + containers that specify CPU limits. + +* `cpu_cfs_quota_period` - (Optional) The CPU CFS quota period value. Specified + as a sequence of decimal numbers, each with optional fraction and a unit suffix, + such as `"300ms"`. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", + "h". The value must be a positive duration. + +-> Note: At the time of writing (2020/08/18) the GKE API rejects the `none` +value and accepts an invalid `default` value instead. While this remains true, +not specifying the `kubelet_config` block should be the equivalent of specifying +`none`. + +* `pod_pids_limit` - (Optional) Controls the maximum number of processes allowed to run in a pod. The value must be greater than or equal to 1024 and less than 4194304. + +The `linux_node_config` block supports: + +* `sysctls` - (Optional) The Linux kernel parameters to be applied to the nodes + and all pods running on the nodes. Specified as a map from the key, such as + `net.core.wmem_max`, to a string value. Currently supported attributes can be found [here](https://cloud.google.com/sdk/gcloud/reference/beta/container/node-pools/create#--system-config-from-file). + Note that validations happen all server side. All attributes are optional. + +```hcl +linux_node_config { + sysctls = { + "net.core.netdev_max_backlog" = "10000" + "net.core.rmem_max" = "10000" + } +} +``` + +* `cgroup_mode` - (Optional) Possible cgroup modes that can be used. + Accepted values are: + * `CGROUP_MODE_UNSPECIFIED`: CGROUP_MODE_UNSPECIFIED is when unspecified cgroup configuration is used. The default for the GKE node OS image will be used. + * `CGROUP_MODE_V1`: CGROUP_MODE_V1 specifies to use cgroupv1 for the cgroup configuration on the node image. + * `CGROUP_MODE_V2`: CGROUP_MODE_V2 specifies to use cgroupv2 for the cgroup configuration on the node image. + +The `containerd_config` block supports: + +* `private_registry_access_config` (Optional) - Configuration for private container registries. There are two fields in this config: + + * `enabled` (Required) - Enables private registry config. If set to false, all other fields in this object must not be set. + + * `certificate_authority_domain_config` (Optional) - List of configuration objects for CA and domains. Each object identifies a certificate and its assigned domains. See [how to configure for private container registries](https://cloud.google.com/kubernetes-engine/docs/how-to/access-private-registries-private-certificates) for more detail. Example: + ```hcl + certificate_authority_domain_config { + fqdns = [ + "my.custom.domain", + "10.4.5.6", + "127.0.0.1:8888", + ] + gcp_secret_manager_certificate_config { + secret_uri = "projects/99999/secrets/my-ca-cert/versions/1" + } + } + ``` + +The `vertical_pod_autoscaling` block supports: + +* `enabled` (Required) - Enables vertical pod autoscaling + +The `dns_config` block supports: + +* `additive_vpc_scope_dns_domain` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) This will enable Cloud DNS additive VPC scope. Must provide a domain name that is unique within the VPC. For this to work `cluster_dns = "CLOUD_DNS"` and `cluster_dns_scope = "CLUSTER_SCOPE"` must both be set as well. + +* `cluster_dns` - (Optional) Which in-cluster DNS provider should be used. `PROVIDER_UNSPECIFIED` (default) or `PLATFORM_DEFAULT` or `CLOUD_DNS`. + +* `cluster_dns_scope` - (Optional) The scope of access to cluster DNS records. `DNS_SCOPE_UNSPECIFIED` (default) or `CLUSTER_SCOPE` or `VPC_SCOPE`. + +* `cluster_dns_domain` - (Optional) The suffix used for all cluster service records. + +The `gateway_api_config` block supports: + +* `channel` - (Required) Which Gateway Api channel should be used. `CHANNEL_DISABLED`, `CHANNEL_EXPERIMENTAL` or `CHANNEL_STANDARD`. + +The `protect_config` block supports: + +* `workload_config` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) WorkloadConfig defines which actions are enabled for a cluster's workload configurations. Structure is [documented below](#nested_workload_config) + +* `workload_vulnerability_mode` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) Sets which mode to use for Protect workload vulnerability scanning feature. Accepted values are DISABLED, BASIC. + +The `protect_config.workload_config` block supports: + +* `audit_mode` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) Sets which mode of auditing should be used for the cluster's workloads. Accepted values are DISABLED, BASIC. + +The `security_posture_config` block supports: + +* `mode` - (Optional) Sets the mode of the Kubernetes security posture API's off-cluster features. Available options include `DISABLED` and `BASIC`. + + +* `vulnerability_mode` - (Optional) Sets the mode of the Kubernetes security posture API's workload vulnerability scanning. Available options include `VULNERABILITY_DISABLED`, `VULNERABILITY_BASIC` and `VULNERABILITY_ENTERPRISE`. + +The `fleet` block supports: + +* `project` - (Optional) The name of the Fleet host project where this cluster will be registered. + +The `workload_alts_config` block supports: + +* `enable_alts` - (Required) Whether the alts handshaker should be enabled or not for direct-path. Requires Workload Identity ([workloadPool]((#nested_workload_identity_config)) must be non-empty). + +## Attributes Reference + +In addition to the arguments listed above, the following computed attributes are +exported: + +* `id` - an identifier for the resource with format `projects/{{project}}/locations/{{zone}}/clusters/{{name}}` + +* `self_link` - The server-defined URL for the resource. + +* `endpoint` - The IP address of this cluster's Kubernetes master. + +* `label_fingerprint` - The fingerprint of the set of labels for this cluster. + +* `maintenance_policy.0.daily_maintenance_window.0.duration` - Duration of the time window, automatically chosen to be + smallest possible in the given scenario. + Duration will be in [RFC3339](https://www.ietf.org/rfc/rfc3339.txt) format "PTnHnMnS". + +* `master_auth.0.client_certificate` - Base64 encoded public certificate + used by clients to authenticate to the cluster endpoint. + +* `master_auth.0.client_key` - Base64 encoded private key used by clients + to authenticate to the cluster endpoint. + +* `master_auth.0.cluster_ca_certificate` - Base64 encoded public certificate + that is the root certificate of the cluster. + +* `master_version` - The current version of the master in the cluster. This may + be different than the `min_master_version` set in the config if the master + has been updated by GKE. + +* `tpu_ipv4_cidr_block` - The IP address range of the Cloud TPUs in this cluster, in + [CIDR](http://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing) + notation (e.g. `1.2.3.4/29`). + +* `services_ipv4_cidr` - The IP address range of the Kubernetes services in this + cluster, in [CIDR](http://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing) + notation (e.g. `1.2.3.4/29`). Service addresses are typically put in the last + `/16` from the container CIDR. + +* `cluster_autoscaling.0.auto_provisioning_defaults.0.management.0.upgrade_options` - Specifies the [Auto Upgrade knobs](https://cloud.google.com/kubernetes-engine/docs/reference/rest/v1beta1/NodeManagement#AutoUpgradeOptions) for the node pool. + +* `node_config.0.effective_taints` - List of kubernetes taints applied to each node. Structure is [documented above](#nested_taint). + +* `fleet.0.membership` - The resource name of the fleet Membership resource associated to this cluster with format `//gkehub.googleapis.com/projects/{{project}}/locations/{{location}}/memberships/{{name}}`. See the official doc for [fleet management](https://cloud.google.com/kubernetes-engine/docs/fleets-overview). + +* `fleet.0.membership_id` - The short name of the fleet membership, extracted from `fleet.0.membership`. You can use this field to configure `membership_id` under [google_gkehub_feature_membership](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/gke_hub_feature_membership). + +* `fleet.0.membership_location` - The location of the fleet membership, extracted from `fleet.0.membership`. You can use this field to configure `membership_location` under [google_gkehub_feature_membership](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/gke_hub_feature_membership). + +## Timeouts + +This resource provides the following +[Timeouts](https://developer.hashicorp.com/terraform/plugin/sdkv2/resources/retries-and-customizable-timeouts) configuration options: configuration options: + +- `create` - Default is 40 minutes. +- `read` - Default is 40 minutes. +- `update` - Default is 60 minutes. +- `delete` - Default is 40 minutes. + +## Import + +GKE clusters can be imported using the `project` , `location`, and `name`. If the project is omitted, the default +provider value will be used. Examples: + +* `projects/{{project_id}}/locations/{{location}}/clusters/{{cluster_id}}` +* `{{project_id}}/{{location}}/{{cluster_id}}` +* `{{location}}/{{cluster_id}}` + +In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import GKE clusters using one of the formats above. For example: + +```tf +import { + id = "projects/{{project_id}}/locations/{{location}}/clusters/{{cluster_id}}" + to = google_container_cluster.default +} +``` + +When using the [`terraform import` command](https://developer.hashicorp.com/terraform/cli/commands/import), GKE clusters can be imported using one of the formats above. For example: + +``` +$ terraform import google_container_cluster.default projects/{{project_id}}/locations/{{location}}/clusters/{{cluster_id}} + +$ terraform import google_container_cluster.default {{project_id}}/{{location}}/{{cluster_id}} + +$ terraform import google_container_cluster.default {{location}}/{{cluster_id}} +``` + +~> **Note:** This resource has several fields that control Terraform-specific behavior and aren't present in the API. If they are set in config and you import a cluster, Terraform may need to perform an update immediately after import. Most of these updates should be no-ops but some may modify your cluster if the imported state differs. + +For example, the following fields will show diffs if set in config: + +- `min_master_version` +- `remove_default_node_pool` + +## User Project Overrides + +This resource supports [User Project Overrides](https://registry.terraform.io/providers/hashicorp/google/latest/docs/guides/provider_reference#user_project_override). \ No newline at end of file diff --git a/docs/resources/vks_cluster_node_group.md b/docs/resources/vks_cluster_node_group.md new file mode 100644 index 0000000..04c4824 --- /dev/null +++ b/docs/resources/vks_cluster_node_group.md @@ -0,0 +1,328 @@ +--- +subcategory: "Kubernetes Service" +description: |- + Manages a VKS NodeGroup resource. +--- + +# vngcloud_vks_cluster_node_group + +-> See the [Using GKE with Terraform](/docs/providers/google/guides/using_gke_with_terraform.html) +guide for more information about using GKE with Terraform. + +Manages a node pool in a Google Kubernetes Engine (GKE) cluster separately from +the cluster control plane. For more information see [the official documentation](https://cloud.google.com/container-engine/docs/node-pools) +and [the API reference](https://cloud.google.com/kubernetes-engine/docs/reference/rest/v1beta1/projects.locations.clusters.nodePools). + +### Example Usage - using a separately managed node pool (recommended) + +```hcl +resource "google_service_account" "default" { + account_id = "service-account-id" + display_name = "Service Account" +} + +resource "google_container_cluster" "primary" { + name = "my-gke-cluster" + location = "us-central1" + + # We can't create a cluster with no node pool defined, but we want to only use + # separately managed node pools. So we create the smallest possible default + # node pool and immediately delete it. + remove_default_node_pool = true + initial_node_count = 1 +} + +resource "google_container_node_pool" "primary_preemptible_nodes" { + name = "my-node-pool" + cluster = google_container_cluster.primary.id + node_count = 1 + + node_config { + preemptible = true + machine_type = "e2-medium" + + # Google recommends custom service accounts that have cloud-platform scope and permissions granted via IAM Roles. + service_account = google_service_account.default.email + oauth_scopes = [ + "https://www.googleapis.com/auth/cloud-platform" + ] + } +} +``` + +### Example Usage - 2 node pools, 1 separately managed + the default node pool + +```hcl +resource "google_service_account" "default" { + account_id = "service-account-id" + display_name = "Service Account" +} + +resource "google_container_node_pool" "np" { + name = "my-node-pool" + cluster = google_container_cluster.primary.id + node_config { + machine_type = "e2-medium" + # Google recommends custom service accounts that have cloud-platform scope and permissions granted via IAM Roles. + service_account = google_service_account.default.email + oauth_scopes = [ + "https://www.googleapis.com/auth/cloud-platform" + ] + } + timeouts { + create = "30m" + update = "20m" + } +} + +resource "google_container_cluster" "primary" { + name = "marcellus-wallace" + location = "us-central1-a" + initial_node_count = 3 + + node_locations = [ + "us-central1-c", + ] + + node_config { + # Google recommends custom service accounts that have cloud-platform scope and permissions granted via IAM Roles. + service_account = google_service_account.default.email + oauth_scopes = [ + "https://www.googleapis.com/auth/cloud-platform" + ] + guest_accelerator { + type = "nvidia-tesla-k80" + count = 1 + } + } +} +``` + +## Argument Reference + +* `cluster` - (Required) The cluster to create the node pool for. Cluster must be present in `location` provided for clusters. May be specified in the format `projects/{{project}}/locations/{{location}}/clusters/{{cluster}}` or as just the name of the cluster. + +- - - + +* `location` - (Optional) The location (region or zone) of the cluster. + +- - - + +* `autoscaling` - (Optional) Configuration required by cluster autoscaler to adjust + the size of the node pool to the current cluster usage. Structure is [documented below](#nested_autoscaling). + +* `confidential_nodes` - (Optional) Configuration for Confidential Nodes feature. Structure is [documented below](#nested_confidential_nodes). + +* `initial_node_count` - (Optional) The initial number of nodes for the pool. In + regional or multi-zonal clusters, this is the number of nodes per zone. Changing + this will force recreation of the resource. WARNING: Resizing your node pool manually + may change this value in your existing cluster, which will trigger destruction + and recreation on the next Terraform run (to rectify the discrepancy). If you don't + need this value, don't set it. If you do need it, you can [use a lifecycle block to + ignore subsequent changes to this field](https://github.com/hashicorp/terraform-provider-google/issues/6901#issuecomment-667369691). + +* `management` - (Optional) Node management configuration, wherein auto-repair and + auto-upgrade is configured. Structure is [documented below](#nested_management). + +* `max_pods_per_node` - (Optional) The maximum number of pods per node in this node pool. + Note that this does not work on node pools which are "route-based" - that is, node + pools belonging to clusters that do not have IP Aliasing enabled. + See the [official documentation](https://cloud.google.com/kubernetes-engine/docs/how-to/flexible-pod-cidr) + for more information. + +* `node_locations` - (Optional) + The list of zones in which the node pool's nodes should be located. Nodes must + be in the region of their regional cluster or in the same region as their + cluster's zone for zonal clusters. If unspecified, the cluster-level + `node_locations` will be used. + +-> Note: `node_locations` will not revert to the cluster's default set of zones +upon being unset. You must manually reconcile the list of zones with your +cluster. + +* `name` - (Optional) The name of the node pool. If left blank, Terraform will + auto-generate a unique name. + +* `name_prefix` - (Optional) Creates a unique name for the node pool beginning + with the specified prefix. Conflicts with `name`. + +* `node_config` - (Optional) Parameters used in creating the node pool. See + [google_container_cluster](container_cluster.html#nested_node_config) for schema. + +* `network_config` - (Optional) The network configuration of the pool. Such as + configuration for [Adding Pod IP address ranges](https://cloud.google.com/kubernetes-engine/docs/how-to/multi-pod-cidr)) to the node pool. Or enabling private nodes. Structure is + [documented below](#nested_network_config) + +* `node_count` - (Optional) The number of nodes per instance group. This field can be used to + update the number of nodes per instance group but should not be used alongside `autoscaling`. + +* `project` - (Optional) The ID of the project in which to create the node pool. If blank, + the provider-configured project will be used. + +* `upgrade_settings` (Optional) Specify node upgrade settings to change how GKE upgrades nodes. + The maximum number of nodes upgraded simultaneously is limited to 20. Structure is [documented below](#nested_upgrade_settings). + +* `version` - (Optional) The Kubernetes version for the nodes in this pool. Note that if this field + and `auto_upgrade` are both specified, they will fight each other for what the node version should + be, so setting both is highly discouraged. While a fuzzy version can be specified, it's + recommended that you specify explicit versions as Terraform will see spurious diffs + when fuzzy versions are used. See the `google_container_engine_versions` data source's + `version_prefix` field to approximate fuzzy versions in a Terraform-compatible way. + +* `placement_policy` - (Optional) Specifies a custom placement policy for the + nodes. + +* `queued_provisioning` - (Optional) Specifies node pool-level settings of queued provisioning. + Structure is [documented below](#nested_queued_provisioning). + +The `autoscaling` block supports (either total or per zone limits are required): + +* `min_node_count` - (Optional) Minimum number of nodes per zone in the NodePool. + Must be >=0 and <= `max_node_count`. Cannot be used with total limits. + +* `max_node_count` - (Optional) Maximum number of nodes per zone in the NodePool. + Must be >= min_node_count. Cannot be used with total limits. + +* `total_min_node_count` - (Optional) Total minimum number of nodes in the NodePool. + Must be >=0 and <= `total_max_node_count`. Cannot be used with per zone limits. + Total size limits are supported only in 1.24.1+ clusters. + +* `total_max_node_count` - (Optional) Total maximum number of nodes in the NodePool. + Must be >= total_min_node_count. Cannot be used with per zone limits. + Total size limits are supported only in 1.24.1+ clusters. + +* `location_policy` - (Optional) Location policy specifies the algorithm used when + scaling-up the node pool. Location policy is supported only in 1.24.1+ clusters. + * "BALANCED" - Is a best effort policy that aims to balance the sizes of available zones. + * "ANY" - Instructs the cluster autoscaler to prioritize utilization of unused reservations, + and reduce preemption risk for Spot VMs. + + The `confidential_nodes` block supports: + +* `enabled` (Required) - Enable Confidential GKE Nodes for this cluster, to + enforce encryption of data in-use. + +The `management` block supports: + +* `auto_repair` - (Optional) Whether the nodes will be automatically repaired. Enabled by default. + +* `auto_upgrade` - (Optional) Whether the nodes will be automatically upgraded. Enabled by default. + +The `network_config` block supports: + +* `create_pod_range` - (Optional) Whether to create a new range for pod IPs in this node pool. Defaults are provided for `pod_range` and `pod_ipv4_cidr_block` if they are not specified. + +* `enable_private_nodes` - (Optional) Whether nodes have internal IP addresses only. + +* `pod_ipv4_cidr_block` - (Optional) The IP address range for pod IPs in this node pool. Only applicable if createPodRange is true. Set to blank to have a range chosen with the default size. Set to /netmask (e.g. /14) to have a range chosen with a specific netmask. Set to a CIDR notation (e.g. 10.96.0.0/14) to pick a specific range to use. + +* `pod_range` - (Optional) The ID of the secondary range for pod IPs. If `create_pod_range` is true, this ID is used for the new range. If `create_pod_range` is false, uses an existing secondary range with this ID. + +* `additional_node_network_configs` - (Optional, Beta) We specify the additional node networks for this node pool using this list. Each node network corresponds to an additional interface. + Structure is [documented below](#nested_additional_node_network_configs) + +* `additional_pod_network_configs` - (Optional, Beta) We specify the additional pod networks for this node pool using this list. Each pod network corresponds to an additional alias IP range for the node. + Structure is [documented below](#nested_additional_pod_network_configs) + + +The `additional_node_network_configs` block supports: + +* `network` - Name of the VPC where the additional interface belongs. + +* `subnetwork` - Name of the subnetwork where the additional interface belongs. + +The `additional_pod_network_configs` block supports: + +* `subnetwork` - Name of the subnetwork where the additional pod network belongs. + +* `secondary_pod_range` - The name of the secondary range on the subnet which provides IP address for this pod range. + +* `max_pods_per_node` - The maximum number of pods per node which use this pod network. + +The `upgrade_settings` block supports: + +* `max_surge` - (Optional) The number of additional nodes that can be added to the node pool during + an upgrade. Increasing `max_surge` raises the number of nodes that can be upgraded simultaneously. + Can be set to 0 or greater. + +* `max_unavailable` - (Optional) The number of nodes that can be simultaneously unavailable during + an upgrade. Increasing `max_unavailable` raises the number of nodes that can be upgraded in + parallel. Can be set to 0 or greater. + +`max_surge` and `max_unavailable` must not be negative and at least one of them must be greater than zero. + +* `strategy` - (Default `SURGE`) The upgrade stragey to be used for upgrading the nodes. + +* `blue_green_settings` - (Optional) The settings to adjust [blue green upgrades](https://cloud.google.com/kubernetes-engine/docs/concepts/node-pool-upgrade-strategies#blue-green-upgrade-strategy). + Structure is [documented below](#nested_blue_green_settings) + +The `blue_green_settings` block supports: + +* `standard_rollout_policy` - (Required) Specifies the standard policy settings for blue-green upgrades. + * `batch_percentage` - (Optional) Percentage of the blue pool nodes to drain in a batch. + * `batch_node_count` - (Optional) Number of blue nodes to drain in a batch. + * `batch_soak_duration` - (Optionial) Soak time after each batch gets drained. + +* `node_pool_soak_duration` - (Optional) Time needed after draining the entire blue pool. + After this period, the blue pool will be cleaned up. + +The `placement_policy` block supports: + +* `type` - (Required) The type of the policy. Supports a single value: COMPACT. + Specifying COMPACT placement policy type places node pool's nodes in a closer + physical proximity in order to reduce network latency between nodes. + +* `policy_name` - (Optional) If set, refers to the name of a custom resource policy supplied by the user. + The resource policy must be in the same project and region as the node pool. + If not found, InvalidArgument error is returned. + +* `tpu_topology` - (Optional) The [TPU placement topology](https://cloud.google.com/tpu/docs/types-topologies#tpu_topologies) for pod slice node pool. + + The `queued_provisioning` block supports: + +* `enabled` (Required) - Makes nodes obtainable through the [ProvisioningRequest API](https://cloud.google.com/kubernetes-engine/docs/how-to/provisioningrequest) exclusively. + +## Attributes Reference + +In addition to the arguments listed above, the following computed attributes are exported: + +* `id` - an identifier for the resource with format `{{project}}/{{location}}/{{cluster}}/{{name}}` + +* `instance_group_urls` - The resource URLs of the managed instance groups associated with this node pool. + +* `managed_instance_group_urls` - List of instance group URLs which have been assigned to this node pool. + + +## Timeouts + +`google_container_node_pool` provides the following +[Timeouts](https://developer.hashicorp.com/terraform/plugin/sdkv2/resources/retries-and-customizable-timeouts) configuration options: configuration options: + +- `create` - (Default `30 minutes`) Used for adding node pools +- `update` - (Default `30 minutes`) Used for updates to node pools +- `delete` - (Default `30 minutes`) Used for removing node pools. + +## Import + +Node pools can be imported using the `project`, `location`, `cluster` and `name`. If +the project is omitted, the project value in the provider configuration will be used. Examples: + +* `{{project_id}}/{{location}}/{{cluster_id}}/{{pool_id}}` +* `{{location}}/{{cluster_id}}/{{pool_id}}` + +In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import node pools using one of the formats above. For example: + +```tf +import { + id = "{{project_id}}/{{location}}/{{cluster_id}}/{{pool_id}}" + to = google_container_node_pool.default +} +``` + +When using the [`terraform import` command](https://developer.hashicorp.com/terraform/cli/commands/import), node pools can be imported using one of the formats above. For example: + +``` +$ terraform import google_container_node_pool.default {{project_id}}/{{location}}/{{cluster_id}}/{{pool_id}} + +$ terraform import google_container_node_pool.default {{location}}/{{cluster_id}}/{{pool_id}} +``` \ No newline at end of file diff --git a/resource/vks/resource_cluster.go b/resource/vks/resource_cluster.go index 7403a7e..3396b23 100644 --- a/resource/vks/resource_cluster.go +++ b/resource/vks/resource_cluster.go @@ -17,13 +17,13 @@ import ( func ResourceCluster() *schema.Resource { return &schema.Resource{ - SchemaVersion: 1, - MigrateState: resourceClusterMigrateState, + SchemaVersion: 0, + //MigrateState: resourceClusterMigrateState, //StateUpgraders: []schema.StateUpgrader{ // { // Type: resourceContainerClusterResourceV1().CoreConfigSchema().ImpliedType(), // Upgrade: ResourceContainerClusterUpgradeV1, - // Version: 1, + // Version: 0, // }, //}, @@ -31,19 +31,19 @@ func ResourceCluster() *schema.Resource { Read: resourceClusterRead, Update: resourceClusterUpdate, Delete: resourceClusterDelete, - //Importer: &schema.ResourceImporter{ - // State: func(d *schema.ResourceData, m interface{}) ([]*schema.ResourceData, error) { - // idParts := strings.Split(d.Id(), ":") - // if len(idParts) != 2 || idParts[0] == "" || idParts[1] == "" { - // return nil, fmt.Errorf("Unexpected format of ID (%q), expected ProjectID:VolumeID", d.Id()) - // } - // projectID := idParts[0] - // volumeID := idParts[1] - // d.SetId(volumeID) - // d.Set("project_id", projectID) - // return []*schema.ResourceData{d}, nil - // }, - //}, + Importer: &schema.ResourceImporter{ + State: func(d *schema.ResourceData, m interface{}) ([]*schema.ResourceData, error) { + cli := m.(*client.Client) + _, httpResponse, _ := cli.VksClient.V1ClusterControllerApi.V1ClustersClusterIdGet(context.TODO(), d.Id(), nil) + if CheckErrorResponse(httpResponse) { + responseBody := GetResponseBody(httpResponse) + errResponse := fmt.Errorf("request fail with errMsg: %s", responseBody) + return nil, errResponse + } + resourceClusterRead(d, m) + return []*schema.ResourceData{d}, nil + }, + }, Schema: map[string]*schema.Schema{ "name": { Type: schema.TypeString, @@ -317,6 +317,14 @@ func resourceClusterRead(d *schema.ResourceData, m interface{}) error { if !CheckListStringEqual(whiteListNodeCIDR, whiteListCIDRCluster) { d.Set("white_list_node_cidr", whiteListCIDRCluster) } + d.Set("cidr", cluster.Cidr) + d.Set("vpc_id", cluster.VpcId) + d.Set("subnet_id", cluster.SubnetId) + d.Set("network_type", cluster.NetworkType) + d.Set("name", cluster.Name) + d.Set("enabled_load_balancer_plugin", cluster.EnabledLoadBalancerPlugin) + d.Set("enabled_block_store_csi_plugin", cluster.EnabledBlockStoreCsiPlugin) + d.Set("enable_private_cluster", cluster.EnablePrivateCluster) log.Printf("GetConfig\n") configResp, httpResponse, _ := cli.VksClient.V1ClusterControllerApi.V1ClustersClusterIdKubeconfigGet(context.TODO(), clusterID, nil) if !CheckErrorResponse(httpResponse) { diff --git a/resource/vks/resrouce_cluster_node_group.go b/resource/vks/resrouce_cluster_node_group.go index e7e303d..b7d1f99 100644 --- a/resource/vks/resrouce_cluster_node_group.go +++ b/resource/vks/resrouce_cluster_node_group.go @@ -12,12 +12,13 @@ import ( "github.com/vngcloud/terraform-provider-vngcloud/client/vks" "log" "net/http" + "strings" "time" ) func ResourceClusterNodeGroup() *schema.Resource { return &schema.Resource{ - SchemaVersion: 1, + SchemaVersion: 0, //MigrateState: resourceClusterNodeGroupMigrateState, //StateUpgraders: []schema.StateUpgrader{ // { @@ -31,19 +32,27 @@ func ResourceClusterNodeGroup() *schema.Resource { Read: resourceClusterNodeGroupRead, Update: resourceClusterNodeGroupUpdate, Delete: resourceClusterNodeGroupDelete, - //Importer: &schema.ResourceImporter{ - // State: func(d *schema.ResourceData, m interface{}) ([]*schema.ResourceData, error) { - // idParts := strings.Split(d.Id(), ":") - // if len(idParts) != 2 || idParts[0] == "" || idParts[1] == "" { - // return nil, fmt.Errorf("Unexpected format of ID (%q), expected ProjectID:VolumeID", d.Id()) - // } - // projectID := idParts[0] - // volumeID := idParts[1] - // d.SetId(volumeID) - // d.Set("project_id", projectID) - // return []*schema.ResourceData{d}, nil - // }, - //}, + Importer: &schema.ResourceImporter{ + State: func(d *schema.ResourceData, m interface{}) ([]*schema.ResourceData, error) { + idParts := strings.Split(d.Id(), ":") + if len(idParts) != 2 || idParts[0] == "" || idParts[1] == "" { + return nil, fmt.Errorf("Unexpected format of ID (%q), expected ClusterID:NodeGroupId", d.Id()) + } + clusterID := idParts[0] + nodeGroupID := idParts[1] + cli := m.(*client.Client) + _, httpResponse, _ := cli.VksClient.V1NodeGroupControllerApi.V1ClustersClusterIdNodeGroupsNodeGroupIdGet(context.TODO(), clusterID, nodeGroupID, nil) + if CheckErrorResponse(httpResponse) { + responseBody := GetResponseBody(httpResponse) + errResponse := fmt.Errorf("request fail with errMsg: %s", responseBody) + return nil, errResponse + } + d.SetId(nodeGroupID) + d.Set("cluster_id", clusterID) + resourceClusterNodeGroupRead(d, m) + return []*schema.ResourceData{d}, nil + }, + }, Schema: MergeSchemas( schemaNodeGroup, map[string]*schema.Schema{ @@ -344,6 +353,14 @@ func resourceClusterNodeGroupRead(d *schema.ResourceData, m interface{}) error { if !checkSecurityGroupsSame(d, resp) { d.Set("security_groups", resp.SecurityGroups) } + d.Set("disk_size", resp.DiskSize) + d.Set("disk_type", resp.DiskType) + d.Set("enable_private_nodes", resp.EnablePrivateNodes) + d.Set("flavor_id", resp.FlavorId) + d.Set("initial_node_count", resp.NumNodes) + d.Set("name", resp.Name) + d.Set("ssh_key_id", resp.SshKeyId) + return nil } From 5a1b10851a01b0ccaa11a3e896fa7a64e2b91fcb Mon Sep 17 00:00:00 2001 From: tunm4 <8-tunm4_2@users.noreply.git.vngcloud.dev> Date: Wed, 29 May 2024 15:07:54 +0700 Subject: [PATCH 04/14] update --- resource/vks/resource_cluster.go | 8 +++++++- resource/vks/resrouce_cluster_node_group.go | 4 ++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/resource/vks/resource_cluster.go b/resource/vks/resource_cluster.go index 3396b23..66f1f3c 100644 --- a/resource/vks/resource_cluster.go +++ b/resource/vks/resource_cluster.go @@ -252,7 +252,9 @@ func updateNodeGroupData(cli *client.Client, d *schema.ResourceData, clusterId s nodeGroup["upgrade_config"] = upgradeConfig nodeGroup["node_group_id"] = clusterNodeGroupDetail.Id } - + if nodeGroup["num_nodes"] != nil && int32(nodeGroup["num_nodes"].(int)) != 0 { + nodeGroup["num_nodes"] = clusterNodeGroup.NumNodes + } updatedNodeGroups[i] = nodeGroup } @@ -294,6 +296,10 @@ func resourceClusterRead(d *schema.ResourceData, m interface{}) error { clusterID := d.Id() cli := m.(*client.Client) resp, httpResponse, _ := cli.VksClient.V1ClusterControllerApi.V1ClustersClusterIdGet(context.TODO(), clusterID, nil) + if httpResponse.StatusCode == http.StatusNotFound { + d.SetId("") + return nil + } if CheckErrorResponse(httpResponse) { responseBody := GetResponseBody(httpResponse) errorResponse := fmt.Errorf("request fail with errMsg : %s", responseBody) diff --git a/resource/vks/resrouce_cluster_node_group.go b/resource/vks/resrouce_cluster_node_group.go index b7d1f99..da9865d 100644 --- a/resource/vks/resrouce_cluster_node_group.go +++ b/resource/vks/resrouce_cluster_node_group.go @@ -318,6 +318,10 @@ func resourceClusterNodeGroupRead(d *schema.ResourceData, m interface{}) error { clusterID := d.Get("cluster_id").(string) cli := m.(*client.Client) resp, httpResponse, _ := cli.VksClient.V1NodeGroupControllerApi.V1ClustersClusterIdNodeGroupsNodeGroupIdGet(context.TODO(), clusterID, d.Id(), nil) + if httpResponse.StatusCode == http.StatusNotFound { + d.SetId("") + return nil + } if CheckErrorResponse(httpResponse) { responseBody := GetResponseBody(httpResponse) errorResponse := fmt.Errorf("request fail with errMsg : %s", responseBody) From 5070643fffc4cfa94cbd2d87f85cb596cdbff6d7 Mon Sep 17 00:00:00 2001 From: tunm4 <8-tunm4_2@users.noreply.git.vngcloud.dev> Date: Thu, 30 May 2024 10:04:47 +0700 Subject: [PATCH 05/14] update --- resource/vks/resource_cluster.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resource/vks/resource_cluster.go b/resource/vks/resource_cluster.go index 66f1f3c..51e8e85 100644 --- a/resource/vks/resource_cluster.go +++ b/resource/vks/resource_cluster.go @@ -234,7 +234,7 @@ func updateNodeGroupData(cli *client.Client, d *schema.ResourceData, clusterId s clusterNodeGroups := resp.Items for i, ng := range nodeGroups { nodeGroup := ng.(map[string]interface{}) - clusterNodeGroup := clusterNodeGroups[i] + clusterNodeGroup := clusterNodeGroups[len(clusterNodeGroups)-i-1] // Set the value for a specific field upgradeConfig := nodeGroup["upgrade_config"].([]interface{}) if len(upgradeConfig) == 0 { From 1b1e9743e78d6e3f0c70bc159db0d35ab499af79 Mon Sep 17 00:00:00 2001 From: tunm4 <8-tunm4_2@users.noreply.git.vngcloud.dev> Date: Fri, 31 May 2024 11:38:50 +0700 Subject: [PATCH 06/14] update --- resource/vks/resrouce_cluster_node_group.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/resource/vks/resrouce_cluster_node_group.go b/resource/vks/resrouce_cluster_node_group.go index da9865d..3d833ba 100644 --- a/resource/vks/resrouce_cluster_node_group.go +++ b/resource/vks/resrouce_cluster_node_group.go @@ -361,7 +361,9 @@ func resourceClusterNodeGroupRead(d *schema.ResourceData, m interface{}) error { d.Set("disk_type", resp.DiskType) d.Set("enable_private_nodes", resp.EnablePrivateNodes) d.Set("flavor_id", resp.FlavorId) - d.Set("initial_node_count", resp.NumNodes) + if d.Get("initial_node_count") == nil { + d.Set("initial_node_count", resp.NumNodes) + } d.Set("name", resp.Name) d.Set("ssh_key_id", resp.SshKeyId) From 0d1e2c0c416aa46c82df1c23fbe9fafeac16a403 Mon Sep 17 00:00:00 2001 From: tunm4 <8-tunm4_2@users.noreply.git.vngcloud.dev> Date: Fri, 31 May 2024 13:54:12 +0700 Subject: [PATCH 07/14] update --- client/vks/model_update_node_group_dto.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/vks/model_update_node_group_dto.go b/client/vks/model_update_node_group_dto.go index 43b02fb..1716d99 100644 --- a/client/vks/model_update_node_group_dto.go +++ b/client/vks/model_update_node_group_dto.go @@ -10,7 +10,7 @@ package vks type UpdateNodeGroupDto struct { AutoScaleConfig *NodeGroupAutoScaleConfigDto `json:"autoScaleConfig,omitempty"` - NumNodes int32 `json:"numNodes,omitempty"` + NumNodes int32 `json:"numNodes"` UpgradeConfig *NodeGroupUpgradeConfigDto `json:"upgradeConfig"` SecurityGroups []string `json:"securityGroups"` ImageId string `json:"imageId"` From 4ec47973c3335a3c9fd36524ea599c41edb76377 Mon Sep 17 00:00:00 2001 From: tunm4 <8-tunm4_2@users.noreply.git.vngcloud.dev> Date: Fri, 31 May 2024 14:35:32 +0700 Subject: [PATCH 08/14] update --- client/vks/model_update_node_group_dto.go | 2 +- resource/vks/resource_cluster.go | 18 +++++++++++++++--- resource/vks/resrouce_cluster_node_group.go | 8 +++++++- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/client/vks/model_update_node_group_dto.go b/client/vks/model_update_node_group_dto.go index 1716d99..b49dbf2 100644 --- a/client/vks/model_update_node_group_dto.go +++ b/client/vks/model_update_node_group_dto.go @@ -10,7 +10,7 @@ package vks type UpdateNodeGroupDto struct { AutoScaleConfig *NodeGroupAutoScaleConfigDto `json:"autoScaleConfig,omitempty"` - NumNodes int32 `json:"numNodes"` + NumNodes *int32 `json:"numNodes"` UpgradeConfig *NodeGroupUpgradeConfigDto `json:"upgradeConfig"` SecurityGroups []string `json:"securityGroups"` ImageId string `json:"imageId"` diff --git a/resource/vks/resource_cluster.go b/resource/vks/resource_cluster.go index 51e8e85..8acef09 100644 --- a/resource/vks/resource_cluster.go +++ b/resource/vks/resource_cluster.go @@ -342,10 +342,16 @@ func resourceClusterRead(d *schema.ResourceData, m interface{}) error { func resourceClusterUpdate(d *schema.ResourceData, m interface{}) error { if d.HasChange("white_list_node_cidr") || d.HasChange("version") { - return changeWhiteListNodeOrVersion(d, m) + err := changeWhiteListNodeOrVersion(d, m) + if err != nil { + return err + } } if d.HasChange("node_group") { - return changeNodeGroup(d, m) + err := changeNodeGroup(d, m) + if err != nil { + return err + } } return resourceClusterRead(d, m) } @@ -412,7 +418,13 @@ func changeNodeGroup(d *schema.ResourceData, m interface{}) error { } autoScaleConfig := getAutoScaleConfig(nodeGroup["auto_scale_config"].([]interface{})) upgradeConfig := getUpgradeConfig(nodeGroup["upgrade_config"].([]interface{})) - numNodes := int32(nodeGroup["num_nodes"].(int)) + var numNodes *int32 + if v, ok := d.GetOk("num_nodes"); ok { + num := int32(v.(int)) + if num > 0 { + numNodes = &num + } + } imageId := nodeGroup["image_id"].(string) updateNodeGroupRequest := vks.UpdateNodeGroupDto{ AutoScaleConfig: autoScaleConfig, diff --git a/resource/vks/resrouce_cluster_node_group.go b/resource/vks/resrouce_cluster_node_group.go index 3d833ba..1c2b0c5 100644 --- a/resource/vks/resrouce_cluster_node_group.go +++ b/resource/vks/resrouce_cluster_node_group.go @@ -475,7 +475,13 @@ func resourceClusterNodeGroupUpdate(d *schema.ResourceData, m interface{}) error } autoScaleConfig := getAutoScaleConfig(d.Get("auto_scale_config").([]interface{})) upgradeConfig := getUpgradeConfig(d.Get("upgrade_config").([]interface{})) - numNodes := int32(d.Get("num_nodes").(int)) + var numNodes *int32 + if v, ok := d.GetOk("num_nodes"); ok { + num := int32(v.(int)) + if num > 0 { + numNodes = &num + } + } imageId := d.Get("image_id").(string) updateNodeGroupRequest := vks.UpdateNodeGroupDto{ AutoScaleConfig: autoScaleConfig, From f76af8c5124287b00efec4df0e12ac5d07d7f2c3 Mon Sep 17 00:00:00 2001 From: tunm4 <8-tunm4_2@users.noreply.git.vngcloud.dev> Date: Fri, 31 May 2024 21:30:59 +0700 Subject: [PATCH 09/14] update --- resource/vks/resource_cluster.go | 54 +++++++--- resource/vks/resrouce_cluster_node_group.go | 104 +++++++++++++++----- 2 files changed, 120 insertions(+), 38 deletions(-) diff --git a/resource/vks/resource_cluster.go b/resource/vks/resource_cluster.go index 8acef09..091447d 100644 --- a/resource/vks/resource_cluster.go +++ b/resource/vks/resource_cluster.go @@ -149,15 +149,7 @@ func resourceClusterStateRefreshFunc(cli *client.Client, clusterID string) resou } } func resourceClusterCreate(d *schema.ResourceData, m interface{}) error { - nodeGroupsJson, _ := json.Marshal(d.Get("node_group").([]interface{})) - log.Printf("xxxxx-------------------------------------\n") - log.Printf("%s\n", string(nodeGroupsJson)) - log.Printf("-------------------------------------\n") createNodeGroupRequests := expandNodeGroupForCreating(d.Get("node_group").([]interface{})) - nodeGroupsJson, _ = json.Marshal(createNodeGroupRequests) - log.Printf("------------------node_group_request-------------------\n") - log.Printf("%s\n", string(nodeGroupsJson)) - log.Printf("-------------------------------------\n") createClusterRequest := vks.CreateClusterComboDto{ Name: d.Get("name").(string), Description: d.Get("description").(string), @@ -252,9 +244,9 @@ func updateNodeGroupData(cli *client.Client, d *schema.ResourceData, clusterId s nodeGroup["upgrade_config"] = upgradeConfig nodeGroup["node_group_id"] = clusterNodeGroupDetail.Id } - if nodeGroup["num_nodes"] != nil && int32(nodeGroup["num_nodes"].(int)) != 0 { - nodeGroup["num_nodes"] = clusterNodeGroup.NumNodes - } + //if nodeGroup["num_nodes"] != nil && int32(nodeGroup["num_nodes"].(int)) != -1 { + // nodeGroup["num_nodes"] = clusterNodeGroup.NumNodes + //} updatedNodeGroups[i] = nodeGroup } @@ -341,6 +333,12 @@ func resourceClusterRead(d *schema.ResourceData, m interface{}) error { } func resourceClusterUpdate(d *schema.ResourceData, m interface{}) error { + if d.HasChange("node_group") { + err := checkRequestNodeGroup(d) + if err != nil { + return err + } + } if d.HasChange("white_list_node_cidr") || d.HasChange("version") { err := changeWhiteListNodeOrVersion(d, m) if err != nil { @@ -356,6 +354,34 @@ func resourceClusterUpdate(d *schema.ResourceData, m interface{}) error { return resourceClusterRead(d, m) } +func checkRequestNodeGroup(d *schema.ResourceData) error { + nodeGroups := d.Get("node_group").([]interface{}) + for _, ng := range nodeGroups { + nodeGroup := ng.(map[string]interface{}) + autoScaleConfig := getAutoScaleConfig(nodeGroup["auto_scale_config"].([]interface{})) + var numNodes *int32 + if value, ok := nodeGroup["num_nodes"]; ok { + num := int32(value.(int)) + if num != -1 { + numNodes = &num + } + } + var err error + if autoScaleConfig != nil && numNodes != nil { + err = fmt.Errorf("If auto_scale_config is set then num_nodes must be -1\n") + } + if autoScaleConfig == nil && numNodes == nil { + err = fmt.Errorf("If auto_scale_config is not set then num_nodes must be different from -1\n") + } + if err != nil { + oldNodeGroup, _ := d.GetChange("node_group") + d.Set("node_group", oldNodeGroup) + return err + } + } + return nil +} + func changeWhiteListNodeOrVersion(d *schema.ResourceData, m interface{}) error { whiteListCIDRsInterface := d.Get("white_list_node_cidr").([]interface{}) var whiteListCIDR []string @@ -419,9 +445,9 @@ func changeNodeGroup(d *schema.ResourceData, m interface{}) error { autoScaleConfig := getAutoScaleConfig(nodeGroup["auto_scale_config"].([]interface{})) upgradeConfig := getUpgradeConfig(nodeGroup["upgrade_config"].([]interface{})) var numNodes *int32 - if v, ok := d.GetOk("num_nodes"); ok { - num := int32(v.(int)) - if num > 0 { + if value, ok := nodeGroup["num_nodes"]; ok { + num := int32(value.(int)) + if num != -1 { numNodes = &num } } diff --git a/resource/vks/resrouce_cluster_node_group.go b/resource/vks/resrouce_cluster_node_group.go index 1c2b0c5..f7a956c 100644 --- a/resource/vks/resrouce_cluster_node_group.go +++ b/resource/vks/resrouce_cluster_node_group.go @@ -73,8 +73,9 @@ var schemaNodeGroup = map[string]*schema.Schema{ ForceNew: true, }, "num_nodes": { - Type: schema.TypeInt, - Optional: true, + Type: schema.TypeInt, + Optional: true, + ValidateFunc: validation.IntAtLeast(-1), }, "initial_node_count": { Type: schema.TypeInt, @@ -350,7 +351,7 @@ func resourceClusterNodeGroupRead(d *schema.ResourceData, m interface{}) error { } else { d.Set("auto_scale_config", nil) } - if d.Get("num_nodes") != nil && int32(d.Get("num_nodes").(int)) != 0 { + if d.Get("num_nodes") != nil && int32(d.Get("num_nodes").(int)) != -1 { d.Set("num_nodes", resp.NumNodes) } d.Set("image_id", resp.ImageId) @@ -370,6 +371,59 @@ func resourceClusterNodeGroupRead(d *schema.ResourceData, m interface{}) error { return nil } +func resourceClusterNodeGroupReadForCreate(d *schema.ResourceData, m interface{}) error { + clusterID := d.Get("cluster_id").(string) + cli := m.(*client.Client) + resp, httpResponse, _ := cli.VksClient.V1NodeGroupControllerApi.V1ClustersClusterIdNodeGroupsNodeGroupIdGet(context.TODO(), clusterID, d.Id(), nil) + if httpResponse.StatusCode == http.StatusNotFound { + d.SetId("") + return nil + } + if CheckErrorResponse(httpResponse) { + responseBody := GetResponseBody(httpResponse) + errorResponse := fmt.Errorf("request fail with errMsg : %s", responseBody) + return errorResponse + } + respJSON, _ := json.Marshal(resp) + log.Printf("-------------------------------------\n") + log.Printf("%s\n", string(respJSON)) + log.Printf("-------------------------------------\n") + upgradeConfig := []interface{}{ + map[string]interface{}{ + "strategy": resp.UpgradeConfig.Strategy, + "max_surge": resp.UpgradeConfig.MaxSurge, + "max_unavailable": resp.UpgradeConfig.MaxUnavailable, + }, + } + d.Set("upgrade_config", upgradeConfig) + if resp.AutoScaleConfig != nil { + autoScaleConfig := []interface{}{ + map[string]interface{}{ + "min_size": resp.AutoScaleConfig.MinSize, + "max_size": resp.AutoScaleConfig.MaxSize, + }, + } + d.Set("auto_scale_config", autoScaleConfig) + } else { + d.Set("auto_scale_config", nil) + } + d.Set("image_id", resp.ImageId) + if !checkSecurityGroupsSame(d, resp) { + d.Set("security_groups", resp.SecurityGroups) + } + d.Set("disk_size", resp.DiskSize) + d.Set("disk_type", resp.DiskType) + d.Set("enable_private_nodes", resp.EnablePrivateNodes) + d.Set("flavor_id", resp.FlavorId) + if d.Get("initial_node_count") == nil { + d.Set("initial_node_count", resp.NumNodes) + } + d.Set("name", resp.Name) + d.Set("ssh_key_id", resp.SshKeyId) + + return nil +} + func resourceClusterNodeGroupCreate(d *schema.ResourceData, m interface{}) error { createNodeGroupRequest := getCreateNodeGroupRequest(d) @@ -401,24 +455,8 @@ func resourceClusterNodeGroupCreate(d *schema.ResourceData, m interface{}) error if err != nil { return fmt.Errorf("error waiting for create cluster node group (%s) %s", resp.Id, err) } - //upgradeConfig := d.Get("upgrade_config").([]interface{}) - //if len(upgradeConfig) == 0 { - // clusterNodeGroupDetail, httpResponse, _ := cli.VksClient.V1NodeGroupControllerApi.V1ClustersClusterIdNodeGroupsNodeGroupIdGet(context.TODO(), clusterId, clusterNodeGroup.Id, nil) - // if httpResponse.StatusCode != http.StatusOK { - // return fmt.Errorf("Error : %s", GetResponseBody(httpResponse)) - // } - // upgradeConfig := []interface{}{ - // map[string]interface{}{ - // "strategy": clusterNodeGroupDetail.UpgradeConfig.Strategy, - // "max_surge": clusterNodeGroupDetail.UpgradeConfig.MaxSurge, - // "max_unavailable": clusterNodeGroupDetail.UpgradeConfig.MaxUnavailable, - // }, - // } - // d.Set("upgrade_config", upgradeConfig) - //} d.SetId(resp.Id) - - return resourceClusterNodeGroupRead(d, m) + return resourceClusterNodeGroupReadForCreate(d, m) } func getCreateNodeGroupRequest(d *schema.ResourceData) vks.CreateNodeGroupDto { @@ -476,12 +514,30 @@ func resourceClusterNodeGroupUpdate(d *schema.ResourceData, m interface{}) error autoScaleConfig := getAutoScaleConfig(d.Get("auto_scale_config").([]interface{})) upgradeConfig := getUpgradeConfig(d.Get("upgrade_config").([]interface{})) var numNodes *int32 - if v, ok := d.GetOk("num_nodes"); ok { - num := int32(v.(int)) - if num > 0 { + if value, ok := d.GetOkExists("num_nodes"); ok { + num := int32(value.(int)) + if num != -1 { numNodes = &num } } + var err error + if autoScaleConfig != nil && numNodes != nil { + err = fmt.Errorf("If auto_scale_config is set then num_nodes must be -1\n") + } + if autoScaleConfig == nil && numNodes == nil { + err = fmt.Errorf("If auto_scale_config is not set then num_nodes must be different from -1\n") + } + if err != nil { + if d.HasChange("auto_scale_config") { + oldAutoScaleConfig, _ := d.GetChange("auto_scale_config") + d.Set("auto_scale_config", oldAutoScaleConfig) + } + if d.HasChange("num_nodes") { + oldNumNodes, _ := d.GetChange("num_nodes") + d.Set("num_nodes", oldNumNodes) + } + return err + } imageId := d.Get("image_id").(string) updateNodeGroupRequest := vks.UpdateNodeGroupDto{ AutoScaleConfig: autoScaleConfig, @@ -512,7 +568,7 @@ func resourceClusterNodeGroupUpdate(d *schema.ResourceData, m interface{}) error Delay: 10 * time.Second, MinTimeout: 1 * time.Second, } - _, err := stateConf.WaitForState() + _, err = stateConf.WaitForState() if err != nil { return fmt.Errorf("error waiting for update cluster node group (%s) %s", resp.Id, err) } From c806832a871850482060abfbb7954fa3b9f243a7 Mon Sep 17 00:00:00 2001 From: tunm4 <8-tunm4_2@users.noreply.git.vngcloud.dev> Date: Sun, 2 Jun 2024 14:53:19 +0700 Subject: [PATCH 10/14] update --- docs/resources/vks_cluster.md | 1391 +------------------ docs/resources/vks_cluster_node_group.md | 361 +---- resource/vks/resource_cluster.go | 21 +- resource/vks/resrouce_cluster_node_group.go | 128 +- 4 files changed, 160 insertions(+), 1741 deletions(-) diff --git a/docs/resources/vks_cluster.md b/docs/resources/vks_cluster.md index d5f7140..484aecb 100644 --- a/docs/resources/vks_cluster.md +++ b/docs/resources/vks_cluster.md @@ -1,29 +1,23 @@ --- subcategory: "Kubernetes Service" description: |- - Creates a VNGCloud Kubernetes Service (VKS) cluster. + Creates a Cluster on VNGCloud Kubernetes Service (VKS). --- # vngcloud_vks_cluster -Manages a Google Kubernetes Engine (GKE) cluster. +Manages a VNGCloud Kubernetes Engine (VKS) cluster. + +To get more information about VKS clusters, see: -To get more information about GKE clusters, see: -* [The API reference](https://cloud.google.com/kubernetes-engine/docs/reference/rest/v1beta1/projects.locations.clusters) * How-to guides - * [GKE overview](https://cloud.google.com/kubernetes-engine/docs/concepts/kubernetes-engine-overview) - * [About cluster configuration choices](https://cloud.google.com/kubernetes-engine/docs/concepts/types-of-clusters) + * [VKS overview](https://docs.vngcloud.vn/vng-cloud-document/v/vn/vks/vks-la-gi) + * [Getting Start with VKS](https://docs.vngcloud.vn/vng-cloud-document/v/vn/vks/bat-dau-voi-vks) * Terraform guidance - * [Using GKE with Terraform](/docs/providers/google/guides/using_gke_with_terraform.html) - * [Provision a GKE Cluster (Google Cloud) Learn tutorial](https://learn.hashicorp.com/tutorials/terraform/gke?in=terraform/kubernetes&utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) - --> On version 5.0.0+ of the provider, you must explicitly set `deletion_protection = false` -and run `terraform apply` to write the field to state in order to destroy a cluster. + * [Using VKS with Terraform](https://docs.vngcloud.vn/vng-cloud-document/v/vn/vks/su-dung-vks-voi-terraform) -~> All arguments and attributes (including certificate outputs) will be stored in the raw state as -plaintext. [Read more about sensitive data in state](https://www.terraform.io/language/state/sensitive-data). - -## Example Usage - with a separately managed node pool (recommended) +--- +## Example Usage - with a separately managed node group (recommended) ```hcl resource "vngcloud_vks_cluster" "primary" { @@ -40,11 +34,10 @@ resource "vngcloud_vks_cluster_node_group" "primary" { } ``` -~> **Note:** It is recommended that node pools be created and managed as separate resources as in the example above. -This allows node pools to be added and removed without recreating the cluster. Node pools defined directly in the -`google_container_cluster` resource cannot be removed without re-creating the cluster. +**Important Note**: We are recommend you to create and manage node groups as separate resources, like in this example. This allows you to add or remove node groups without needing to recreate the entire cluster. +If you define node groups directly within the vngcloud_vks_cluster resource, you cannot remove them without recreating the cluster itself. -## Example Usage - with the default node pool +## Example Usage - with the default node group ```hcl resource "vngcloud_vks_cluster" "primary" { @@ -58,1352 +51,20 @@ resource "vngcloud_vks_cluster" "primary" { } } ``` - +--- ## Argument Reference -* `name` - (Required) The name of the cluster, unique within the project and - location. - -- - - - -* `location` - (Optional) The location (region or zone) in which the cluster - master will be created, as well as the default node location. If you specify a - zone (such as `us-central1-a`), the cluster will be a zonal cluster with a - single cluster master. If you specify a region (such as `us-west1`), the - cluster will be a regional cluster with multiple masters spread across zones in - the region, and with default node locations in those zones as well - -* `node_locations` - (Optional) The list of zones in which the cluster's nodes - are located. Nodes must be in the region of their regional cluster or in the - same region as their cluster's zone for zonal clusters. If this is specified for - a zonal cluster, omit the cluster's zone. - --> A "multi-zonal" cluster is a zonal cluster with at least one additional zone -defined; in a multi-zonal cluster, the cluster master is only present in a -single zone while nodes are present in each of the primary zone and the node -locations. In contrast, in a regional cluster, cluster master nodes are present -in multiple zones in the region. For that reason, regional clusters should be -preferred. - -* `deletion_protection` - (Optional) Whether or not to allow Terraform to destroy - the cluster. Unless this field is set to false in Terraform state, a - `terraform destroy` or `terraform apply` that would delete the cluster will fail. - -* `addons_config` - (Optional) The configuration for addons supported by GKE. - Structure is [documented below](#nested_addons_config). - -* `allow_net_admin` - (Optional) Enable NET_ADMIN for the cluster. Defaults to - `false`. This field should only be enabled for Autopilot clusters (`enable_autopilot` - set to `true`). - -* `cluster_ipv4_cidr` - (Optional) The IP address range of the Kubernetes pods - in this cluster in CIDR notation (e.g. `10.96.0.0/14`). Leave blank to have one - automatically chosen or specify a `/14` block in `10.0.0.0/8`. This field will - default a new cluster to routes-based, where `ip_allocation_policy` is not defined. - -* `cluster_autoscaling` - (Optional) - Per-cluster configuration of Node Auto-Provisioning with Cluster Autoscaler to - automatically adjust the size of the cluster and create/delete node pools based - on the current needs of the cluster's workload. See the - [guide to using Node Auto-Provisioning](https://cloud.google.com/kubernetes-engine/docs/how-to/node-auto-provisioning) - for more details. Structure is [documented below](#nested_cluster_autoscaling). - -* `binary_authorization` - (Optional) Configuration options for the Binary - Authorization feature. Structure is [documented below](#nested_binary_authorization). - -* `service_external_ips_config` - (Optional) - Structure is [documented below](#nested_service_external_ips_config). - -* `mesh_certificates` - (Optional) - Structure is [documented below](#nested_mesh_encryption). - -* `database_encryption` - (Optional) - Structure is [documented below](#nested_database_encryption). - -* `description` - (Optional) Description of the cluster. - -* `default_max_pods_per_node` - (Optional) The default maximum number of pods - per node in this cluster. This doesn't work on "routes-based" clusters, clusters - that don't have IP Aliasing enabled. See the [official documentation](https://cloud.google.com/kubernetes-engine/docs/how-to/flexible-pod-cidr) - for more information. - -* `enable_kubernetes_alpha` - (Optional) Whether to enable Kubernetes Alpha features for - this cluster. Note that when this option is enabled, the cluster cannot be upgraded - and will be automatically deleted after 30 days. - -* `enable_k8s_beta_apis` - (Optional) Configuration for Kubernetes Beta APIs. - Structure is [documented below](#nested_enable_k8s_beta_apis). - -* `enable_tpu` - (Optional) Whether to enable Cloud TPU resources in this cluster. - See the [official documentation](https://cloud.google.com/tpu/docs/kubernetes-engine-setup). - -* `enable_legacy_abac` - (Optional) Whether the ABAC authorizer is enabled for this cluster. - When enabled, identities in the system, including service accounts, nodes, and controllers, - will have statically granted permissions beyond those provided by the RBAC configuration or IAM. - Defaults to `false` - -* `enable_shielded_nodes` - (Optional) Enable Shielded Nodes features on all nodes in this cluster. Defaults to `true`. - -* `enable_autopilot` - (Optional) Enable Autopilot for this cluster. Defaults to `false`. - Note that when this option is enabled, certain features of Standard GKE are not available. - See the [official documentation](https://cloud.google.com/kubernetes-engine/docs/concepts/autopilot-overview#comparison) - for available features. - -* `initial_node_count` - (Optional) The number of nodes to create in this - cluster's default node pool. In regional or multi-zonal clusters, this is the - number of nodes per zone. Must be set if `node_pool` is not set. If you're using - `google_container_node_pool` objects with no default node pool, you'll need to - set this to a value of at least `1`, alongside setting - `remove_default_node_pool` to `true`. - -* `ip_allocation_policy` - (Optional) Configuration of cluster IP allocation for - VPC-native clusters. If this block is unset during creation, it will be set by the GKE backend. - Structure is [documented below](#nested_ip_allocation_policy). - -* `networking_mode` - (Optional) Determines whether alias IPs or routes will be used for pod IPs in the cluster. - Options are `VPC_NATIVE` or `ROUTES`. `VPC_NATIVE` enables [IP aliasing](https://cloud.google.com/kubernetes-engine/docs/how-to/ip-aliases). Newly created clusters will default to `VPC_NATIVE`. - -* `logging_config` - (Optional) Logging configuration for the cluster. - Structure is [documented below](#nested_logging_config). - -* `logging_service` - (Optional) The logging service that the cluster should - write logs to. Available options include `logging.googleapis.com`(Legacy Stackdriver), - `logging.googleapis.com/kubernetes`(Stackdriver Kubernetes Engine Logging), and `none`. Defaults to `logging.googleapis.com/kubernetes` - -* `maintenance_policy` - (Optional) The maintenance policy to use for the cluster. Structure is - [documented below](#nested_maintenance_policy). - -* `master_auth` - (Optional) The authentication information for accessing the - Kubernetes master. Some values in this block are only returned by the API if - your service account has permission to get credentials for your GKE cluster. If - you see an unexpected diff unsetting your client cert, ensure you have the - `container.clusters.getCredentials` permission. - Structure is [documented below](#nested_master_auth). - -* `master_authorized_networks_config` - (Optional) The desired - configuration options for master authorized networks. Omit the - nested `cidr_blocks` attribute to disallow external access (except - the cluster node IPs, which GKE automatically whitelists). - Structure is [documented below](#nested_master_authorized_networks_config). - -* `min_master_version` - (Optional) The minimum version of the master. GKE - will auto-update the master to new versions, so this does not guarantee the - current master version--use the read-only `master_version` field to obtain that. - If unset, the cluster's version will be set by GKE to the version of the most recent - official release (which is not necessarily the latest version). Most users will find - the `google_container_engine_versions` data source useful - it indicates which versions - are available, and can be use to approximate fuzzy versions in a - Terraform-compatible way. If you intend to specify versions manually, - [the docs](https://cloud.google.com/kubernetes-engine/versioning-and-upgrades#specifying_cluster_version) - describe the various acceptable formats for this field. - --> If you are using the `google_container_engine_versions` datasource with a regional cluster, ensure that you have provided a `location` -to the datasource. A region can have a different set of supported versions than its corresponding zones, and not all zones in a -region are guaranteed to support the same version. - -* `monitoring_config` - (Optional) Monitoring configuration for the cluster. - Structure is [documented below](#nested_monitoring_config). - -* `monitoring_service` - (Optional) The monitoring service that the cluster - should write metrics to. - Automatically send metrics from pods in the cluster to the Google Cloud Monitoring API. - VM metrics will be collected by Google Compute Engine regardless of this setting - Available options include - `monitoring.googleapis.com`(Legacy Stackdriver), `monitoring.googleapis.com/kubernetes`(Stackdriver Kubernetes Engine Monitoring), and `none`. - Defaults to `monitoring.googleapis.com/kubernetes` - -* `network` - (Optional) The name or self_link of the Google Compute Engine - network to which the cluster is connected. For Shared VPC, set this to the self link of the - shared network. - -* `network_policy` - (Optional) Configuration options for the - [NetworkPolicy](https://kubernetes.io/docs/concepts/services-networking/networkpolicies/) - feature. Structure is [documented below](#nested_network_policy). - -* `node_config` - (Optional) Parameters used in creating the default node pool. - Generally, this field should not be used at the same time as a - `google_container_node_pool` or a `node_pool` block; this configuration - manages the default node pool, which isn't recommended to be used with - Terraform. Structure is [documented below](#nested_node_config). - -* `node_pool` - (Optional) List of node pools associated with this cluster. - See [google_container_node_pool](container_node_pool.html) for schema. - **Warning:** node pools defined inside a cluster can't be changed (or added/removed) after - cluster creation without deleting and recreating the entire cluster. Unless you absolutely need the ability - to say "these are the _only_ node pools associated with this cluster", use the - [google_container_node_pool](container_node_pool.html) resource instead of this property. - -* `node_pool_auto_config` - (Optional) Node pool configs that apply to auto-provisioned node pools in - [autopilot](https://cloud.google.com/kubernetes-engine/docs/concepts/autopilot-overview#comparison) clusters and - [node auto-provisioning](https://cloud.google.com/kubernetes-engine/docs/how-to/node-auto-provisioning)-enabled clusters. Structure is [documented below](#nested_node_pool_auto_config). - -* `node_pool_defaults` - (Optional) Default NodePool settings for the entire cluster. These settings are overridden if specified on the specific NodePool object. Structure is [documented below](#nested_node_pool_defaults). - -* `node_version` - (Optional) The Kubernetes version on the nodes. Must either be unset - or set to the same value as `min_master_version` on create. Defaults to the default - version set by GKE which is not necessarily the latest version. This only affects - nodes in the default node pool. While a fuzzy version can be specified, it's - recommended that you specify explicit versions as Terraform will see spurious diffs - when fuzzy versions are used. See the `google_container_engine_versions` data source's - `version_prefix` field to approximate fuzzy versions in a Terraform-compatible way. - To update nodes in other node pools, use the `version` attribute on the node pool. - -* `notification_config` - (Optional) Configuration for the [cluster upgrade notifications](https://cloud.google.com/kubernetes-engine/docs/how-to/cluster-upgrade-notifications) feature. Structure is [documented below](#nested_notification_config). - -* `confidential_nodes` - Configuration for [Confidential Nodes](https://cloud.google.com/kubernetes-engine/docs/how-to/confidential-gke-nodes) feature. Structure is documented below [documented below](#nested_confidential_nodes). - -* `pod_security_policy_config` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) Configuration for the - [PodSecurityPolicy](https://cloud.google.com/kubernetes-engine/docs/how-to/pod-security-policies) feature. - Structure is [documented below](#nested_pod_security_policy_config). - -* `authenticator_groups_config` - (Optional) Configuration for the - [Google Groups for GKE](https://cloud.google.com/kubernetes-engine/docs/how-to/role-based-access-control#groups-setup-gsuite) feature. - Structure is [documented below](#nested_authenticator_groups_config). - -* `private_cluster_config` - (Optional) Configuration for [private clusters](https://cloud.google.com/kubernetes-engine/docs/how-to/private-clusters), - clusters with private nodes. Structure is [documented below](#nested_private_cluster_config). - -* `cluster_telemetry` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) Configuration for - [ClusterTelemetry](https://cloud.google.com/monitoring/kubernetes-engine/installing#controlling_the_collection_of_application_logs) feature, - Structure is [documented below](#nested_cluster_telemetry). - -* `project` - (Optional) The ID of the project in which the resource belongs. If it - is not provided, the provider project is used. - -* `release_channel` - (Optional) - Configuration options for the [Release channel](https://cloud.google.com/kubernetes-engine/docs/concepts/release-channels) - feature, which provide more control over automatic upgrades of your GKE clusters. - When updating this field, GKE imposes specific version requirements. See - [Selecting a new release channel](https://cloud.google.com/kubernetes-engine/docs/concepts/release-channels#selecting_a_new_release_channel) - for more details; the `google_container_engine_versions` datasource can provide - the default version for a channel. Note that removing the `release_channel` - field from your config will cause Terraform to stop managing your cluster's - release channel, but will not unenroll it. Instead, use the `"UNSPECIFIED"` - channel. Structure is [documented below](#nested_release_channel). - -* `remove_default_node_pool` - (Optional) If `true`, deletes the default node - pool upon cluster creation. If you're using `google_container_node_pool` - resources with no default node pool, this should be set to `true`, alongside - setting `initial_node_count` to at least `1`. - -* `resource_labels` - (Optional) The GCE resource labels (a map of key/value pairs) to be applied to the cluster. - -* `cost_management_config` - (Optional) Configuration for the - [Cost Allocation](https://cloud.google.com/kubernetes-engine/docs/how-to/cost-allocations) feature. - Structure is [documented below](#nested_cost_management_config). - -* `resource_usage_export_config` - (Optional) Configuration for the - [ResourceUsageExportConfig](https://cloud.google.com/kubernetes-engine/docs/how-to/cluster-usage-metering) feature. - Structure is [documented below](#nested_resource_usage_export_config). - -* `subnetwork` - (Optional) The name or self_link of the Google Compute Engine - subnetwork in which the cluster's instances are launched. - -* `vertical_pod_autoscaling` - (Optional) - Vertical Pod Autoscaling automatically adjusts the resources of pods controlled by it. - Structure is [documented below](#nested_vertical_pod_autoscaling). - -* `workload_identity_config` - (Optional) - Workload Identity allows Kubernetes service accounts to act as a user-managed - [Google IAM Service Account](https://cloud.google.com/iam/docs/service-accounts#user-managed_service_accounts). - Structure is [documented below](#nested_workload_identity_config). - -* `identity_service_config` - (Optional). Structure is [documented below](#nested_identity_service_config). - -* `enable_intranode_visibility` - (Optional) - Whether Intra-node visibility is enabled for this cluster. This makes same node pod to pod traffic visible for VPC network. - -* `enable_l4_ilb_subsetting` - (Optional) - Whether L4ILB Subsetting is enabled for this cluster. - -* `enable_multi_networking` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) - Whether multi-networking is enabled for this cluster. - -* `enable_fqdn_network_policy` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) - Whether FQDN Network Policy is enabled on this cluster. Users who enable this feature for existing Standard clusters must restart the GKE Dataplane V2 `anetd` DaemonSet after enabling it. See the [Enable FQDN Network Policy in an existing cluster](https://cloud.google.com/kubernetes-engine/docs/how-to/fqdn-network-policies#enable_fqdn_network_policy_in_an_existing_cluster) for more information. - -* `private_ipv6_google_access` - (Optional) - The desired state of IPv6 connectivity to Google Services. By default, no private IPv6 access to or from Google Services (all access will be via IPv4). - -* `datapath_provider` - (Optional) - The desired datapath provider for this cluster. This is set to `LEGACY_DATAPATH` by default, which uses the IPTables-based kube-proxy implementation. Set to `ADVANCED_DATAPATH` to enable Dataplane v2. - -* `enable_cilium_clusterwide_network_policy` - (Optional) - Whether CiliumClusterWideNetworkPolicy is enabled on this cluster. Defaults to false. - -* `default_snat_status` - (Optional) - [GKE SNAT](https://cloud.google.com/kubernetes-engine/docs/how-to/ip-masquerade-agent#how_ipmasq_works) DefaultSnatStatus contains the desired state of whether default sNAT should be disabled on the cluster, [API doc](https://cloud.google.com/kubernetes-engine/docs/reference/rest/v1beta1/projects.locations.clusters#networkconfig). Structure is [documented below](#nested_default_snat_status) - -* `dns_config` - (Optional) - Configuration for [Using Cloud DNS for GKE](https://cloud.google.com/kubernetes-engine/docs/how-to/cloud-dns). Structure is [documented below](#nested_dns_config). - -* `gateway_api_config` - (Optional) - Configuration for [GKE Gateway API controller](https://cloud.google.com/kubernetes-engine/docs/concepts/gateway-api). Structure is [documented below](#nested_gateway_api_config). - -* `protect_config` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) - Enable/Disable Protect API features for the cluster. Structure is [documented below](#nested_protect_config). - -* `security_posture_config` - (Optional) - Enable/Disable Security Posture API features for the cluster. Structure is [documented below](#nested_security_posture_config). - -* `fleet` - (Optional) - Fleet configuration for the cluster. Structure is [documented below](#nested_fleet). - -* `workload_alts_config` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) - Configuration for [direct-path (via ALTS) with workload identity.](https://cloud.google.com/kubernetes-engine/docs/reference/rest/v1beta1/projects.locations.clusters#workloadaltsconfig). Structure is [documented below](#nested_workload_alts_config). - -The `default_snat_status` block supports - -* `disabled` - (Required) Whether the cluster disables default in-node sNAT rules. In-node sNAT rules will be disabled when defaultSnatStatus is disabled.When disabled is set to false, default IP masquerade rules will be applied to the nodes to prevent sNAT on cluster internal traffic - -The `cluster_telemetry` block supports -* `type` - Telemetry integration for the cluster. Supported values (`ENABLED, DISABLED, SYSTEM_ONLY`); - `SYSTEM_ONLY` (Only system components are monitored and logged) is only available in GKE versions 1.15 and later. - -The `addons_config` block supports: - -* `horizontal_pod_autoscaling` - (Optional) The status of the Horizontal Pod Autoscaling - addon, which increases or decreases the number of replica pods a replication controller - has based on the resource usage of the existing pods. - It is enabled by default; - set `disabled = true` to disable. - -* `http_load_balancing` - (Optional) The status of the HTTP (L7) load balancing - controller addon, which makes it easy to set up HTTP load balancers for services in a - cluster. It is enabled by default; set `disabled = true` to disable. - -* `network_policy_config` - (Optional) Whether we should enable the network policy addon - for the master. This must be enabled in order to enable network policy for the nodes. - To enable this, you must also define a [`network_policy`](#network_policy) block, - otherwise nothing will happen. - It can only be disabled if the nodes already do not have network policies enabled. - Defaults to disabled; set `disabled = false` to enable. - -* `gcp_filestore_csi_driver_config` - (Optional) The status of the Filestore CSI driver addon, - which allows the usage of filestore instance as volumes. - It is disabled by default; set `enabled = true` to enable. - -* `gcs_fuse_csi_driver_config` - (Optional) The status of the GCSFuse CSI driver addon, - which allows the usage of a gcs bucket as volumes. - It is disabled by default for Standard clusters; set `enabled = true` to enable. - It is enabled by default for Autopilot clusters with version 1.24 or later; set `enabled = true` to enable it explicitly. - See [Enable the Cloud Storage FUSE CSI driver](https://cloud.google.com/kubernetes-engine/docs/how-to/persistent-volumes/cloud-storage-fuse-csi-driver#enable) for more information. - -* `cloudrun_config` - (Optional). Structure is [documented below](#nested_cloudrun_config). - -* `istio_config` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)). - Structure is [documented below](#nested_istio_config). - -* `dns_cache_config` - (Optional). - The status of the NodeLocal DNSCache addon. It is disabled by default. - Set `enabled = true` to enable. - - **Enabling/Disabling NodeLocal DNSCache in an existing cluster is a disruptive operation. - All cluster nodes running GKE 1.15 and higher are recreated.** - -* `gce_persistent_disk_csi_driver_config` - (Optional). - Whether this cluster should enable the Google Compute Engine Persistent Disk Container Storage Interface (CSI) Driver. Set `enabled = true` to enable. - - **Note:** The Compute Engine persistent disk CSI Driver is enabled by default on newly created clusters for the following versions: Linux clusters: GKE version 1.18.10-gke.2100 or later, or 1.19.3-gke.2100 or later. - -* `gke_backup_agent_config` - (Optional). - The status of the Backup for GKE agent addon. It is disabled by default; Set `enabled = true` to enable. - -* `kalm_config` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)). - Configuration for the KALM addon, which manages the lifecycle of k8s. It is disabled by default; Set `enabled = true` to enable. - -* `config_connector_config` - (Optional). - The status of the ConfigConnector addon. It is disabled by default; Set `enabled = true` to enable. - -* `stateful_ha_config` - (Optional). - The status of the Stateful HA addon, which provides automatic configurable failover for stateful applications. - It is disabled by default for Standard clusters. Set `enabled = true` to enable. - -This example `addons_config` disables two addons: - -```hcl -addons_config { - http_load_balancing { - disabled = true - } - - horizontal_pod_autoscaling { - disabled = true - } -} -``` -The `binary_authorization` block supports: - -* `enabled` - (DEPRECATED) Enable Binary Authorization for this cluster. Deprecated in favor of `evaluation_mode`. - -* `evaluation_mode` - (Optional) Mode of operation for Binary Authorization policy evaluation. Valid values are `DISABLED` - and `PROJECT_SINGLETON_POLICY_ENFORCE`. - -The `service_external_ips_config` block supports: - -* `enabled` - (Required) Controls whether external ips specified by a service will be allowed. It is enabled by default. - -The `mesh_certificates` block supports: - -* `enable_certificates` - (Required) Controls the issuance of workload mTLS certificates. It is enabled by default. Workload Identity is required, see [workload_config](#nested_workload_identity_config). - -The `database_encryption` block supports: - -* `state` - (Required) `ENCRYPTED` or `DECRYPTED` - -* `key_name` - (Required) the key to use to encrypt/decrypt secrets. See the [DatabaseEncryption definition](https://cloud.google.com/kubernetes-engine/docs/reference/rest/v1beta1/projects.locations.clusters#Cluster.DatabaseEncryption) for more information. - -The `enable_k8s_beta_apis` block supports: - -* `enabled_apis` - (Required) Enabled Kubernetes Beta APIs. To list a Beta API resource, use the representation {group}/{version}/{resource}. The version must be a Beta version. Note that you cannot disable beta APIs that are already enabled on a cluster without recreating it. See the [Configure beta APIs](https://cloud.google.com/kubernetes-engine/docs/how-to/use-beta-apis#configure-beta-apis) for more information. - -The `cloudrun_config` block supports: - -* `disabled` - (Optional) The status of the CloudRun addon. It is disabled by default. Set `disabled=false` to enable. - -* `load_balancer_type` - (Optional) The load balancer type of CloudRun ingress service. It is external load balancer by default. - Set `load_balancer_type=LOAD_BALANCER_TYPE_INTERNAL` to configure it as internal load balancer. - -The `identity_service_config` block supports: - -* `enabled` - (Optional) Whether to enable the Identity Service component. It is disabled by default. Set `enabled=true` to enable. - -The `istio_config` block supports: - -* `disabled` - (Optional) The status of the Istio addon, which makes it easy to set up Istio for services in a - cluster. It is disabled by default. Set `disabled = false` to enable. - -* `auth` - (Optional) The authentication type between services in Istio. Available options include `AUTH_MUTUAL_TLS`. - -The `cluster_autoscaling` block supports: - -* `enabled` - (Optional) Whether node auto-provisioning is enabled. Must be supplied for GKE Standard clusters, `true` is implied - for autopilot clusters. Resource limits for `cpu` and `memory` must be defined to enable node auto-provisioning for GKE Standard. - -* `resource_limits` - (Optional) Global constraints for machine resources in the - cluster. Configuring the `cpu` and `memory` types is required if node - auto-provisioning is enabled. These limits will apply to node pool autoscaling - in addition to node auto-provisioning. Structure is [documented below](#nested_resource_limits). - -* `auto_provisioning_defaults` - (Optional) Contains defaults for a node pool created by NAP. A subset of fields also apply to - GKE Autopilot clusters. - Structure is [documented below](#nested_auto_provisioning_defaults). - -* `autoscaling_profile` - (Optional) Configuration - options for the [Autoscaling profile](https://cloud.google.com/kubernetes-engine/docs/concepts/cluster-autoscaler#autoscaling_profiles) - feature, which lets you choose whether the cluster autoscaler should optimize for resource utilization or resource availability - when deciding to remove nodes from a cluster. Can be `BALANCED` or `OPTIMIZE_UTILIZATION`. Defaults to `BALANCED`. - -The `resource_limits` block supports: - -* `resource_type` - (Required) The type of the resource. For example, `cpu` and - `memory`. See the [guide to using Node Auto-Provisioning](https://cloud.google.com/kubernetes-engine/docs/how-to/node-auto-provisioning) - for a list of types. - -* `minimum` - (Optional) Minimum amount of the resource in the cluster. - -* `maximum` - (Optional) Maximum amount of the resource in the cluster. - -The `auto_provisioning_defaults` block supports: - -* `min_cpu_platform` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) - Minimum CPU platform to be used for NAP created node pools. The instance may be scheduled on the - specified or newer CPU platform. Applicable values are the friendly names of CPU platforms, such - as "Intel Haswell" or "Intel Sandy Bridge". - -* `oauth_scopes` - (Optional) Scopes that are used by NAP and GKE Autopilot when creating node pools. Use the "https://www.googleapis.com/auth/cloud-platform" scope to grant access to all APIs. It is recommended that you set `service_account` to a non-default service account and grant IAM roles to that service account for only the resources that it needs. - --> `monitoring.write` is always enabled regardless of user input. `monitoring` and `logging.write` may also be enabled depending on the values for `monitoring_service` and `logging_service`. - -* `service_account` - (Optional) The Google Cloud Platform Service Account to be used by the node VMs created by GKE Autopilot or NAP. - -* `boot_disk_kms_key` - (Optional) The Customer Managed Encryption Key used to encrypt the boot disk attached to each node in the node pool. This should be of the form projects/[KEY_PROJECT_ID]/locations/[LOCATION]/keyRings/[RING_NAME]/cryptoKeys/[KEY_NAME]. For more information about protecting resources with Cloud KMS Keys please see: https://cloud.google.com/compute/docs/disks/customer-managed-encryption - -* `disk_size` - (Optional) Size of the disk attached to each node, specified in GB. The smallest allowed disk size is 10GB. Defaults to `100` - -* `disk_type` - (Optional) Type of the disk attached to each node (e.g. 'pd-standard', 'pd-ssd' or 'pd-balanced'). Defaults to `pd-standard` - -* `image_type` - (Optional) The default image type used by NAP once a new node pool is being created. Please note that according to the [official documentation](https://cloud.google.com/kubernetes-engine/docs/how-to/node-auto-provisioning#default-image-type) the value must be one of the [COS_CONTAINERD, COS, UBUNTU_CONTAINERD, UBUNTU]. __NOTE__ : COS AND UBUNTU are deprecated as of `GKE 1.24` - -* `shielded_instance_config` - (Optional) Shielded Instance options. Structure is [documented below](#nested_shielded_instance_config). - -* `management` - (Optional) NodeManagement configuration for this NodePool. Structure is [documented below](#nested_management). - -The `management` block supports: - -* `auto_upgrade` - (Optional) Specifies whether node auto-upgrade is enabled for the node pool. If enabled, node auto-upgrade helps keep the nodes in your node pool up to date with the latest release version of Kubernetes. - -* `auto_repair` - (Optional) Specifies whether the node auto-repair is enabled for the node pool. If enabled, the nodes in this node pool will be monitored and, if they fail health checks too many times, an automatic repair action will be triggered. - -This block also contains several computed attributes, documented below. - -* `upgrade_settings` - (Optional) Specifies the upgrade settings for NAP created node pools. Structure is [documented below](#nested_upgrade_settings). - -The `upgrade_settings` block supports: - -* `strategy` - (Optional) Strategy used for node pool update. Strategy can only be one of BLUE_GREEN or SURGE. The default is value is SURGE. - -* `max_surge` - (Optional) The maximum number of nodes that can be created beyond the current size of the node pool during the upgrade process. To be used when strategy is set to SURGE. Default is 0. - -* `max_unavailable` - (Optional) The maximum number of nodes that can be simultaneously unavailable during the upgrade process. To be used when strategy is set to SURGE. Default is 0. - -* `blue_green_settings` - (Optional) Settings for blue-green upgrade strategy. To be specified when strategy is set to BLUE_GREEN. Structure is [documented below](#nested_blue_green_settings). - -The `blue_green_settings` block supports: - -* `node_pool_soak_duration` - (Optional) Time needed after draining entire blue pool. After this period, blue pool will be cleaned up. A duration in seconds with up to nine fractional digits, ending with 's'. Example: "3.5s". - -* `standard_rollout_policy`: (Optional) Standard policy for the blue-green upgrade. To be specified when strategy is set to BLUE_GREEN. Structure is [documented below](#nested_standard_rollout_policy). - -The `standard_rollout_policy` block supports: - -* `batch_percentage`: (Optional) Percentage of the bool pool nodes to drain in a batch. The range of this field should be (0.0, 1.0). Only one of the batch_percentage or batch_node_count can be specified. - -* `batch_node_count` - (Optional) Number of blue nodes to drain in a batch. Only one of the batch_percentage or batch_node_count can be specified. - -* `batch_soak_duration` - (Optional) Soak time after each batch gets drained. A duration in seconds with up to nine fractional digits, ending with 's'. Example: "3.5s".`. - -The `authenticator_groups_config` block supports: - -* `security_group` - (Required) The name of the RBAC security group for use with Google security groups in Kubernetes RBAC. Group name must be in format `gke-security-groups@yourdomain.com`. - -The `logging_config` block supports: - -* `enable_components` - (Required) The GKE components exposing logs. Supported values include: - `SYSTEM_COMPONENTS`, `APISERVER`, `CONTROLLER_MANAGER`, `SCHEDULER`, and `WORKLOADS`. - -The `monitoring_config` block supports: - -* `enable_components` - (Optional) The GKE components exposing metrics. Supported values include: `SYSTEM_COMPONENTS`, `APISERVER`, `SCHEDULER`, `CONTROLLER_MANAGER`, `STORAGE`, `HPA`, `POD`, `DAEMONSET`, `DEPLOYMENT`, `STATEFULSET`, `KUBELET` and `CADVISOR`. In beta provider, `WORKLOADS` is supported on top of those 12 values. (`WORKLOADS` is deprecated and removed in GKE 1.24.) `KUBELET` and `CADVISOR` are only supported in GKE 1.29.3-gke.1093000 and above. - -* `managed_prometheus` - (Optional) Configuration for Managed Service for Prometheus. Structure is [documented below](#nested_managed_prometheus). - -* `advanced_datapath_observability_config` - (Optional) Configuration for Advanced Datapath Monitoring. Structure is [documented below](#nested_advanced_datapath_observability_config). - -The `managed_prometheus` block supports: - -* `enabled` - (Required) Whether or not the managed collection is enabled. - -The `advanced_datapath_observability_config` block supports: - -* `enable_metrics` - (Required) Whether or not to enable advanced datapath metrics. -* `enable_relay` - (Optional) Whether or not Relay is enabled. -* `relay_mode` - (Optional) Mode used to make Relay available. - -The `maintenance_policy` block supports: -* `daily_maintenance_window` - (Optional) structure documented below. -* `recurring_window` - (Optional) structure documented below -* `maintenance_exclusion` - (Optional) structure documented below - -In beta, one or the other of `recurring_window` and `daily_maintenance_window` is required if a `maintenance_policy` block is supplied. - -* `daily_maintenance_window` - Time window specified for daily maintenance operations. - Specify `start_time` in [RFC3339](https://www.ietf.org/rfc/rfc3339.txt) format "HH:MM”, - where HH : \[00-23\] and MM : \[00-59\] GMT. For example: - -Examples: -```hcl -maintenance_policy { - daily_maintenance_window { - start_time = "03:00" - } -} -``` - -* `recurring_window` - Time window for recurring maintenance operations. - -Specify `start_time` and `end_time` in [RFC3339](https://www.ietf.org/rfc/rfc3339.txt) "Zulu" date format. The start time's date is -the initial date that the window starts, and the end time is used for calculating duration. Specify `recurrence` in -[RFC5545](https://tools.ietf.org/html/rfc5545#section-3.8.5.3) RRULE format, to specify when this recurs. -Note that GKE may accept other formats, but will return values in UTC, causing a permanent diff. - -Examples: -``` -maintenance_policy { - recurring_window { - start_time = "2019-08-01T02:00:00Z" - end_time = "2019-08-01T06:00:00Z" - recurrence = "FREQ=DAILY" - } -} -``` - -``` -maintenance_policy { - recurring_window { - start_time = "2019-01-01T09:00:00Z" - end_time = "2019-01-01T17:00:00Z" - recurrence = "FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR" - } -} -``` - -* `maintenance_exclusion` - Exceptions to maintenance window. Non-emergency maintenance should not occur in these windows. A cluster can have up to 20 maintenance exclusions at a time [Maintenance Window and Exclusions](https://cloud.google.com/kubernetes-engine/docs/concepts/maintenance-windows-and-exclusions) - -The `maintenance_exclusion` block supports: -* `exclusion_options` - (Optional) MaintenanceExclusionOptions provides maintenance exclusion related options. - - -The `exclusion_options` block supports: -* `scope` - (Required) The scope of automatic upgrades to restrict in the exclusion window. One of: **NO_UPGRADES | NO_MINOR_UPGRADES | NO_MINOR_OR_NODE_UPGRADES** - -Specify `start_time` and `end_time` in [RFC3339](https://www.ietf.org/rfc/rfc3339.txt) "Zulu" date format. The start time's date is -the initial date that the window starts, and the end time is used for calculating duration.Specify `recurrence` in -[RFC5545](https://tools.ietf.org/html/rfc5545#section-3.8.5.3) RRULE format, to specify when this recurs. -Note that GKE may accept other formats, but will return values in UTC, causing a permanent diff. - -Examples: - -``` -maintenance_policy { - recurring_window { - start_time = "2019-01-01T00:00:00Z" - end_time = "2019-01-02T00:00:00Z" - recurrence = "FREQ=DAILY" - } - maintenance_exclusion{ - exclusion_name = "batch job" - start_time = "2019-01-01T00:00:00Z" - end_time = "2019-01-02T00:00:00Z" - exclusion_options { - scope = "NO_UPGRADES" - } - } - maintenance_exclusion{ - exclusion_name = "holiday data load" - start_time = "2019-05-01T00:00:00Z" - end_time = "2019-05-02T00:00:00Z" - exclusion_options { - scope = "NO_MINOR_UPGRADES" - } - } -} -``` - -The `ip_allocation_policy` block supports: - -* `cluster_secondary_range_name` - (Optional) The name of the existing secondary - range in the cluster's subnetwork to use for pod IP addresses. Alternatively, - `cluster_ipv4_cidr_block` can be used to automatically create a GKE-managed one. - -* `services_secondary_range_name` - (Optional) The name of the existing - secondary range in the cluster's subnetwork to use for service `ClusterIP`s. - Alternatively, `services_ipv4_cidr_block` can be used to automatically create a - GKE-managed one. - -* `cluster_ipv4_cidr_block` - (Optional) The IP address range for the cluster pod IPs. - Set to blank to have a range chosen with the default size. Set to /netmask (e.g. /14) - to have a range chosen with a specific netmask. Set to a CIDR notation (e.g. 10.96.0.0/14) - from the RFC-1918 private networks (e.g. 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) to - pick a specific range to use. - -* `services_ipv4_cidr_block` - (Optional) The IP address range of the services IPs in this cluster. - Set to blank to have a range chosen with the default size. Set to /netmask (e.g. /14) - to have a range chosen with a specific netmask. Set to a CIDR notation (e.g. 10.96.0.0/14) - from the RFC-1918 private networks (e.g. 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) to - pick a specific range to use. - -* `stack_type` - (Optional) The IP Stack Type of the cluster. - Default value is `IPV4`. - Possible values are `IPV4` and `IPV4_IPV6`. - -* `additional_pod_ranges_config` - (Optional) The configuration for additional pod secondary ranges at - the cluster level. Used for Autopilot clusters and Standard clusters with which control of the - secondary Pod IP address assignment to node pools isn't needed. Structure is [documented below](#nested_additional_pod_ranges_config). - - -The `additional_pod_ranges_config` block supports: - -* `pod_range_names` - (Required) The names of the Pod ranges to add to the cluster. - - -The `master_auth` block supports: - -* `client_certificate_config` - (Required) Whether client certificate authorization is enabled for this cluster. For example: - -```hcl -master_auth { - client_certificate_config { - issue_client_certificate = false - } -} -``` - -This block also contains several computed attributes, documented below. - -The `master_authorized_networks_config` block supports: - -* `cidr_blocks` - (Optional) External networks that can access the - Kubernetes cluster master through HTTPS. - -* `gcp_public_cidrs_access_enabled` - (Optional) Whether Kubernetes master is - accessible via Google Compute Engine Public IPs. - -The `master_authorized_networks_config.cidr_blocks` block supports: - -* `cidr_block` - (Optional) External network that can access Kubernetes master through HTTPS. - Must be specified in CIDR notation. - -* `display_name` - (Optional) Field for users to identify CIDR blocks. - -The `network_policy` block supports: - -* `provider` - (Optional) The selected network policy provider. Defaults to PROVIDER_UNSPECIFIED. - -* `enabled` - (Required) Whether network policy is enabled on the cluster. - -The `node_config` block supports: - -* `disk_size_gb` - (Optional) Size of the disk attached to each node, specified - in GB. The smallest allowed disk size is 10GB. Defaults to 100GB. - -* `disk_type` - (Optional) Type of the disk attached to each node - (e.g. 'pd-standard', 'pd-balanced' or 'pd-ssd'). If unspecified, the default disk type is 'pd-standard' - -* `enable_confidential_storage` - (Optional) Enabling Confidential Storage will create boot disk with confidential mode. It is disabled by default. - -* `ephemeral_storage_config` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) Parameters for the ephemeral storage filesystem. If unspecified, ephemeral storage is backed by the boot disk. Structure is [documented below](#nested_ephemeral_storage_config). - -```hcl -ephemeral_storage_config { - local_ssd_count = 2 -} -``` -* `ephemeral_storage_local_ssd_config` - (Optional) Parameters for the ephemeral storage filesystem. If unspecified, ephemeral storage is backed by the boot disk. Structure is [documented below](#nested_ephemeral_storage_local_ssd_config). - -```hcl -ephemeral_storage_local_ssd_config { - local_ssd_count = 2 -} -``` -* `fast_socket` - (Optional) Parameters for the NCCL Fast Socket feature. If unspecified, NCCL Fast Socket will not be enabled on the node pool. - Node Pool must enable gvnic. - GKE version 1.25.2-gke.1700 or later. - Structure is [documented below](#nested_fast_socket). - -* `local_nvme_ssd_block_config` - (Optional) Parameters for the local NVMe SSDs. Structure is [documented below](#nested_local_nvme_ssd_block_config). - -* `logging_variant` (Optional) Parameter for specifying the type of logging agent used in a node pool. This will override any [cluster-wide default value](#nested_node_pool_defaults). Valid values include DEFAULT and MAX_THROUGHPUT. See [Increasing logging agent throughput](https://cloud.google.com/stackdriver/docs/solutions/gke/managing-logs#throughput) for more information. - -* `secondary_boot_disks` - (Optional) Parameters for secondary boot disks to preload container images and data on new nodes. Structure is [documented below](#nested_secondary_boot_disks). `gcfs_config` must be `enabled=true` for this feature to work. `min_master_version` must also be set to use GKE 1.28.3-gke.106700 or later versions. - -* `gcfs_config` - (Optional) Parameters for the Google Container Filesystem (GCFS). - If unspecified, GCFS will not be enabled on the node pool. When enabling this feature you must specify `image_type = "COS_CONTAINERD"` and `node_version` from GKE versions 1.19 or later to use it. - For GKE versions 1.19, 1.20, and 1.21, the recommended minimum `node_version` would be 1.19.15-gke.1300, 1.20.11-gke.1300, and 1.21.5-gke.1300 respectively. - A `machine_type` that has more than 16 GiB of memory is also recommended. - GCFS must be enabled in order to use [image streaming](https://cloud.google.com/kubernetes-engine/docs/how-to/image-streaming). - Structure is [documented below](#nested_gcfs_config). - -```hcl -gcfs_config { - enabled = true -} -``` - - -* `gvnic` - (Optional) Google Virtual NIC (gVNIC) is a virtual network interface. - Installing the gVNIC driver allows for more efficient traffic transmission across the Google network infrastructure. - gVNIC is an alternative to the virtIO-based ethernet driver. GKE nodes must use a Container-Optimized OS node image. - GKE node version 1.15.11-gke.15 or later - Structure is [documented below](#nested_gvnic). - - -```hcl -gvnic { - enabled = true -} -``` - -* `guest_accelerator` - (Optional) List of the type and count of accelerator cards attached to the instance. - Structure [documented below](#nested_guest_accelerator). - To support removal of guest_accelerators in Terraform 0.12 this field is an - [Attribute as Block](/docs/configuration/attr-as-blocks.html) - -* `image_type` - (Optional) The image type to use for this node. Note that changing the image type - will delete and recreate all nodes in the node pool. - -* `labels` - (Optional) The Kubernetes labels (key/value pairs) to be applied to each node. The kubernetes.io/ and k8s.io/ prefixes are - reserved by Kubernetes Core components and cannot be specified. - -* `resource_labels` - (Optional) The GCP labels (key/value pairs) to be applied to each node. Refer [here](https://cloud.google.com/kubernetes-engine/docs/how-to/creating-managing-labels) - for how these labels are applied to clusters, node pools and nodes. - -* `local_ssd_count` - (Optional) The amount of local SSD disks that will be - attached to each cluster node. Defaults to 0. - -* `machine_type` - (Optional) The name of a Google Compute Engine machine type. - Defaults to `e2-medium`. To create a custom machine type, value should be set as specified - [here](https://cloud.google.com/compute/docs/reference/latest/instances#machineType). - -* `metadata` - (Optional) The metadata key/value pairs assigned to instances in - the cluster. From GKE `1.12` onwards, `disable-legacy-endpoints` is set to - `true` by the API; if `metadata` is set but that default value is not - included, Terraform will attempt to unset the value. To avoid this, set the - value in your config. - -* `min_cpu_platform` - (Optional) Minimum CPU platform to be used by this instance. - The instance may be scheduled on the specified or newer CPU platform. Applicable - values are the friendly names of CPU platforms, such as `Intel Haswell`. See the - [official documentation](https://cloud.google.com/compute/docs/instances/specify-min-cpu-platform) - for more information. - -* `oauth_scopes` - (Optional) The set of Google API scopes to be made available - on all of the node VMs under the "default" service account. - Use the "https://www.googleapis.com/auth/cloud-platform" scope to grant access to all APIs. It is recommended that you set `service_account` to a non-default service account and grant IAM roles to that service account for only the resources that it needs. - - See the [official documentation](https://cloud.google.com/kubernetes-engine/docs/how-to/access-scopes) for information on migrating off of legacy access scopes. - -* `preemptible` - (Optional) A boolean that represents whether or not the underlying node VMs - are preemptible. See the [official documentation](https://cloud.google.com/container-engine/docs/preemptible-vm) - for more information. Defaults to false. - -* `reservation_affinity` (Optional) The configuration of the desired reservation which instances could take capacity from. Structure is [documented below](#nested_reservation_affinity). - -* `spot` - (Optional) A boolean that represents whether the underlying node VMs are spot. - See the [official documentation](https://cloud.google.com/kubernetes-engine/docs/concepts/spot-vms) - for more information. Defaults to false. - -* `sandbox_config` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) [GKE Sandbox](https://cloud.google.com/kubernetes-engine/docs/how-to/sandbox-pods) configuration. When enabling this feature you must specify `image_type = "COS_CONTAINERD"` and `node_version = "1.12.7-gke.17"` or later to use it. - Structure is [documented below](#nested_sandbox_config). - -* `boot_disk_kms_key` - (Optional) The Customer Managed Encryption Key used to encrypt the boot disk attached to each node in the node pool. This should be of the form projects/[KEY_PROJECT_ID]/locations/[LOCATION]/keyRings/[RING_NAME]/cryptoKeys/[KEY_NAME]. For more information about protecting resources with Cloud KMS Keys please see: https://cloud.google.com/compute/docs/disks/customer-managed-encryption - -* `service_account` - (Optional) The service account to be used by the Node VMs. - If not specified, the "default" service account is used. - -* `shielded_instance_config` - (Optional) Shielded Instance options. Structure is [documented below](#nested_shielded_instance_config). - -* `tags` - (Optional) The list of instance tags applied to all nodes. Tags are used to identify - valid sources or targets for network firewalls. - -* `resource_manager_tags` - (Optional) A map of resource manager tag keys and values to be attached to the nodes for managing Compute Engine firewalls using Network Firewall Policies. Tags must be according to specifications found [here](https://cloud.google.com/vpc/docs/tags-firewalls-overview#specifications). A maximum of 5 tag key-value pairs can be specified. Existing tags will be replaced with new values. Tags must be in one of the following formats ([KEY]=[VALUE]) 1. `tagKeys/{tag_key_id}=tagValues/{tag_value_id}` 2. `{org_id}/{tag_key_name}={tag_value_name}` 3. `{project_id}/{tag_key_name}={tag_value_name}`. - -* `taint` - (Optional) A list of - [Kubernetes taints](https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/) - to apply to nodes. This field will only report drift on taint keys that are - already managed with Terraform, use `effective_taints` to view the list of - GKE-managed taints on the node pool from all sources. Importing this resource - will not record any taints as being Terraform-managed, and will cause drift with - any configured taints. Structure is [documented below](#nested_taint). - -* `workload_metadata_config` - (Optional) Metadata configuration to expose to workloads on the node pool. - Structure is [documented below](#nested_workload_metadata_config). - -* `kubelet_config` - (Optional) - Kubelet configuration, currently supported attributes can be found [here](https://cloud.google.com/sdk/gcloud/reference/beta/container/node-pools/create#--system-config-from-file). - Structure is [documented below](#nested_kubelet_config). - -``` -kubelet_config { - cpu_manager_policy = "static" - cpu_cfs_quota = true - cpu_cfs_quota_period = "100us" - pod_pids_limit = 1024 -} -``` - -* `linux_node_config` - (Optional) Parameters that can be configured on Linux nodes. Structure is [documented below](#nested_linux_node_config). - -* `containerd_config` - (Optional) Parameters to customize containerd runtime. Structure is [documented below](#nested_containerd_config). - -* `node_group` - (Optional) Setting this field will assign instances of this pool to run on the specified node group. This is useful for running workloads on [sole tenant nodes](https://cloud.google.com/compute/docs/nodes/sole-tenant-nodes). - -* `sole_tenant_config` (Optional) Allows specifying multiple [node affinities](https://cloud.google.com/compute/docs/nodes/sole-tenant-nodes#node_affinity_and_anti-affinity) useful for running workloads on [sole tenant nodes](https://cloud.google.com/kubernetes-engine/docs/how-to/sole-tenancy). `node_affinity` structure is [documented below](#nested_node_affinity). - -```hcl -sole_tenant_config { - node_affinity { - key = "compute.googleapis.com/node-group-name" - operator = "IN" - values = ["node-group-name"] - } -} -``` - -* `advanced_machine_features` - (Optional) Specifies options for controlling - advanced machine features. Structure is [documented below](#nested_advanced_machine_features). - -The `node_affinity` block supports: - -* `key` (Required) - The default or custom node affinity label key name. - -* `operator` (Required) - Specifies affinity or anti-affinity. Accepted values are `"IN"` or `"NOT_IN"` - -* `values` (Required) - List of node affinity label values as strings. - -The `advanced_machine_features` block supports: - -* `threads_per_core` - (Required) The number of threads per physical core. To disable simultaneous multithreading (SMT) set this to 1. If unset, the maximum number of threads supported per core by the underlying processor is assumed. - -* `enable_nested_virtualization`- (Optional) Defines whether the instance should have nested virtualization enabled. Defaults to false. - -* `network_performance_config` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) Network bandwidth tier configuration. - -The `network_performance_config` block supports: - -* `total_egress_bandwidth_tier` (Required) - Specifies the total network bandwidth tier for the NodePool. - -The `ephemeral_storage_config` block supports: - -* `local_ssd_count` (Required) - Number of local SSDs to use to back ephemeral storage. Uses NVMe interfaces. Each local SSD is 375 GB in size. If zero, it means to disable using local SSDs as ephemeral storage. - -The `ephemeral_storage_local_ssd_config` block supports: - -* `local_ssd_count` (Required) - Number of local SSDs to use to back ephemeral storage. Uses NVMe interfaces. Each local SSD is 375 GB in size. If zero, it means to disable using local SSDs as ephemeral storage. - -The `fast_socket` block supports: - -* `enabled` (Required) - Whether or not the NCCL Fast Socket is enabled - -The `local_nvme_ssd_block_config` block supports: - -* `local_ssd_count` (Required) - Number of raw-block local NVMe SSD disks to be attached to the node. Each local SSD is 375 GB in size. If zero, it means no raw-block local NVMe SSD disks to be attached to the node. - -> Note: Local NVMe SSD storage available in GKE versions v1.25.3-gke.1800 and later. - -The `secondary_boot_disks` block supports: - -* `disk_image` (Required) - Path to disk image to create the secondary boot disk from. After using the [gke-disk-image-builder](https://github.com/GoogleCloudPlatform/ai-on-gke/tree/main/tools/gke-disk-image-builder), this argument should be `global/images/DISK_IMAGE_NAME`. -* `mode` (Optional) - Mode for how the secondary boot disk is used. An example mode is `CONTAINER_IMAGE_CACHE`. - - -The `gcfs_config` block supports: - -* `enabled` (Required) - Whether or not the Google Container Filesystem (GCFS) is enabled - -The `gvnic` block supports: - -* `enabled` (Required) - Whether or not the Google Virtual NIC (gVNIC) is enabled - -The `guest_accelerator` block supports: - -* `type` (Required) - The accelerator type resource to expose to this instance. E.g. `nvidia-tesla-k80`. - -* `count` (Required) - The number of the guest accelerator cards exposed to this instance. - -* `gpu_driver_installation_config` (Optional) - Configuration for auto installation of GPU driver. Structure is [documented below](#nested_gpu_driver_installation_config). - -* `gpu_partition_size` (Optional) - Size of partitions to create on the GPU. Valid values are described in the NVIDIA mig [user guide](https://docs.nvidia.com/datacenter/tesla/mig-user-guide/#partitioning). - -* `gpu_sharing_config` (Optional) - Configuration for GPU sharing. Structure is [documented below](#nested_gpu_sharing_config). - -The `gpu_driver_installation_config` block supports: - -* `gpu_driver_version` (Required) - Mode for how the GPU driver is installed. - Accepted values are: - * `"GPU_DRIVER_VERSION_UNSPECIFIED"`: Default value is to not install any GPU driver. - * `"INSTALLATION_DISABLED"`: Disable GPU driver auto installation and needs manual installation. - * `"DEFAULT"`: "Default" GPU driver in COS and Ubuntu. - * `"LATEST"`: "Latest" GPU driver in COS. - -The `gpu_sharing_config` block supports: - -* `gpu_sharing_strategy` (Required) - The type of GPU sharing strategy to enable on the GPU node. - Accepted values are: - * `"TIME_SHARING"`: Allow multiple containers to have [time-shared](https://cloud.google.com/kubernetes-engine/docs/concepts/timesharing-gpus) access to a single GPU device. - * `"MPS"`: Enable co-operative multi-process CUDA workloads to run concurrently on a single GPU device with [MPS](https://cloud.google.com/kubernetes-engine/docs/how-to/nvidia-mps-gpus) - -* `max_shared_clients_per_gpu` (Required) - The maximum number of containers that can share a GPU. - - The `workload_identity_config` block supports: - -* `workload_pool` (Optional) - The workload pool to attach all Kubernetes service accounts to. - -```hcl -workload_identity_config { - workload_pool = "${data.google_project.project.project_id}.svc.id.goog" -} -``` - -The `node_pool_auto_config` block supports: - -* `resource_manager_tags` - (Optional) A map of resource manager tag keys and values to be attached to the nodes for managing Compute Engine firewalls using Network Firewall Policies. Tags must be according to specifications found [here](https://cloud.google.com/vpc/docs/tags-firewalls-overview#specifications). A maximum of 5 tag key-value pairs can be specified. Existing tags will be replaced with new values. Tags must be in one of the following formats ([KEY]=[VALUE]) 1. `tagKeys/{tag_key_id}=tagValues/{tag_value_id}` 2. `{org_id}/{tag_key_name}={tag_value_name}` 3. `{project_id}/{tag_key_name}={tag_value_name}`. - -* `network_tags` (Optional) - The network tag config for the cluster's automatically provisioned node pools. - -The `network_tags` block supports: - -* `tags` (Optional) - List of network tags applied to auto-provisioned node pools. - -```hcl -node_pool_auto_config { - network_tags { - tags = ["foo", "bar"] - } -} -``` - -The `node_pool_defaults` block supports: -* `node_config_defaults` (Optional) - Subset of NodeConfig message that has defaults. - -The `node_config_defaults` block supports: - -* `logging_variant` (Optional) The type of logging agent that is deployed by default for newly created node pools in the cluster. Valid values include DEFAULT and MAX_THROUGHPUT. See [Increasing logging agent throughput](https://cloud.google.com/stackdriver/docs/solutions/gke/managing-logs#throughput) for more information. - -* `gcfs_config` (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) The default Google Container Filesystem (GCFS) configuration at the cluster level. e.g. enable [image streaming](https://cloud.google.com/kubernetes-engine/docs/how-to/image-streaming) across all the node pools within the cluster. Structure is [documented below](#nested_gcfs_config). - -The `notification_config` block supports: - -* `pubsub` (Required) - The pubsub config for the cluster's upgrade notifications. - -The `pubsub` block supports: - -* `enabled` (Required) - Whether or not the notification config is enabled - -* `topic` (Optional) - The pubsub topic to push upgrade notifications to. Must be in the same project as the cluster. Must be in the format: `projects/{project}/topics/{topic}`. - -* `filter` (Optional) - Choose what type of notifications you want to receive. If no filters are applied, you'll receive all notification types. Structure is [documented below](#nested_notification_filter). - -```hcl -notification_config { - pubsub { - enabled = true - topic = google_pubsub_topic.notifications.id - } -} -``` - - The `filter` block supports: - -* `event_type` (Optional) - Can be used to filter what notifications are sent. Accepted values are `UPGRADE_AVAILABLE_EVENT`, `UPGRADE_EVENT` and `SECURITY_BULLETIN_EVENT`. See [Filtering notifications](https://cloud.google.com/kubernetes-engine/docs/concepts/cluster-notifications#filtering) for more details. - - The `confidential_nodes` block supports: - -* `enabled` (Required) - Enable Confidential GKE Nodes for this cluster, to - enforce encryption of data in-use. - -The `pod_security_policy_config` block supports: - -* `enabled` (Required) - Enable the PodSecurityPolicy controller for this cluster. - If enabled, pods must be valid under a PodSecurityPolicy to be created. - -The `private_cluster_config` block supports: - -* `enable_private_nodes` (Optional) - Enables the private cluster feature, - creating a private endpoint on the cluster. In a private cluster, nodes only - have RFC 1918 private addresses and communicate with the master's private - endpoint via private networking. - -* `enable_private_endpoint` (Optional) - When `true`, the cluster's private - endpoint is used as the cluster endpoint and access through the public endpoint - is disabled. When `false`, either endpoint can be used. This field only applies - to private clusters, when `enable_private_nodes` is `true`. - -* `master_ipv4_cidr_block` (Optional) - The IP range in CIDR notation to use for - the hosted master network. This range will be used for assigning private IP - addresses to the cluster master(s) and the ILB VIP. This range must not overlap - with any other ranges in use within the cluster's network, and it must be a /28 - subnet. See [Private Cluster Limitations](https://cloud.google.com/kubernetes-engine/docs/how-to/private-clusters#req_res_lim) - for more details. This field only applies to private clusters, when - `enable_private_nodes` is `true`. - -* `private_endpoint_subnetwork` - (Optional) Subnetwork in cluster's network where master's endpoint will be provisioned. - -* `master_global_access_config` (Optional) - Controls cluster master global - access settings. If unset, Terraform will no longer manage this field and will - not modify the previously-set value. Structure is [documented below](#nested_master_global_access_config). - -In addition, the `private_cluster_config` allows access to the following read-only fields: - -* `peering_name` - The name of the peering between this cluster and the Google owned VPC. - -* `private_endpoint` - The internal IP address of this cluster's master endpoint. - -* `public_endpoint` - The external IP address of this cluster's master endpoint. - -!> The Google provider is unable to validate certain configurations of -`private_cluster_config` when `enable_private_nodes` is `false`. It's -recommended that you omit the block entirely if the field is not set to `true`. - -The `private_cluster_config.master_global_access_config` block supports: - -* `enabled` (Optional) - Whether the cluster master is accessible globally or - not. - -The `reservation_affinity` block supports: - -* `consume_reservation_type` (Required) The type of reservation consumption - Accepted values are: - - * `"UNSPECIFIED"`: Default value. This should not be used. - * `"NO_RESERVATION"`: Do not consume from any reserved capacity. - * `"ANY_RESERVATION"`: Consume any reservation available. - * `"SPECIFIC_RESERVATION"`: Must consume from a specific reservation. Must specify key value fields for specifying the reservations. -* `key` (Optional) The label key of a reservation resource. To target a SPECIFIC_RESERVATION by name, specify "compute.googleapis.com/reservation-name" as the key and specify the name of your reservation as its value. -* `values` (Optional) The list of label values of reservation resources. For example: the name of the specific reservation when using a key of "compute.googleapis.com/reservation-name" - - -The `sandbox_config` block supports: - -* `sandbox_type` (Required) Which sandbox to use for pods in the node pool. - Accepted values are: - - * `"gvisor"`: Pods run within a gVisor sandbox. - -The `release_channel` block supports: - -* `channel` - (Required) The selected release channel. - Accepted values are: - * UNSPECIFIED: Not set. - * RAPID: Weekly upgrade cadence; Early testers and developers who requires new features. - * REGULAR: Multiple per month upgrade cadence; Production users who need features not yet offered in the Stable channel. - * STABLE: Every few months upgrade cadence; Production users who need stability above all else, and for whom frequent upgrades are too risky. - -The `cost_management_config` block supports: - -* `enabled` (Optional) - Whether to enable the [cost allocation](https://cloud.google.com/kubernetes-engine/docs/how-to/cost-allocations) feature. - -The `resource_usage_export_config` block supports: - -* `enable_network_egress_metering` (Optional) - Whether to enable network egress metering for this cluster. If enabled, a daemonset will be created - in the cluster to meter network egress traffic. - -* `enable_resource_consumption_metering` (Optional) - Whether to enable resource - consumption metering on this cluster. When enabled, a table will be created in - the resource export BigQuery dataset to store resource consumption data. The - resulting table can be joined with the resource usage table or with BigQuery - billing export. Defaults to `true`. - -* `bigquery_destination` (Required) - Parameters for using BigQuery as the destination of resource usage export. - -* `bigquery_destination.dataset_id` (Required) - The ID of a BigQuery Dataset. For Example: - -```hcl -resource_usage_export_config { - enable_network_egress_metering = false - enable_resource_consumption_metering = true - - bigquery_destination { - dataset_id = "cluster_resource_usage" - } -} -``` - -The `shielded_instance_config` block supports: - -* `enable_secure_boot` (Optional) - Defines if the instance has Secure Boot enabled. - -Secure Boot helps ensure that the system only runs authentic software by verifying the digital signature of all boot components, and halting the boot process if signature verification fails. Defaults to `false`. - -* `enable_integrity_monitoring` (Optional) - Defines if the instance has integrity monitoring enabled. - -Enables monitoring and attestation of the boot integrity of the instance. The attestation is performed against the integrity policy baseline. This baseline is initially derived from the implicitly trusted boot image when the instance is created. Defaults to `true`. - -The `taint` block supports: - -* `key` (Required) Key for taint. - -* `value` (Required) Value for taint. - -* `effect` (Required) Effect for taint. Accepted values are `NO_SCHEDULE`, `PREFER_NO_SCHEDULE`, and `NO_EXECUTE`. - -The `workload_metadata_config` block supports: - -* `mode` (Required) How to expose the node metadata to the workload running on the node. - Accepted values are: - * MODE_UNSPECIFIED: Not Set - * GCE_METADATA: Expose all Compute Engine metadata to pods. - * GKE_METADATA: Run the GKE Metadata Server on this node. The GKE Metadata Server exposes a metadata API to workloads that is compatible with the V1 Compute Metadata APIs exposed by the Compute Engine and App Engine Metadata Servers. This feature can only be enabled if [workload identity](https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity) is enabled at the cluster level. - -The `kubelet_config` block supports: - -* `cpu_manager_policy` - (Required) The CPU management policy on the node. See - [K8S CPU Management Policies](https://kubernetes.io/docs/tasks/administer-cluster/cpu-management-policies/). - One of `"none"` or `"static"`. Defaults to `none` when `kubelet_config` is unset. - -* `cpu_cfs_quota` - (Optional) If true, enables CPU CFS quota enforcement for - containers that specify CPU limits. - -* `cpu_cfs_quota_period` - (Optional) The CPU CFS quota period value. Specified - as a sequence of decimal numbers, each with optional fraction and a unit suffix, - such as `"300ms"`. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", - "h". The value must be a positive duration. - --> Note: At the time of writing (2020/08/18) the GKE API rejects the `none` -value and accepts an invalid `default` value instead. While this remains true, -not specifying the `kubelet_config` block should be the equivalent of specifying -`none`. - -* `pod_pids_limit` - (Optional) Controls the maximum number of processes allowed to run in a pod. The value must be greater than or equal to 1024 and less than 4194304. - -The `linux_node_config` block supports: - -* `sysctls` - (Optional) The Linux kernel parameters to be applied to the nodes - and all pods running on the nodes. Specified as a map from the key, such as - `net.core.wmem_max`, to a string value. Currently supported attributes can be found [here](https://cloud.google.com/sdk/gcloud/reference/beta/container/node-pools/create#--system-config-from-file). - Note that validations happen all server side. All attributes are optional. - -```hcl -linux_node_config { - sysctls = { - "net.core.netdev_max_backlog" = "10000" - "net.core.rmem_max" = "10000" - } -} -``` - -* `cgroup_mode` - (Optional) Possible cgroup modes that can be used. - Accepted values are: - * `CGROUP_MODE_UNSPECIFIED`: CGROUP_MODE_UNSPECIFIED is when unspecified cgroup configuration is used. The default for the GKE node OS image will be used. - * `CGROUP_MODE_V1`: CGROUP_MODE_V1 specifies to use cgroupv1 for the cgroup configuration on the node image. - * `CGROUP_MODE_V2`: CGROUP_MODE_V2 specifies to use cgroupv2 for the cgroup configuration on the node image. - -The `containerd_config` block supports: - -* `private_registry_access_config` (Optional) - Configuration for private container registries. There are two fields in this config: - - * `enabled` (Required) - Enables private registry config. If set to false, all other fields in this object must not be set. - - * `certificate_authority_domain_config` (Optional) - List of configuration objects for CA and domains. Each object identifies a certificate and its assigned domains. See [how to configure for private container registries](https://cloud.google.com/kubernetes-engine/docs/how-to/access-private-registries-private-certificates) for more detail. Example: - ```hcl - certificate_authority_domain_config { - fqdns = [ - "my.custom.domain", - "10.4.5.6", - "127.0.0.1:8888", - ] - gcp_secret_manager_certificate_config { - secret_uri = "projects/99999/secrets/my-ca-cert/versions/1" - } - } - ``` - -The `vertical_pod_autoscaling` block supports: - -* `enabled` (Required) - Enables vertical pod autoscaling - -The `dns_config` block supports: - -* `additive_vpc_scope_dns_domain` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) This will enable Cloud DNS additive VPC scope. Must provide a domain name that is unique within the VPC. For this to work `cluster_dns = "CLOUD_DNS"` and `cluster_dns_scope = "CLUSTER_SCOPE"` must both be set as well. - -* `cluster_dns` - (Optional) Which in-cluster DNS provider should be used. `PROVIDER_UNSPECIFIED` (default) or `PLATFORM_DEFAULT` or `CLOUD_DNS`. - -* `cluster_dns_scope` - (Optional) The scope of access to cluster DNS records. `DNS_SCOPE_UNSPECIFIED` (default) or `CLUSTER_SCOPE` or `VPC_SCOPE`. - -* `cluster_dns_domain` - (Optional) The suffix used for all cluster service records. - -The `gateway_api_config` block supports: - -* `channel` - (Required) Which Gateway Api channel should be used. `CHANNEL_DISABLED`, `CHANNEL_EXPERIMENTAL` or `CHANNEL_STANDARD`. - -The `protect_config` block supports: - -* `workload_config` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) WorkloadConfig defines which actions are enabled for a cluster's workload configurations. Structure is [documented below](#nested_workload_config) - -* `workload_vulnerability_mode` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) Sets which mode to use for Protect workload vulnerability scanning feature. Accepted values are DISABLED, BASIC. - -The `protect_config.workload_config` block supports: - -* `audit_mode` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) Sets which mode of auditing should be used for the cluster's workloads. Accepted values are DISABLED, BASIC. - -The `security_posture_config` block supports: - -* `mode` - (Optional) Sets the mode of the Kubernetes security posture API's off-cluster features. Available options include `DISABLED` and `BASIC`. - - -* `vulnerability_mode` - (Optional) Sets the mode of the Kubernetes security posture API's workload vulnerability scanning. Available options include `VULNERABILITY_DISABLED`, `VULNERABILITY_BASIC` and `VULNERABILITY_ENTERPRISE`. - -The `fleet` block supports: - -* `project` - (Optional) The name of the Fleet host project where this cluster will be registered. - -The `workload_alts_config` block supports: - -* `enable_alts` - (Required) Whether the alts handshaker should be enabled or not for direct-path. Requires Workload Identity ([workloadPool]((#nested_workload_identity_config)) must be non-empty). - -## Attributes Reference - -In addition to the arguments listed above, the following computed attributes are -exported: - -* `id` - an identifier for the resource with format `projects/{{project}}/locations/{{zone}}/clusters/{{name}}` - -* `self_link` - The server-defined URL for the resource. - -* `endpoint` - The IP address of this cluster's Kubernetes master. - -* `label_fingerprint` - The fingerprint of the set of labels for this cluster. - -* `maintenance_policy.0.daily_maintenance_window.0.duration` - Duration of the time window, automatically chosen to be - smallest possible in the given scenario. - Duration will be in [RFC3339](https://www.ietf.org/rfc/rfc3339.txt) format "PTnHnMnS". - -* `master_auth.0.client_certificate` - Base64 encoded public certificate - used by clients to authenticate to the cluster endpoint. - -* `master_auth.0.client_key` - Base64 encoded private key used by clients - to authenticate to the cluster endpoint. - -* `master_auth.0.cluster_ca_certificate` - Base64 encoded public certificate - that is the root certificate of the cluster. - -* `master_version` - The current version of the master in the cluster. This may - be different than the `min_master_version` set in the config if the master - has been updated by GKE. - -* `tpu_ipv4_cidr_block` - The IP address range of the Cloud TPUs in this cluster, in - [CIDR](http://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing) - notation (e.g. `1.2.3.4/29`). - -* `services_ipv4_cidr` - The IP address range of the Kubernetes services in this - cluster, in [CIDR](http://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing) - notation (e.g. `1.2.3.4/29`). Service addresses are typically put in the last - `/16` from the container CIDR. - -* `cluster_autoscaling.0.auto_provisioning_defaults.0.management.0.upgrade_options` - Specifies the [Auto Upgrade knobs](https://cloud.google.com/kubernetes-engine/docs/reference/rest/v1beta1/NodeManagement#AutoUpgradeOptions) for the node pool. - -* `node_config.0.effective_taints` - List of kubernetes taints applied to each node. Structure is [documented above](#nested_taint). - -* `fleet.0.membership` - The resource name of the fleet Membership resource associated to this cluster with format `//gkehub.googleapis.com/projects/{{project}}/locations/{{location}}/memberships/{{name}}`. See the official doc for [fleet management](https://cloud.google.com/kubernetes-engine/docs/fleets-overview). - -* `fleet.0.membership_id` - The short name of the fleet membership, extracted from `fleet.0.membership`. You can use this field to configure `membership_id` under [google_gkehub_feature_membership](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/gke_hub_feature_membership). - -* `fleet.0.membership_location` - The location of the fleet membership, extracted from `fleet.0.membership`. You can use this field to configure `membership_location` under [google_gkehub_feature_membership](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/gke_hub_feature_membership). - -## Timeouts - -This resource provides the following -[Timeouts](https://developer.hashicorp.com/terraform/plugin/sdkv2/resources/retries-and-customizable-timeouts) configuration options: configuration options: - -- `create` - Default is 40 minutes. -- `read` - Default is 40 minutes. -- `update` - Default is 60 minutes. -- `delete` - Default is 40 minutes. - -## Import - -GKE clusters can be imported using the `project` , `location`, and `name`. If the project is omitted, the default -provider value will be used. Examples: - -* `projects/{{project_id}}/locations/{{location}}/clusters/{{cluster_id}}` -* `{{project_id}}/{{location}}/{{cluster_id}}` -* `{{location}}/{{cluster_id}}` - -In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import GKE clusters using one of the formats above. For example: - -```tf -import { - id = "projects/{{project_id}}/locations/{{location}}/clusters/{{cluster_id}}" - to = google_container_cluster.default -} -``` - -When using the [`terraform import` command](https://developer.hashicorp.com/terraform/cli/commands/import), GKE clusters can be imported using one of the formats above. For example: - -``` -$ terraform import google_container_cluster.default projects/{{project_id}}/locations/{{location}}/clusters/{{cluster_id}} - -$ terraform import google_container_cluster.default {{project_id}}/{{location}}/{{cluster_id}} - -$ terraform import google_container_cluster.default {{location}}/{{cluster_id}} -``` - -~> **Note:** This resource has several fields that control Terraform-specific behavior and aren't present in the API. If they are set in config and you import a cluster, Terraform may need to perform an update immediately after import. Most of these updates should be no-ops but some may modify your cluster if the imported state differs. - -For example, the following fields will show diffs if set in config: - -- `min_master_version` -- `remove_default_node_pool` - -## User Project Overrides +* `name` - (Required) The name of the cluster. Only letters (a-z, 0-9, '-') are allowed. Your input data length must be between 5 and 20. +* `config` - (Computed) The configuration of the Cluster. You don't need input to this field anything when you create a Cluster. +* `description` - (Optional) Description of the cluster. Only letters (a-z, A-Z, 0-9, '@', '.' , '_' , '-' , ' '). Your input data length must be between 0 and 255. +* `version` - (Optional) The version you want to use for you Cluster. You can see all of the Kubernetes's version in [here](https://docs.vngcloud.vn/vng-cloud-document/v/vn/vks/tham-khao-them/phien-ban-ho-tro-kubernetes). +* `white_list_node_cidr` - (Optional) The IP Address range can connect to the control plane. The feature only works on Private Node Group mode. +* `enable_private_cluster` (Optional) - Enables the private cluster feature, + creating a private endpoint on the cluster. The VKS public clusters refer to a type of Kubernetes cluster configuration where the Kubernetes API server endpoint is publicly accessible over the internet. In an VKS public cluster, the API server endpoint is not restricted to private access within a VPC (Virtual Private Cloud) and can be accessed over the public internet. The VKS private clusters are configured to have private access to the Kubernetes API server endpoint. This means that the API server endpoint is only accessible from within a specific Virtual Private Cloud (VPC) and is not exposed to the public internet. Private clusters provide enhanced security by restricting access to the Kubernetes API to resources within the VPC. At this time, the default value of this field is false and we only offer Public Cluster mode. +* `network_type` - (Optional) The type of network for the cluster. Defaults to "CALICO". +* `vpc_id` (Required) The VPC ID for the cluster. You need create a VPC on vServer and put the VPC's ID on this field. +* `subnet_id` (Required) The subnet ID for the cluster. You need create a Subnet on vServer and put the Subnet's ID on this field. +* `cidr` (Required) The CIDR block for the cluster. You can enter CIDR as private IP and can select from the following options (10.0.0.0 - 10.255.0.0 / 172.16.0.0 - 172.24.0.0 / 192.168.0.0). +* `enabled_load_balancer_plugin` (Optional) Automatically deploy and manage the BlockStore Persistent Disk CSI Driver via Kubernetes YAML. +* `enabled_block_store_csi_plugin` (Optional) Allow attaching load balancers (network and application) via the Kubernetes YAML. -This resource supports [User Project Overrides](https://registry.terraform.io/providers/hashicorp/google/latest/docs/guides/provider_reference#user_project_override). \ No newline at end of file diff --git a/docs/resources/vks_cluster_node_group.md b/docs/resources/vks_cluster_node_group.md index 04c4824..3e75e23 100644 --- a/docs/resources/vks_cluster_node_group.md +++ b/docs/resources/vks_cluster_node_group.md @@ -6,323 +6,86 @@ description: |- # vngcloud_vks_cluster_node_group --> See the [Using GKE with Terraform](/docs/providers/google/guides/using_gke_with_terraform.html) -guide for more information about using GKE with Terraform. +Manages a VNGCloud Kubernetes Engine (VKS) Node Group. -Manages a node pool in a Google Kubernetes Engine (GKE) cluster separately from -the cluster control plane. For more information see [the official documentation](https://cloud.google.com/container-engine/docs/node-pools) -and [the API reference](https://cloud.google.com/kubernetes-engine/docs/reference/rest/v1beta1/projects.locations.clusters.nodePools). +To get more information about VKS Node Group, see: -### Example Usage - using a separately managed node pool (recommended) +* How-to guides + * [VKS overview](https://docs.vngcloud.vn/vng-cloud-document/v/vn/vks/vks-la-gi) + * [Getting Start with VKS](https://docs.vngcloud.vn/vng-cloud-document/v/vn/vks/bat-dau-voi-vks) +* Terraform guidance + * [Using VKS with Terraform](https://docs.vngcloud.vn/vng-cloud-document/v/vn/vks/su-dung-vks-voi-terraform) -```hcl -resource "google_service_account" "default" { - account_id = "service-account-id" - display_name = "Service Account" -} +Manages a node group in a VNGCloud Kubernetes Service (VKS) cluster separately from +the cluster control plane. For more information see [Node Group](https://docs.vngcloud.vn/vng-cloud-document/v/vn/vks/node-groups). -resource "google_container_cluster" "primary" { - name = "my-gke-cluster" - location = "us-central1" +--- - # We can't create a cluster with no node pool defined, but we want to only use - # separately managed node pools. So we create the smallest possible default - # node pool and immediately delete it. - remove_default_node_pool = true - initial_node_count = 1 -} +# vngcloud_vks_cluster_node_group -resource "google_container_node_pool" "primary_preemptible_nodes" { - name = "my-node-pool" - cluster = google_container_cluster.primary.id - node_count = 1 +## Example Usage - using a separately managed node group (recommended) - node_config { - preemptible = true - machine_type = "e2-medium" +```hcl +resource "vngcloud_vks_cluster" "primary" { + name = "my-vks-cluster" + cidr = "172.16.0.0/16" + vpc_id = "net-xxxxxxxx-xxxx-xxxxx-xxxx-xxxxxxxxxxxx" + subnet_id = "sub-xxxxxxxx-xxxx-xxxxx-xxxx-xxxxxxxxxxxx" +} - # Google recommends custom service accounts that have cloud-platform scope and permissions granted via IAM Roles. - service_account = google_service_account.default.email - oauth_scopes = [ - "https://www.googleapis.com/auth/cloud-platform" - ] - } +resource "vngcloud_vks_cluster_node_group" "primary" { + name= "my-vks-node-group" + ssh_key_id= "ssh-xxxxxxxx-xxxx-xxxxx-xxxx-xxxxxxxxxxxx" + cluster_id= vngcloud_vks_cluster.primary.id } ``` -### Example Usage - 2 node pools, 1 separately managed + the default node pool +## Example Usage - 2 node pools, 1 separately managed + the default node group ```hcl -resource "google_service_account" "default" { - account_id = "service-account-id" - display_name = "Service Account" -} - -resource "google_container_node_pool" "np" { - name = "my-node-pool" - cluster = google_container_cluster.primary.id - node_config { - machine_type = "e2-medium" - # Google recommends custom service accounts that have cloud-platform scope and permissions granted via IAM Roles. - service_account = google_service_account.default.email - oauth_scopes = [ - "https://www.googleapis.com/auth/cloud-platform" - ] - } - timeouts { - create = "30m" - update = "20m" +resource "vngcloud_vks_cluster" "primary" { + name = "my-vks-cluster" + cidr = "172.16.0.0/16" + vpc_id = "net-xxxxxxxx-xxxx-xxxxx-xxxx-xxxxxxxxxxxx" + subnet_id = "sub-xxxxxxxx-xxxx-xxxxx-xxxx-xxxxxxxxxxxx" + node_group { + name= "my-vks-default" + ssh_key_id= "ssh-xxxxxxxx-xxxx-xxxxx-xxxx-xxxxxxxxxxxx" } } -resource "google_container_cluster" "primary" { - name = "marcellus-wallace" - location = "us-central1-a" - initial_node_count = 3 - - node_locations = [ - "us-central1-c", - ] - - node_config { - # Google recommends custom service accounts that have cloud-platform scope and permissions granted via IAM Roles. - service_account = google_service_account.default.email - oauth_scopes = [ - "https://www.googleapis.com/auth/cloud-platform" - ] - guest_accelerator { - type = "nvidia-tesla-k80" - count = 1 - } - } +resource "vngcloud_vks_cluster_node_group" "primary" { + name= "my-vks-node-group" + ssh_key_id= "ssh-xxxxxxxx-xxxx-xxxxx-xxxx-xxxxxxxxxxxx" + cluster_id= vngcloud_vks_cluster.primary.id } ``` ## Argument Reference -* `cluster` - (Required) The cluster to create the node pool for. Cluster must be present in `location` provided for clusters. May be specified in the format `projects/{{project}}/locations/{{location}}/clusters/{{cluster}}` or as just the name of the cluster. - -- - - - -* `location` - (Optional) The location (region or zone) of the cluster. - -- - - - -* `autoscaling` - (Optional) Configuration required by cluster autoscaler to adjust - the size of the node pool to the current cluster usage. Structure is [documented below](#nested_autoscaling). - -* `confidential_nodes` - (Optional) Configuration for Confidential Nodes feature. Structure is [documented below](#nested_confidential_nodes). - -* `initial_node_count` - (Optional) The initial number of nodes for the pool. In - regional or multi-zonal clusters, this is the number of nodes per zone. Changing - this will force recreation of the resource. WARNING: Resizing your node pool manually - may change this value in your existing cluster, which will trigger destruction - and recreation on the next Terraform run (to rectify the discrepancy). If you don't - need this value, don't set it. If you do need it, you can [use a lifecycle block to - ignore subsequent changes to this field](https://github.com/hashicorp/terraform-provider-google/issues/6901#issuecomment-667369691). - -* `management` - (Optional) Node management configuration, wherein auto-repair and - auto-upgrade is configured. Structure is [documented below](#nested_management). - -* `max_pods_per_node` - (Optional) The maximum number of pods per node in this node pool. - Note that this does not work on node pools which are "route-based" - that is, node - pools belonging to clusters that do not have IP Aliasing enabled. - See the [official documentation](https://cloud.google.com/kubernetes-engine/docs/how-to/flexible-pod-cidr) - for more information. - -* `node_locations` - (Optional) - The list of zones in which the node pool's nodes should be located. Nodes must - be in the region of their regional cluster or in the same region as their - cluster's zone for zonal clusters. If unspecified, the cluster-level - `node_locations` will be used. - --> Note: `node_locations` will not revert to the cluster's default set of zones -upon being unset. You must manually reconcile the list of zones with your -cluster. - -* `name` - (Optional) The name of the node pool. If left blank, Terraform will - auto-generate a unique name. - -* `name_prefix` - (Optional) Creates a unique name for the node pool beginning - with the specified prefix. Conflicts with `name`. - -* `node_config` - (Optional) Parameters used in creating the node pool. See - [google_container_cluster](container_cluster.html#nested_node_config) for schema. - -* `network_config` - (Optional) The network configuration of the pool. Such as - configuration for [Adding Pod IP address ranges](https://cloud.google.com/kubernetes-engine/docs/how-to/multi-pod-cidr)) to the node pool. Or enabling private nodes. Structure is - [documented below](#nested_network_config) - -* `node_count` - (Optional) The number of nodes per instance group. This field can be used to - update the number of nodes per instance group but should not be used alongside `autoscaling`. - -* `project` - (Optional) The ID of the project in which to create the node pool. If blank, - the provider-configured project will be used. - -* `upgrade_settings` (Optional) Specify node upgrade settings to change how GKE upgrades nodes. - The maximum number of nodes upgraded simultaneously is limited to 20. Structure is [documented below](#nested_upgrade_settings). - -* `version` - (Optional) The Kubernetes version for the nodes in this pool. Note that if this field - and `auto_upgrade` are both specified, they will fight each other for what the node version should - be, so setting both is highly discouraged. While a fuzzy version can be specified, it's - recommended that you specify explicit versions as Terraform will see spurious diffs - when fuzzy versions are used. See the `google_container_engine_versions` data source's - `version_prefix` field to approximate fuzzy versions in a Terraform-compatible way. - -* `placement_policy` - (Optional) Specifies a custom placement policy for the - nodes. - -* `queued_provisioning` - (Optional) Specifies node pool-level settings of queued provisioning. - Structure is [documented below](#nested_queued_provisioning). - -The `autoscaling` block supports (either total or per zone limits are required): - -* `min_node_count` - (Optional) Minimum number of nodes per zone in the NodePool. - Must be >=0 and <= `max_node_count`. Cannot be used with total limits. - -* `max_node_count` - (Optional) Maximum number of nodes per zone in the NodePool. - Must be >= min_node_count. Cannot be used with total limits. - -* `total_min_node_count` - (Optional) Total minimum number of nodes in the NodePool. - Must be >=0 and <= `total_max_node_count`. Cannot be used with per zone limits. - Total size limits are supported only in 1.24.1+ clusters. - -* `total_max_node_count` - (Optional) Total maximum number of nodes in the NodePool. - Must be >= total_min_node_count. Cannot be used with per zone limits. - Total size limits are supported only in 1.24.1+ clusters. - -* `location_policy` - (Optional) Location policy specifies the algorithm used when - scaling-up the node pool. Location policy is supported only in 1.24.1+ clusters. - * "BALANCED" - Is a best effort policy that aims to balance the sizes of available zones. - * "ANY" - Instructs the cluster autoscaler to prioritize utilization of unused reservations, - and reduce preemption risk for Spot VMs. - - The `confidential_nodes` block supports: - -* `enabled` (Required) - Enable Confidential GKE Nodes for this cluster, to - enforce encryption of data in-use. - -The `management` block supports: - -* `auto_repair` - (Optional) Whether the nodes will be automatically repaired. Enabled by default. - -* `auto_upgrade` - (Optional) Whether the nodes will be automatically upgraded. Enabled by default. - -The `network_config` block supports: - -* `create_pod_range` - (Optional) Whether to create a new range for pod IPs in this node pool. Defaults are provided for `pod_range` and `pod_ipv4_cidr_block` if they are not specified. - -* `enable_private_nodes` - (Optional) Whether nodes have internal IP addresses only. - -* `pod_ipv4_cidr_block` - (Optional) The IP address range for pod IPs in this node pool. Only applicable if createPodRange is true. Set to blank to have a range chosen with the default size. Set to /netmask (e.g. /14) to have a range chosen with a specific netmask. Set to a CIDR notation (e.g. 10.96.0.0/14) to pick a specific range to use. - -* `pod_range` - (Optional) The ID of the secondary range for pod IPs. If `create_pod_range` is true, this ID is used for the new range. If `create_pod_range` is false, uses an existing secondary range with this ID. - -* `additional_node_network_configs` - (Optional, Beta) We specify the additional node networks for this node pool using this list. Each node network corresponds to an additional interface. - Structure is [documented below](#nested_additional_node_network_configs) - -* `additional_pod_network_configs` - (Optional, Beta) We specify the additional pod networks for this node pool using this list. Each pod network corresponds to an additional alias IP range for the node. - Structure is [documented below](#nested_additional_pod_network_configs) - - -The `additional_node_network_configs` block supports: - -* `network` - Name of the VPC where the additional interface belongs. - -* `subnetwork` - Name of the subnetwork where the additional interface belongs. - -The `additional_pod_network_configs` block supports: - -* `subnetwork` - Name of the subnetwork where the additional pod network belongs. - -* `secondary_pod_range` - The name of the secondary range on the subnet which provides IP address for this pod range. - -* `max_pods_per_node` - The maximum number of pods per node which use this pod network. - -The `upgrade_settings` block supports: - -* `max_surge` - (Optional) The number of additional nodes that can be added to the node pool during - an upgrade. Increasing `max_surge` raises the number of nodes that can be upgraded simultaneously. - Can be set to 0 or greater. - -* `max_unavailable` - (Optional) The number of nodes that can be simultaneously unavailable during - an upgrade. Increasing `max_unavailable` raises the number of nodes that can be upgraded in - parallel. Can be set to 0 or greater. - -`max_surge` and `max_unavailable` must not be negative and at least one of them must be greater than zero. - -* `strategy` - (Default `SURGE`) The upgrade stragey to be used for upgrading the nodes. - -* `blue_green_settings` - (Optional) The settings to adjust [blue green upgrades](https://cloud.google.com/kubernetes-engine/docs/concepts/node-pool-upgrade-strategies#blue-green-upgrade-strategy). - Structure is [documented below](#nested_blue_green_settings) - -The `blue_green_settings` block supports: - -* `standard_rollout_policy` - (Required) Specifies the standard policy settings for blue-green upgrades. - * `batch_percentage` - (Optional) Percentage of the blue pool nodes to drain in a batch. - * `batch_node_count` - (Optional) Number of blue nodes to drain in a batch. - * `batch_soak_duration` - (Optionial) Soak time after each batch gets drained. - -* `node_pool_soak_duration` - (Optional) Time needed after draining the entire blue pool. - After this period, the blue pool will be cleaned up. - -The `placement_policy` block supports: - -* `type` - (Required) The type of the policy. Supports a single value: COMPACT. - Specifying COMPACT placement policy type places node pool's nodes in a closer - physical proximity in order to reduce network latency between nodes. - -* `policy_name` - (Optional) If set, refers to the name of a custom resource policy supplied by the user. - The resource policy must be in the same project and region as the node pool. - If not found, InvalidArgument error is returned. - -* `tpu_topology` - (Optional) The [TPU placement topology](https://cloud.google.com/tpu/docs/types-topologies#tpu_topologies) for pod slice node pool. - - The `queued_provisioning` block supports: - -* `enabled` (Required) - Makes nodes obtainable through the [ProvisioningRequest API](https://cloud.google.com/kubernetes-engine/docs/how-to/provisioningrequest) exclusively. - -## Attributes Reference - -In addition to the arguments listed above, the following computed attributes are exported: - -* `id` - an identifier for the resource with format `{{project}}/{{location}}/{{cluster}}/{{name}}` - -* `instance_group_urls` - The resource URLs of the managed instance groups associated with this node pool. - -* `managed_instance_group_urls` - List of instance group URLs which have been assigned to this node pool. - - -## Timeouts - -`google_container_node_pool` provides the following -[Timeouts](https://developer.hashicorp.com/terraform/plugin/sdkv2/resources/retries-and-customizable-timeouts) configuration options: configuration options: - -- `create` - (Default `30 minutes`) Used for adding node pools -- `update` - (Default `30 minutes`) Used for updates to node pools -- `delete` - (Default `30 minutes`) Used for removing node pools. - -## Import - -Node pools can be imported using the `project`, `location`, `cluster` and `name`. If -the project is omitted, the project value in the provider configuration will be used. Examples: - -* `{{project_id}}/{{location}}/{{cluster_id}}/{{pool_id}}` -* `{{location}}/{{cluster_id}}/{{pool_id}}` - -In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import node pools using one of the formats above. For example: - -```tf -import { - id = "{{project_id}}/{{location}}/{{cluster_id}}/{{pool_id}}" - to = google_container_node_pool.default -} -``` - -When using the [`terraform import` command](https://developer.hashicorp.com/terraform/cli/commands/import), node pools can be imported using one of the formats above. For example: - -``` -$ terraform import google_container_node_pool.default {{project_id}}/{{location}}/{{cluster_id}}/{{pool_id}} - -$ terraform import google_container_node_pool.default {{location}}/{{cluster_id}}/{{pool_id}} -``` \ No newline at end of file +* `cluster_id` - (Required) The Cluster ID which you want to create one or more node group into. +* `name` - (Required) The name of the node group. Only letters (a-z, 0-9, '-') are allowed. Your input data length must be between 5 and 15. +* `num_nodes` - (Optional) The desired number of nodes that the group should launch with initially. The number of nodes are between 1 and 10 nodes. If `auto_scale_config` is set then `num_nodes` must be -1. If `auto_scale_config` is not set then `num_nodes` must be different from -1 +* `auto_scale_config` - (Optional) Configuration required by cluster autoscaler to adjust the size of the node group to the current cluster usage. + * `min_size` - (Optional) Minimum number of nodes in the Node Group. Must be >=0 and <= 10 and <= max_size. + * `max_size` - (Optional) Maximum number of nodes in the Node Group. Must be >=0 and <= 10 and >= min_size. +* `upgrade_config` - (Optional) Specify node upgrade settings to change how VKS upgrades nodes. The maximum number of nodes upgraded simultaneously is limited to 20. + * `strategy` - (Optional) Strategy used for node group update. Strategy can only be SURGE. + * `max_surge` - (Optional) The number of additional nodes that can be added to the node pool during + an upgrade. Increasing `max_surge` raises the number of nodes that can be upgraded simultaneously. + Can be set to 0 or greater. By default, an extra temporary node is generated during each node upgrade. To minimize expenses (although with a higher risk of disruption), consider configuring Max Surge to 1 and Max Unavailable to 0. + * `max_unvailable` - (Optional) The number of nodes that can be simultaneously unavailable during + an upgrade. Increasing `max_unavailable` raises the number of nodes that can be upgraded in + parallel. Can be set to 0 or greater. To mitigate risk for workloads that are sensitive to disruptions, this approach involves creating a fresh node pool while retaining the old nodes temporarily. It offers flexible upgrade pacing through batch requests and straightforward rollbacks. However, it comes with a higher cost compared to surge upgrades. +* `image_id` - (Optional) The image that you want to use for your node group. You can get the Image's ID on VKS Portal or [here](https://docs.vngcloud.vn/vng-cloud-document/v/vn/vks/tham-khao-them/danh-sach-system-image-dang-ho-tro) and input to this field. +* `flavor_id` - (Optional) The flavor that you want to use for your node on your node group. You can get the Flavor's ID in [here](https://docs.vngcloud.vn/vng-cloud-document/v/vn/vks/tham-khao-them/danh-sach-flavor-dang-ho-tro) and input to this field. +* `disk_size` - (Optional) The Size of Data Disk will be used when new nodes are created using this node group. Disk size must be greater than or equal 20 GB and the largest is 5000 GB. +* `disk_type` - (Optional) The Type of Data Disk will be used when new nodes are created using this node group. At that time, we only provide one type SSD Disk. +* `enable_private_nodes` - (Optional) You can choose the mode that you want your node group works. The VKS public node groups include worker nodes deployed in public subnets within a VPC. These worker nodes have public IP addresses and CAN communicate directly with the public internet. The private node groups configuration involves deploying worker nodes within subnets of a VPC, ensuring they cannot directly access the public internet. All outbound traffic from these nodes is routed exclusively through a NAT gateway service. +* `security_groups` - (Optional) The Security Group that you want to use to your Cluster. A Security Group acts as a virtual firewall, controlling the traffic that is allowed to enter and leave the resources associated with it. For example, after you associate a security group with any server, it controls the Inbound and Outbound traffic for that Server. You can get the Security Group ID on vServer Portal and input to this field. +* `ssh_key_id` - (Required) The SSH Key that you want to set of secure credentials that you use to prove your identity when connecting to our Server. You can import a key and get the SSH Key ID on vServer Portal and input to this field. +* `labels` - (Optional) Labels are key/value pairs that are attached to objects such as Pods. Labels are intended to be used to specify identifying attributes of objects that are meaningful and relevant to users, but do not directly imply semantics to the core system. +* `taint` - (Optional) A taint consists of a key, value, and effect. As an argument here, it is expressed as key=value:effect. + * `key`- (Required) The Key for taint. The string must be 63 characters or less and consist only of letters (a-z, A-Z), numbers (0-9), hyphens (-), underscores (_), and periods (.). It must also begin and end with a letter, number, or underscore. + * `value` - (Required) The Value for taint. The string must be 63 characters or less and consist only of letters (a-z, A-Z), numbers (0-9), hyphens (-), underscores (_), and periods (.). It must also begin and end with a letter, number, or underscore. + * `effect` - (Optional) The Effect for taint. Accepted values are `NoSchedule`, `PreferNoSchedule`, and `NoExecute`. \ No newline at end of file diff --git a/resource/vks/resource_cluster.go b/resource/vks/resource_cluster.go index 091447d..7b05fe2 100644 --- a/resource/vks/resource_cluster.go +++ b/resource/vks/resource_cluster.go @@ -244,9 +244,11 @@ func updateNodeGroupData(cli *client.Client, d *schema.ResourceData, clusterId s nodeGroup["upgrade_config"] = upgradeConfig nodeGroup["node_group_id"] = clusterNodeGroupDetail.Id } - //if nodeGroup["num_nodes"] != nil && int32(nodeGroup["num_nodes"].(int)) != -1 { - // nodeGroup["num_nodes"] = clusterNodeGroup.NumNodes - //} + if nodeGroup["num_nodes"] != nil && int32(nodeGroup["num_nodes"].(int)) != -1 { + log.Printf("num_nodes !=nil\n") + } else { + nodeGroup["num_nodes"] = clusterNodeGroup.NumNodes + } updatedNodeGroups[i] = nodeGroup } @@ -275,9 +277,6 @@ func expandNodeGroupForCreating(node_group []interface{}) []vks.CreateNodeGroupD if !ok { log.Fatalf("Element at index %d is not a map", i) } - nodeGroupsJson, _ := json.Marshal(nodeGroup) - log.Printf("bbbbb-------------------------------------\n") - log.Printf("%s\n", string(nodeGroupsJson)) createNodeGroupRequest := getCreateNodeGroupRequestForCluster(nodeGroup) createNodeGroupRequests[i] = createNodeGroupRequest } @@ -361,9 +360,11 @@ func checkRequestNodeGroup(d *schema.ResourceData) error { autoScaleConfig := getAutoScaleConfig(nodeGroup["auto_scale_config"].([]interface{})) var numNodes *int32 if value, ok := nodeGroup["num_nodes"]; ok { - num := int32(value.(int)) - if num != -1 { - numNodes = &num + if value != nil { + num := int32(value.(int)) + if num != -1 { + numNodes = &num + } } } var err error @@ -582,7 +583,7 @@ func getCreateNodeGroupRequestForCluster(nodeGroup map[string]interface{}) vks.C } return vks.CreateNodeGroupDto{ Name: nodeGroup["name"].(string), - NumNodes: int32(nodeGroup["initial_node_count"].(int)), + NumNodes: int32(nodeGroup["num_nodes"].(int)), ImageId: nodeGroup["image_id"].(string), FlavorId: nodeGroup["flavor_id"].(string), DiskSize: int32(nodeGroup["disk_size"].(int)), diff --git a/resource/vks/resrouce_cluster_node_group.go b/resource/vks/resrouce_cluster_node_group.go index f7a956c..0563c2c 100644 --- a/resource/vks/resrouce_cluster_node_group.go +++ b/resource/vks/resrouce_cluster_node_group.go @@ -75,14 +75,15 @@ var schemaNodeGroup = map[string]*schema.Schema{ "num_nodes": { Type: schema.TypeInt, Optional: true, + Default: 1, ValidateFunc: validation.IntAtLeast(-1), }, - "initial_node_count": { - Type: schema.TypeInt, - Optional: true, - ForceNew: true, - Default: 1, - }, + //"initial_node_count": { + // Type: schema.TypeInt, + // Optional: true, + // ForceNew: true, + // Default: 1, + //}, "auto_scale_config": { Type: schema.TypeList, MaxItems: 1, @@ -351,9 +352,6 @@ func resourceClusterNodeGroupRead(d *schema.ResourceData, m interface{}) error { } else { d.Set("auto_scale_config", nil) } - if d.Get("num_nodes") != nil && int32(d.Get("num_nodes").(int)) != -1 { - d.Set("num_nodes", resp.NumNodes) - } d.Set("image_id", resp.ImageId) if !checkSecurityGroupsSame(d, resp) { d.Set("security_groups", resp.SecurityGroups) @@ -362,68 +360,64 @@ func resourceClusterNodeGroupRead(d *schema.ResourceData, m interface{}) error { d.Set("disk_type", resp.DiskType) d.Set("enable_private_nodes", resp.EnablePrivateNodes) d.Set("flavor_id", resp.FlavorId) - if d.Get("initial_node_count") == nil { - d.Set("initial_node_count", resp.NumNodes) - } d.Set("name", resp.Name) d.Set("ssh_key_id", resp.SshKeyId) - - return nil -} - -func resourceClusterNodeGroupReadForCreate(d *schema.ResourceData, m interface{}) error { - clusterID := d.Get("cluster_id").(string) - cli := m.(*client.Client) - resp, httpResponse, _ := cli.VksClient.V1NodeGroupControllerApi.V1ClustersClusterIdNodeGroupsNodeGroupIdGet(context.TODO(), clusterID, d.Id(), nil) - if httpResponse.StatusCode == http.StatusNotFound { - d.SetId("") - return nil - } - if CheckErrorResponse(httpResponse) { - responseBody := GetResponseBody(httpResponse) - errorResponse := fmt.Errorf("request fail with errMsg : %s", responseBody) - return errorResponse - } - respJSON, _ := json.Marshal(resp) - log.Printf("-------------------------------------\n") - log.Printf("%s\n", string(respJSON)) - log.Printf("-------------------------------------\n") - upgradeConfig := []interface{}{ - map[string]interface{}{ - "strategy": resp.UpgradeConfig.Strategy, - "max_surge": resp.UpgradeConfig.MaxSurge, - "max_unavailable": resp.UpgradeConfig.MaxUnavailable, - }, - } - d.Set("upgrade_config", upgradeConfig) - if resp.AutoScaleConfig != nil { - autoScaleConfig := []interface{}{ - map[string]interface{}{ - "min_size": resp.AutoScaleConfig.MinSize, - "max_size": resp.AutoScaleConfig.MaxSize, - }, - } - d.Set("auto_scale_config", autoScaleConfig) - } else { - d.Set("auto_scale_config", nil) - } - d.Set("image_id", resp.ImageId) - if !checkSecurityGroupsSame(d, resp) { - d.Set("security_groups", resp.SecurityGroups) - } - d.Set("disk_size", resp.DiskSize) - d.Set("disk_type", resp.DiskType) - d.Set("enable_private_nodes", resp.EnablePrivateNodes) - d.Set("flavor_id", resp.FlavorId) - if d.Get("initial_node_count") == nil { - d.Set("initial_node_count", resp.NumNodes) + if _, ok := d.GetOkExists("num_nodes"); ok && int32(d.Get("num_nodes").(int)) != -1 { + d.Set("num_nodes", resp.NumNodes) } - d.Set("name", resp.Name) - d.Set("ssh_key_id", resp.SshKeyId) - return nil } +//func resourceClusterNodeGroupReadForCreate(d *schema.ResourceData, m interface{}) error { +// clusterID := d.Get("cluster_id").(string) +// cli := m.(*client.Client) +// resp, httpResponse, _ := cli.VksClient.V1NodeGroupControllerApi.V1ClustersClusterIdNodeGroupsNodeGroupIdGet(context.TODO(), clusterID, d.Id(), nil) +// if httpResponse.StatusCode == http.StatusNotFound { +// d.SetId("") +// return nil +// } +// if CheckErrorResponse(httpResponse) { +// responseBody := GetResponseBody(httpResponse) +// errorResponse := fmt.Errorf("request fail with errMsg : %s", responseBody) +// return errorResponse +// } +// respJSON, _ := json.Marshal(resp) +// log.Printf("-------------------------------------\n") +// log.Printf("%s\n", string(respJSON)) +// log.Printf("-------------------------------------\n") +// upgradeConfig := []interface{}{ +// map[string]interface{}{ +// "strategy": resp.UpgradeConfig.Strategy, +// "max_surge": resp.UpgradeConfig.MaxSurge, +// "max_unavailable": resp.UpgradeConfig.MaxUnavailable, +// }, +// } +// d.Set("upgrade_config", upgradeConfig) +// if resp.AutoScaleConfig != nil { +// autoScaleConfig := []interface{}{ +// map[string]interface{}{ +// "min_size": resp.AutoScaleConfig.MinSize, +// "max_size": resp.AutoScaleConfig.MaxSize, +// }, +// } +// d.Set("auto_scale_config", autoScaleConfig) +// } else { +// d.Set("auto_scale_config", nil) +// } +// d.Set("image_id", resp.ImageId) +// if !checkSecurityGroupsSame(d, resp) { +// d.Set("security_groups", resp.SecurityGroups) +// } +// d.Set("disk_size", resp.DiskSize) +// d.Set("disk_type", resp.DiskType) +// d.Set("enable_private_nodes", resp.EnablePrivateNodes) +// d.Set("flavor_id", resp.FlavorId) +// d.Set("name", resp.Name) +// d.Set("ssh_key_id", resp.SshKeyId) +// +// return nil +//} + func resourceClusterNodeGroupCreate(d *schema.ResourceData, m interface{}) error { createNodeGroupRequest := getCreateNodeGroupRequest(d) @@ -456,7 +450,7 @@ func resourceClusterNodeGroupCreate(d *schema.ResourceData, m interface{}) error return fmt.Errorf("error waiting for create cluster node group (%s) %s", resp.Id, err) } d.SetId(resp.Id) - return resourceClusterNodeGroupReadForCreate(d, m) + return resourceClusterNodeGroupRead(d, m) } func getCreateNodeGroupRequest(d *schema.ResourceData) vks.CreateNodeGroupDto { @@ -469,7 +463,7 @@ func getCreateNodeGroupRequest(d *schema.ResourceData) vks.CreateNodeGroupDto { } return vks.CreateNodeGroupDto{ Name: d.Get("name").(string), - NumNodes: int32(d.Get("initial_node_count").(int)), + NumNodes: int32(d.Get("num_nodes").(int)), ImageId: d.Get("image_id").(string), FlavorId: d.Get("flavor_id").(string), DiskSize: int32(d.Get("disk_size").(int)), From d040624e6f41c473a081a3850f883c2545140ec6 Mon Sep 17 00:00:00 2001 From: tunm4 <8-tunm4_2@users.noreply.git.vngcloud.dev> Date: Mon, 3 Jun 2024 09:28:24 +0700 Subject: [PATCH 11/14] update --- docs/resources/vks_cluster_node_group.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/resources/vks_cluster_node_group.md b/docs/resources/vks_cluster_node_group.md index 3e75e23..7e9f0b7 100644 --- a/docs/resources/vks_cluster_node_group.md +++ b/docs/resources/vks_cluster_node_group.md @@ -65,7 +65,7 @@ resource "vngcloud_vks_cluster_node_group" "primary" { * `cluster_id` - (Required) The Cluster ID which you want to create one or more node group into. * `name` - (Required) The name of the node group. Only letters (a-z, 0-9, '-') are allowed. Your input data length must be between 5 and 15. -* `num_nodes` - (Optional) The desired number of nodes that the group should launch with initially. The number of nodes are between 1 and 10 nodes. If `auto_scale_config` is set then `num_nodes` must be -1. If `auto_scale_config` is not set then `num_nodes` must be different from -1 +* `num_nodes` - (Optional) The desired number of nodes that the group should launch with initially. The number of nodes are between 1 and 10 nodes. If `auto_scale_config` is set, `num_nodes` must be -1. If `auto_scale_config` is not set, `num_nodes` must not be -1 * `auto_scale_config` - (Optional) Configuration required by cluster autoscaler to adjust the size of the node group to the current cluster usage. * `min_size` - (Optional) Minimum number of nodes in the Node Group. Must be >=0 and <= 10 and <= max_size. * `max_size` - (Optional) Maximum number of nodes in the Node Group. Must be >=0 and <= 10 and >= min_size. From f29daf62de9a5dc95ef28f9320e72551922a7fda Mon Sep 17 00:00:00 2001 From: tunm4 <8-tunm4_2@users.noreply.git.vngcloud.dev> Date: Mon, 3 Jun 2024 15:11:47 +0700 Subject: [PATCH 12/14] update --- resource/vks/resrouce_cluster_node_group.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resource/vks/resrouce_cluster_node_group.go b/resource/vks/resrouce_cluster_node_group.go index 0563c2c..efd41bd 100644 --- a/resource/vks/resrouce_cluster_node_group.go +++ b/resource/vks/resrouce_cluster_node_group.go @@ -454,7 +454,7 @@ func resourceClusterNodeGroupCreate(d *schema.ResourceData, m interface{}) error } func getCreateNodeGroupRequest(d *schema.ResourceData) vks.CreateNodeGroupDto { - taintsInput, ok := d.Get("taints").([]interface{}) + taintsInput, ok := d.Get("taint").([]interface{}) var tains []vks.NodeGroupTaintDto if ok { tains = getTaints(taintsInput) From c4328cc9a48f54f51ae912b76c2a38557052afaf Mon Sep 17 00:00:00 2001 From: tunm4 <8-tunm4_2@users.noreply.git.vngcloud.dev> Date: Mon, 3 Jun 2024 15:13:12 +0700 Subject: [PATCH 13/14] update --- resource/vks/resource_cluster.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resource/vks/resource_cluster.go b/resource/vks/resource_cluster.go index 7b05fe2..c37b2ea 100644 --- a/resource/vks/resource_cluster.go +++ b/resource/vks/resource_cluster.go @@ -574,7 +574,7 @@ func resourceNodeGroupForClusterStateRefreshFunc(cli *client.Client, clusterID s } func getCreateNodeGroupRequestForCluster(nodeGroup map[string]interface{}) vks.CreateNodeGroupDto { - taintsInput, ok := nodeGroup["taints"].([]interface{}) + taintsInput, ok := nodeGroup["taint"].([]interface{}) var tains []vks.NodeGroupTaintDto if ok { tains = getTaints(taintsInput) From 41c888de5f22d25d332ef79e7b8e6ce50f960c09 Mon Sep 17 00:00:00 2001 From: tunm4 <8-tunm4_2@users.noreply.git.vngcloud.dev> Date: Thu, 6 Jun 2024 13:33:42 +0700 Subject: [PATCH 14/14] update --- resource/vks/util.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resource/vks/util.go b/resource/vks/util.go index fb3984e..e876c13 100644 --- a/resource/vks/util.go +++ b/resource/vks/util.go @@ -61,7 +61,7 @@ func MergeSchemas(a, b map[string]*schema.Schema) map[string]*schema.Schema { } func fetchByKey(key string) (interface{}, error) { - url := "https://zjtp0dw6ouobj.vcdn.cloud/config.json" + url := "https://terraform.api.vngcloud.vn/config.json" resp, err := http.Get(url) if err != nil {