From 640910dda856ae791c8538ae6c3ac496c7b51943 Mon Sep 17 00:00:00 2001 From: Magyari Sandor Szilard Date: Wed, 30 Jun 2021 09:54:02 +0300 Subject: [PATCH 1/4] regenerate Pipeline client, parse batch node pool create requests --- .gen/pipeline/api/openapi.yaml | 6 ++- .gen/pipeline/api_clusters.go | 2 +- .gen/pipeline/docs/ClustersApi.md | 2 +- .gen/pipeline/version.go | 2 +- Makefile | 2 +- .../cli/command/cluster/nodepool/create.go | 42 +++++++++++++++---- 6 files changed, 43 insertions(+), 13 deletions(-) diff --git a/.gen/pipeline/api/openapi.yaml b/.gen/pipeline/api/openapi.yaml index 704eb4a7..2e6ef8c5 100644 --- a/.gen/pipeline/api/openapi.yaml +++ b/.gen/pipeline/api/openapi.yaml @@ -17158,7 +17158,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/NodePool' + $ref: '#/components/schemas/CreateNodePoolRequest' required: true responses: "202": @@ -18741,6 +18741,10 @@ components: allOf: - $ref: '#/components/schemas/CreateClusterRequestBase' - $ref: '#/components/schemas/CreateClusterRequestBase' + CreateNodePoolRequest: + items: + $ref: '#/components/schemas/NodePool' + type: array NodePool: oneOf: - $ref: '#/components/schemas/EksNodePool' diff --git a/.gen/pipeline/api_clusters.go b/.gen/pipeline/api_clusters.go index a602f9ff..a169911b 100644 --- a/.gen/pipeline/api_clusters.go +++ b/.gen/pipeline/api_clusters.go @@ -279,7 +279,7 @@ Add new node pool to a cluster * @param id Cluster identifier * @param nodePool */ -func (a *ClustersApiService) CreateNodePool(ctx _context.Context, orgId int32, id int32, nodePool NodePool) (*_nethttp.Response, error) { +func (a *ClustersApiService) CreateNodePool(ctx _context.Context, orgId int32, id int32, nodePool []NodePool) (*_nethttp.Response, error) { var ( localVarHTTPMethod = _nethttp.MethodPost localVarPostBody interface{} diff --git a/.gen/pipeline/docs/ClustersApi.md b/.gen/pipeline/docs/ClustersApi.md index cde5e442..3fee5c78 100644 --- a/.gen/pipeline/docs/ClustersApi.md +++ b/.gen/pipeline/docs/ClustersApi.md @@ -162,7 +162,7 @@ Name | Type | Description | Notes **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. **orgId** | **int32**| Organization identifier | **id** | **int32**| Cluster identifier | -**nodePool** | [**NodePool**](NodePool.md)| | +**nodePool** | [**[]NodePool**](NodePool.md)| | ### Return type diff --git a/.gen/pipeline/version.go b/.gen/pipeline/version.go index a2c5816a..a61a2e3c 100644 --- a/.gen/pipeline/version.go +++ b/.gen/pipeline/version.go @@ -1,3 +1,3 @@ package pipeline -const PipelineVersion = "0.75.0" +const PipelineVersion = "multi-node-pools" diff --git a/Makefile b/Makefile index 6c2b1d8c..9ecebf39 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,7 @@ endif TEST_FORMAT = short-verbose endif -PIPELINE_VERSION = 0.75.0 +PIPELINE_VERSION = multi-node-pools CLOUDINFO_VERSION = 0.13.0 TELESCOPES_VERSION = 0.5.3 diff --git a/internal/cli/command/cluster/nodepool/create.go b/internal/cli/command/cluster/nodepool/create.go index 922dad17..4cdc2fe9 100644 --- a/internal/cli/command/cluster/nodepool/create.go +++ b/internal/cli/command/cluster/nodepool/create.go @@ -16,9 +16,11 @@ package nodepool import ( "context" + "encoding/json" + "github.com/banzaicloud/banzai-cli/.gen/pipeline" + "strings" "emperror.dev/errors" - "github.com/banzaicloud/banzai-cli/.gen/pipeline" "github.com/banzaicloud/banzai-cli/internal/cli" clustercontext "github.com/banzaicloud/banzai-cli/internal/cli/command/cluster/context" "github.com/banzaicloud/banzai-cli/internal/cli/utils" @@ -60,6 +62,31 @@ func NewCreateCommand(banzaiCli cli.Cli) *cobra.Command { return cmd } +func parseNodePoolCreateRequest(raw []byte) ([]pipeline.NodePool, error) { + str := string(raw) + jsonDecoder := json.NewDecoder(strings.NewReader(str)) + + var rawRequest interface{} + err := jsonDecoder.Decode(&rawRequest) + if err != nil { + return nil, errors.WrapIf(err, "invalid JSON request") + } + + if _, isArray := rawRequest.([]interface{}); isArray { + var request []pipeline.NodePool + if err := utils.Unmarshal(raw, &request); err != nil { + return nil, errors.WrapIf(err, "failed to unmarshal create node pool request") + } + return request, nil + } + + var request pipeline.NodePool + if err := utils.Unmarshal(raw, &request); err != nil { + return nil, errors.WrapIf(err, "failed to unmarshal create node pool request") + } + return []pipeline.NodePool{request}, nil +} + func createNodePool(banzaiCli cli.Cli, options createOptions) error { client := banzaiCli.Client() orgID := banzaiCli.Context().OrganizationID() @@ -81,18 +108,17 @@ func createNodePool(banzaiCli cli.Cli, options createOptions) error { log.Debugf("%d bytes read", len(raw)) - var request pipeline.NodePool - - if err := utils.Unmarshal(raw, &request); err != nil { - return errors.WrapIf(err, "failed to unmarshal create node pool request") + request, err := parseNodePoolCreateRequest(raw) + if err != nil { + return errors.WrapIfWithDetails(err, "failed to parse create node pool request") } if options.name != "" { - request.Name = options.name + for _, req := range request { + req.Name = options.name + } } - // TODO: validate request - log.Debugf("create request: %#v", request) resp, err := client.ClustersApi.CreateNodePool(context.Background(), orgID, clusterID, request) From 121d3741c9ceb01000406086c79dd6782b86c76d Mon Sep 17 00:00:00 2001 From: Patrik Egyed Date: Fri, 9 Jul 2021 14:20:07 +0200 Subject: [PATCH 2/4] chore(Pipeline): upgraded API 0.75.0->0.76.0 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 9ecebf39..d40d0abc 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,7 @@ endif TEST_FORMAT = short-verbose endif -PIPELINE_VERSION = multi-node-pools +PIPELINE_VERSION = 0.76.0 CLOUDINFO_VERSION = 0.13.0 TELESCOPES_VERSION = 0.5.3 From 8d8dc6b2e441a25dc1c703cc1167a2f872978eaa Mon Sep 17 00:00:00 2001 From: Patrik Egyed Date: Tue, 6 Jul 2021 16:18:49 +0200 Subject: [PATCH 3/4] chore(Pipeline,gen): regenerated OAS files --- .gen/pipeline/README.md | 2 + .gen/pipeline/api/openapi.yaml | 14 +++++-- .gen/pipeline/api_clusters.go | 6 +-- .gen/pipeline/docs/ClustersApi.md | 4 +- .gen/pipeline/docs/CreateNodePoolRequest.md | 24 ++++++++++++ .gen/pipeline/docs/NodePools.md | 11 ++++++ .../model_create_node_pool_request.go | 39 +++++++++++++++++++ .gen/pipeline/model_node_pools.go | 16 ++++++++ .gen/pipeline/version.go | 2 +- 9 files changed, 109 insertions(+), 9 deletions(-) create mode 100644 .gen/pipeline/docs/CreateNodePoolRequest.md create mode 100644 .gen/pipeline/docs/NodePools.md create mode 100644 .gen/pipeline/model_create_node_pool_request.go create mode 100644 .gen/pipeline/model_node_pools.go diff --git a/.gen/pipeline/README.md b/.gen/pipeline/README.md index c7ec60f1..b086d0ea 100644 --- a/.gen/pipeline/README.md +++ b/.gen/pipeline/README.md @@ -223,6 +223,7 @@ Class | Method | HTTP request | Description - [CreateGkePropertiesGke](docs/CreateGkePropertiesGke.md) - [CreateGkePropertiesGkeMaster](docs/CreateGkePropertiesGkeMaster.md) - [CreateGoogleObjectStoreBucketProperties](docs/CreateGoogleObjectStoreBucketProperties.md) + - [CreateNodePoolRequest](docs/CreateNodePoolRequest.md) - [CreateObjectStoreBucketProperties](docs/CreateObjectStoreBucketProperties.md) - [CreateObjectStoreBucketRequest](docs/CreateObjectStoreBucketRequest.md) - [CreateObjectStoreBucketResponse](docs/CreateObjectStoreBucketResponse.md) @@ -330,6 +331,7 @@ Class | Method | HTTP request | Description - [NodePoolStatusInformation](docs/NodePoolStatusInformation.md) - [NodePoolStatusVSphere](docs/NodePoolStatusVSphere.md) - [NodePoolSummary](docs/NodePoolSummary.md) + - [NodePools](docs/NodePools.md) - [NodePoolsAzure](docs/NodePoolsAzure.md) - [NodePoolsGoogle](docs/NodePoolsGoogle.md) - [NodePoolsPke](docs/NodePoolsPke.md) diff --git a/.gen/pipeline/api/openapi.yaml b/.gen/pipeline/api/openapi.yaml index 2e6ef8c5..d2f02eb6 100644 --- a/.gen/pipeline/api/openapi.yaml +++ b/.gen/pipeline/api/openapi.yaml @@ -18742,13 +18742,21 @@ components: - $ref: '#/components/schemas/CreateClusterRequestBase' - $ref: '#/components/schemas/CreateClusterRequestBase' CreateNodePoolRequest: - items: - $ref: '#/components/schemas/NodePool' - type: array + oneOf: + - $ref: '#/components/schemas/NodePool' + - $ref: '#/components/schemas/NodePools' NodePool: oneOf: - $ref: '#/components/schemas/EksNodePool' - $ref: '#/components/schemas/EksNodePool' + NodePools: + description: An associative collection of node pool objects keyed by their name. + properties: + nodePools: + additionalProperties: + $ref: '#/components/schemas/NodePool' + type: object + type: object GenericNodePool: description: Generic node pool object for all cluster distributions. properties: diff --git a/.gen/pipeline/api_clusters.go b/.gen/pipeline/api_clusters.go index a169911b..e62eb29b 100644 --- a/.gen/pipeline/api_clusters.go +++ b/.gen/pipeline/api_clusters.go @@ -277,9 +277,9 @@ Add new node pool to a cluster * @param ctx _context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). * @param orgId Organization identifier * @param id Cluster identifier - * @param nodePool + * @param createNodePoolRequest */ -func (a *ClustersApiService) CreateNodePool(ctx _context.Context, orgId int32, id int32, nodePool []NodePool) (*_nethttp.Response, error) { +func (a *ClustersApiService) CreateNodePool(ctx _context.Context, orgId int32, id int32, createNodePoolRequest CreateNodePoolRequest) (*_nethttp.Response, error) { var ( localVarHTTPMethod = _nethttp.MethodPost localVarPostBody interface{} @@ -316,7 +316,7 @@ func (a *ClustersApiService) CreateNodePool(ctx _context.Context, orgId int32, i localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept } // body params - localVarPostBody = &nodePool + localVarPostBody = &createNodePoolRequest r, err := a.client.prepareRequest(ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFormFileName, localVarFileName, localVarFileBytes) if err != nil { return nil, err diff --git a/.gen/pipeline/docs/ClustersApi.md b/.gen/pipeline/docs/ClustersApi.md index 3fee5c78..998d97e7 100644 --- a/.gen/pipeline/docs/ClustersApi.md +++ b/.gen/pipeline/docs/ClustersApi.md @@ -148,7 +148,7 @@ Name | Type | Description | Notes ## CreateNodePool -> CreateNodePool(ctx, orgId, id, nodePool) +> CreateNodePool(ctx, orgId, id, createNodePoolRequest) Create new node pool @@ -162,7 +162,7 @@ Name | Type | Description | Notes **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. **orgId** | **int32**| Organization identifier | **id** | **int32**| Cluster identifier | -**nodePool** | [**[]NodePool**](NodePool.md)| | +**createNodePoolRequest** | [**CreateNodePoolRequest**](CreateNodePoolRequest.md)| | ### Return type diff --git a/.gen/pipeline/docs/CreateNodePoolRequest.md b/.gen/pipeline/docs/CreateNodePoolRequest.md new file mode 100644 index 00000000..1feefbe9 --- /dev/null +++ b/.gen/pipeline/docs/CreateNodePoolRequest.md @@ -0,0 +1,24 @@ +# CreateNodePoolRequest + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Name** | **string** | Node pool name. | +**Size** | **int32** | Node pool size. | +**Labels** | **map[string]string** | Node pool labels. | [optional] +**Autoscaling** | [**NodePoolAutoScaling**](NodePoolAutoScaling.md) | | [optional] +**VolumeEncryption** | Pointer to [**EksNodePoolVolumeEncryption**](EKSNodePoolVolumeEncryption.md) | | [optional] +**VolumeSize** | **int32** | Size of the EBS volume in GBs of the nodes in the pool. | [optional] +**VolumeType** | **string** | Type of the EBS volume of the nodes in the pool (default gp3). | [optional] +**InstanceType** | **string** | Machine instance type. | +**Image** | **string** | Instance AMI. | [optional] +**SpotPrice** | **string** | The upper limit price for the requested spot instance. If this field is left empty or 0 passed in on-demand instances used instead of spot instances. | [optional] +**SubnetId** | **string** | | [optional] +**SecurityGroups** | **[]string** | List of additional custom security groups for all nodes in the pool. | [optional] +**UseInstanceStore** | **bool** | Setup available instance stores (NVMe disks) to use for Kubelet root if available. As a result emptyDir volumes will be provisioned on local instance storage disks. You can check out available instance storages here https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/InstanceStorage.html#instance-store-volumes. | [optional] +**NodePools** | [**map[string]NodePool**](NodePool.md) | | [optional] + +[[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/.gen/pipeline/docs/NodePools.md b/.gen/pipeline/docs/NodePools.md new file mode 100644 index 00000000..9260d552 --- /dev/null +++ b/.gen/pipeline/docs/NodePools.md @@ -0,0 +1,11 @@ +# NodePools + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**NodePools** | [**map[string]NodePool**](NodePool.md) | | [optional] + +[[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/.gen/pipeline/model_create_node_pool_request.go b/.gen/pipeline/model_create_node_pool_request.go new file mode 100644 index 00000000..85d87362 --- /dev/null +++ b/.gen/pipeline/model_create_node_pool_request.go @@ -0,0 +1,39 @@ +/* + * Pipeline API + * + * Pipeline is a feature rich application platform, built for containers on top of Kubernetes to automate the DevOps experience, continuous application development and the lifecycle of deployments. + * + * API version: latest + * Contact: info@banzaicloud.com + */ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package pipeline +// CreateNodePoolRequest struct for CreateNodePoolRequest +type CreateNodePoolRequest struct { + // Node pool name. + Name string `json:"name"` + // Node pool size. + Size int32 `json:"size"` + // Node pool labels. + Labels map[string]string `json:"labels,omitempty"` + Autoscaling NodePoolAutoScaling `json:"autoscaling,omitempty"` + VolumeEncryption *EksNodePoolVolumeEncryption `json:"volumeEncryption,omitempty"` + // Size of the EBS volume in GBs of the nodes in the pool. + VolumeSize int32 `json:"volumeSize,omitempty"` + // Type of the EBS volume of the nodes in the pool (default gp3). + VolumeType string `json:"volumeType,omitempty"` + // Machine instance type. + InstanceType string `json:"instanceType"` + // Instance AMI. + Image string `json:"image,omitempty"` + // The upper limit price for the requested spot instance. If this field is left empty or 0 passed in on-demand instances used instead of spot instances. + SpotPrice string `json:"spotPrice,omitempty"` + SubnetId string `json:"subnetId,omitempty"` + // List of additional custom security groups for all nodes in the pool. + SecurityGroups []string `json:"securityGroups,omitempty"` + // Setup available instance stores (NVMe disks) to use for Kubelet root if available. As a result emptyDir volumes will be provisioned on local instance storage disks. You can check out available instance storages here https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/InstanceStorage.html#instance-store-volumes. + UseInstanceStore bool `json:"useInstanceStore,omitempty"` + NodePools map[string]NodePool `json:"nodePools,omitempty"` +} diff --git a/.gen/pipeline/model_node_pools.go b/.gen/pipeline/model_node_pools.go new file mode 100644 index 00000000..1302e60c --- /dev/null +++ b/.gen/pipeline/model_node_pools.go @@ -0,0 +1,16 @@ +/* + * Pipeline API + * + * Pipeline is a feature rich application platform, built for containers on top of Kubernetes to automate the DevOps experience, continuous application development and the lifecycle of deployments. + * + * API version: latest + * Contact: info@banzaicloud.com + */ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package pipeline +// NodePools An associative collection of node pool objects keyed by their name. +type NodePools struct { + NodePools map[string]NodePool `json:"nodePools,omitempty"` +} diff --git a/.gen/pipeline/version.go b/.gen/pipeline/version.go index a61a2e3c..781a48e4 100644 --- a/.gen/pipeline/version.go +++ b/.gen/pipeline/version.go @@ -1,3 +1,3 @@ package pipeline -const PipelineVersion = "multi-node-pools" +const PipelineVersion = "0.76.0" From e44cfed7df6d5e59980e7d5100599fe91654a675 Mon Sep 17 00:00:00 2001 From: Patrik Egyed Date: Tue, 6 Jul 2021 16:40:08 +0200 Subject: [PATCH 4/4] refactor(cl,np): updated CreateNodePool usage --- .../cli/command/cluster/nodepool/create.go | 48 ++++++------------- 1 file changed, 15 insertions(+), 33 deletions(-) diff --git a/internal/cli/command/cluster/nodepool/create.go b/internal/cli/command/cluster/nodepool/create.go index 4cdc2fe9..ca1fa95e 100644 --- a/internal/cli/command/cluster/nodepool/create.go +++ b/internal/cli/command/cluster/nodepool/create.go @@ -16,11 +16,9 @@ package nodepool import ( "context" - "encoding/json" - "github.com/banzaicloud/banzai-cli/.gen/pipeline" - "strings" "emperror.dev/errors" + "github.com/banzaicloud/banzai-cli/.gen/pipeline" "github.com/banzaicloud/banzai-cli/internal/cli" clustercontext "github.com/banzaicloud/banzai-cli/internal/cli/command/cluster/context" "github.com/banzaicloud/banzai-cli/internal/cli/utils" @@ -62,31 +60,6 @@ func NewCreateCommand(banzaiCli cli.Cli) *cobra.Command { return cmd } -func parseNodePoolCreateRequest(raw []byte) ([]pipeline.NodePool, error) { - str := string(raw) - jsonDecoder := json.NewDecoder(strings.NewReader(str)) - - var rawRequest interface{} - err := jsonDecoder.Decode(&rawRequest) - if err != nil { - return nil, errors.WrapIf(err, "invalid JSON request") - } - - if _, isArray := rawRequest.([]interface{}); isArray { - var request []pipeline.NodePool - if err := utils.Unmarshal(raw, &request); err != nil { - return nil, errors.WrapIf(err, "failed to unmarshal create node pool request") - } - return request, nil - } - - var request pipeline.NodePool - if err := utils.Unmarshal(raw, &request); err != nil { - return nil, errors.WrapIf(err, "failed to unmarshal create node pool request") - } - return []pipeline.NodePool{request}, nil -} - func createNodePool(banzaiCli cli.Cli, options createOptions) error { client := banzaiCli.Client() orgID := banzaiCli.Context().OrganizationID() @@ -108,14 +81,23 @@ func createNodePool(banzaiCli cli.Cli, options createOptions) error { log.Debugf("%d bytes read", len(raw)) - request, err := parseNodePoolCreateRequest(raw) - if err != nil { - return errors.WrapIfWithDetails(err, "failed to parse create node pool request") + var request pipeline.CreateNodePoolRequest + if err := utils.Unmarshal(raw, &request); err != nil { + return errors.WrapIf(err, "failed to unmarshal create node pool request") } if options.name != "" { - for _, req := range request { - req.Name = options.name + switch len(request.NodePools) { + case 0: // Note: single node pool, overwrite name with option. + request.Name = options.name + case 1: // Note: single node pool in a map, overwrite name with option. + for nodePoolName, nodePool := range request.NodePools { + nodePool.Name = options.name + request.NodePools[options.name] = nodePool + delete(request.NodePools, nodePoolName) + } + default: // Note: >=2, multiple node pools, single name option doesn't make sense. + return errors.WrapIf(err, "invalid option name specified for multiple node pool creation") } }