Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add additional fields to GCPManagedMachinePool #944

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions cloud/scope/managedmachinepool.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"context"
"fmt"

"k8s.io/utils/pointer"
"sigs.k8s.io/cluster-api-provider-gcp/cloud"
"sigs.k8s.io/cluster-api-provider-gcp/util/location"

Expand Down Expand Up @@ -170,6 +171,10 @@ func ConvertToSdkNodePool(nodePool infrav1exp.GCPManagedMachinePool, machinePool
Labels: nodePool.Spec.KubernetesLabels,
Taints: infrav1exp.ConvertToSdkTaint(nodePool.Spec.KubernetesTaints),
Metadata: nodePool.Spec.AdditionalLabels,
ShieldedInstanceConfig: &containerpb.ShieldedInstanceConfig{
EnableSecureBoot: pointer.BoolDeref(nodePool.Spec.NodeSecurity.EnableSecureBoot, false),
EnableIntegrityMonitoring: pointer.BoolDeref(nodePool.Spec.NodeSecurity.EnableIntegrityMonitoring, false),
},
},
}
if nodePool.Spec.Scaling != nil {
Expand All @@ -179,6 +184,48 @@ func ConvertToSdkNodePool(nodePool infrav1exp.GCPManagedMachinePool, machinePool
MaxNodeCount: *nodePool.Spec.Scaling.MaxCount,
}
}
if nodePool.Spec.InstanceType != nil {
sdkNodePool.Config.MachineType = *nodePool.Spec.InstanceType
}
if nodePool.Spec.ImageType != nil {
sdkNodePool.Config.ImageType = *nodePool.Spec.ImageType
}
if nodePool.Spec.DiskType != nil {
sdkNodePool.Config.DiskType = string(*nodePool.Spec.DiskType)
}
if nodePool.Spec.DiskSizeGB != nil {
sdkNodePool.Config.DiskSizeGb = int32(*nodePool.Spec.DiskSizeGB)
}
if len(nodePool.Spec.NodeNetwork.Tags) != 0 {
sdkNodePool.Config.Tags = nodePool.Spec.NodeNetwork.Tags
}
if nodePool.Spec.NodeSecurity.ServiceAccount.Email != nil {
sdkNodePool.Config.ServiceAccount = *nodePool.Spec.NodeSecurity.ServiceAccount.Email
}
if len(nodePool.Spec.NodeSecurity.ServiceAccount.Scopes) != 0 {
sdkNodePool.Config.OauthScopes = nodePool.Spec.NodeSecurity.ServiceAccount.Scopes
}
if len(nodePool.Spec.NodeLocations) != 0 {
sdkNodePool.Locations = nodePool.Spec.NodeLocations
}
if nodePool.Spec.MaxPodsPerNode != nil {
sdkNodePool.MaxPodsConstraint = &containerpb.MaxPodsConstraint{
MaxPodsPerNode: *nodePool.Spec.MaxPodsPerNode,
}
}
if nodePool.Spec.NodeNetwork.CreatePodRange != nil && nodePool.Spec.NodeNetwork.PodRangeName != nil && nodePool.Spec.NodeNetwork.PodRangeCidrBlock != nil {
sdkNodePool.NetworkConfig = &containerpb.NodeNetworkConfig{
CreatePodRange: *nodePool.Spec.NodeNetwork.CreatePodRange,
PodRange: *nodePool.Spec.NodeNetwork.PodRangeName,
PodIpv4CidrBlock: *nodePool.Spec.NodeNetwork.PodRangeCidrBlock,
}
}

if pointer.StringDeref(nodePool.Spec.NodeSecurity.SandboxType, "") == "GVISOR" {
sdkNodePool.Config.SandboxConfig = &containerpb.SandboxConfig{
Type: containerpb.SandboxConfig_GVISOR,
}
}
if machinePool.Spec.Template.Spec.Version != nil {
sdkNodePool.Version = *machinePool.Spec.Template.Spec.Version
}
Expand Down
52 changes: 37 additions & 15 deletions cloud/services/container/nodepools/reconcile.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
"cloud.google.com/go/compute/apiv1/computepb"
"cloud.google.com/go/container/apiv1/containerpb"
"github.com/go-logr/logr"
"github.com/google/go-cmp/cmp"
"github.com/googleapis/gax-go/v2/apierror"
"github.com/pkg/errors"
"sigs.k8s.io/cluster-api-provider-gcp/cloud/providerid"
Expand Down Expand Up @@ -127,14 +128,14 @@ func (s *Service) Reconcile(ctx context.Context) (ctrl.Result, error) {
return ctrl.Result{}, nil
}

needUpdateVersionOrImage, nodePoolUpdateVersionOrImage := s.checkDiffAndPrepareUpdateVersionOrImage(nodePool)
if needUpdateVersionOrImage {
log.Info("Version/image update required")
err = s.updateNodePoolVersionOrImage(ctx, nodePoolUpdateVersionOrImage)
needUpdateNodePool, nodePoolUpdateNodePool := s.checkDiffAndPrepareUpdateNodePool(nodePool)
if needUpdateNodePool {
log.Info("Node pool config update required")
err = s.updateNodePool(ctx, nodePoolUpdateNodePool)
if err != nil {
return ctrl.Result{}, err
return ctrl.Result{}, fmt.Errorf("node pool config update (either version/labels/taints/locations/image type/network tag or all) failed: %s", err)
}
log.Info("Node pool version/image updating in progress")
log.Info("Node pool config updating in progress")
s.scope.GCPManagedMachinePool.Status.Ready = true
conditions.MarkTrue(s.scope.ConditionSetter(), infrav1exp.GKEMachinePoolUpdatingCondition)
return ctrl.Result{RequeueAfter: reconciler.DefaultRetryTime}, nil
Expand Down Expand Up @@ -290,26 +291,26 @@ func (s *Service) createNodePool(ctx context.Context, log *logr.Logger) error {
return nil
}

func (s *Service) updateNodePoolVersionOrImage(ctx context.Context, updateNodePoolRequest *containerpb.UpdateNodePoolRequest) error {
_, err := s.scope.ManagedMachinePoolClient().UpdateNodePool(ctx, updateNodePoolRequest)
func (s *Service) updateNodePoolAutoscaling(ctx context.Context, setNodePoolAutoscalingRequest *containerpb.SetNodePoolAutoscalingRequest) error {
_, err := s.scope.ManagedMachinePoolClient().SetNodePoolAutoscaling(ctx, setNodePoolAutoscalingRequest)
if err != nil {
return err
}

return nil
}

func (s *Service) updateNodePoolAutoscaling(ctx context.Context, setNodePoolAutoscalingRequest *containerpb.SetNodePoolAutoscalingRequest) error {
_, err := s.scope.ManagedMachinePoolClient().SetNodePoolAutoscaling(ctx, setNodePoolAutoscalingRequest)
func (s *Service) updateNodePoolSize(ctx context.Context, setNodePoolSizeRequest *containerpb.SetNodePoolSizeRequest) error {
_, err := s.scope.ManagedMachinePoolClient().SetNodePoolSize(ctx, setNodePoolSizeRequest)
if err != nil {
return err
}

return nil
}

func (s *Service) updateNodePoolSize(ctx context.Context, setNodePoolSizeRequest *containerpb.SetNodePoolSizeRequest) error {
_, err := s.scope.ManagedMachinePoolClient().SetNodePoolSize(ctx, setNodePoolSizeRequest)
func (s *Service) updateNodePool(ctx context.Context, updateNodePoolRequest *containerpb.UpdateNodePoolRequest) error {
_, err := s.scope.ManagedMachinePoolClient().UpdateNodePool(ctx, updateNodePoolRequest)
if err != nil {
return err
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be good to warp this error to give some extra context.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated updateNodePool caller function. Hope it is fine now.

}
Expand All @@ -329,7 +330,7 @@ func (s *Service) deleteNodePool(ctx context.Context) error {
return nil
}

func (s *Service) checkDiffAndPrepareUpdateVersionOrImage(existingNodePool *containerpb.NodePool) (bool, *containerpb.UpdateNodePoolRequest) {
func (s *Service) checkDiffAndPrepareUpdateNodePool(existingNodePool *containerpb.NodePool) (bool, *containerpb.UpdateNodePoolRequest) {
needUpdate := false
updateNodePoolRequest := containerpb.UpdateNodePoolRequest{
Name: s.scope.NodePoolFullName(),
Expand All @@ -340,20 +341,41 @@ func (s *Service) checkDiffAndPrepareUpdateVersionOrImage(existingNodePool *cont
updateNodePoolRequest.NodeVersion = *s.scope.NodePoolVersion()
}
// Kubernetes labels
if !reflect.DeepEqual(map[string]string(s.scope.GCPManagedMachinePool.Spec.KubernetesLabels), existingNodePool.Config.Labels) {
if !cmp.Equal(map[string]string(s.scope.GCPManagedMachinePool.Spec.KubernetesLabels), existingNodePool.Config.Labels) {
needUpdate = true
updateNodePoolRequest.Labels = &containerpb.NodeLabels{
Labels: s.scope.GCPManagedMachinePool.Spec.KubernetesLabels,
}
}
// Kubernetes taints
desiredKubernetesTaints := infrav1exp.ConvertToSdkTaint(s.scope.GCPManagedMachinePool.Spec.KubernetesTaints)
if !reflect.DeepEqual(desiredKubernetesTaints, existingNodePool.Config.Taints) {
if !cmp.Equal(desiredKubernetesTaints, existingNodePool.Config.Taints) {
needUpdate = true
updateNodePoolRequest.Taints = &containerpb.NodeTaints{
Taints: desiredKubernetesTaints,
}
}
// Locations
desiredLocations := s.scope.GCPManagedMachinePool.Spec.NodeLocations
if !cmp.Equal(desiredLocations, existingNodePool.Locations) {
needUpdate = true
updateNodePoolRequest.Locations = desiredLocations
}
// Image type
desiredImageType := s.scope.GCPManagedMachinePool.Spec.ImageType
if desiredImageType != nil && existingNodePool.Config != nil && *desiredImageType != existingNodePool.Config.ImageType {
needUpdate = true
updateNodePoolRequest.ImageType = *desiredImageType
}
// Network tags
desiredNetworkTags := s.scope.GCPManagedMachinePool.Spec.NodeNetwork.Tags
if existingNodePool.Config != nil && !cmp.Equal(desiredNetworkTags, existingNodePool.Config.Tags) {
needUpdate = true
updateNodePoolRequest.Tags = &containerpb.NetworkTags{
Tags: desiredNetworkTags,
}
}

return needUpdate, &updateNodePoolRequest
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,25 @@ spec:
GCP resources managed by the GCP provider, in addition to the ones
added by default.
type: object
diskSizeGB:
description: DiskSizeGB is size of the disk attached to each node,
specified in GB.
format: int64
minimum: 10
type: integer
diskType:
description: DiskType is type of the disk attached to each node.
enum:
- pd-standard
- pd-ssd
- pd-balanced
type: string
imageType:
description: ImageType is image type to use for this nodepool.
type: string
instanceType:
description: InstanceType is name of Compute Engine machine type.
type: string
kubernetesLabels:
additionalProperties:
type: string
Expand Down Expand Up @@ -82,12 +101,81 @@ spec:
- value
type: object
type: array
maxPodsPerNode:
description: MaxPodsPerNode is constraint enforced on the max num
of pods per node.
format: int64
maximum: 256
minimum: 8
type: integer
nodeLocations:
description: NodeLocations is the list of zones in which the NodePool's
nodes should be located.
items:
type: string
type: array
nodeNetwork:
description: NodeNetwork specifies the node network configuration
options.
properties:
createPodRange:
description: CreatePodRange specifies whether to create a new
range for pod IPs in this node pool.
type: boolean
podRangeCidrBlock:
description: PodRangeCidrBlock is the IP address range for pod
IPs in this node pool.
type: string
podRangeName:
description: PodRangeName is ID of the secondary range for pod
IPs.
type: string
tags:
description: Tags is list of instance tags applied to all nodes.
Tags are used to identify valid sources or targets for network
firewalls.
items:
type: string
type: array
type: object
nodePoolName:
description: NodePoolName specifies the name of the GKE node pool
corresponding to this MachinePool. If you don't specify a name then
a default name will be created based on the namespace and name of
the managed machine pool.
type: string
nodeSecurity:
description: NodeSecurity specifies the node security options.
properties:
enableIntegrityMonitoring:
description: EnableIntegrityMonitoring defines whether the instance
has integrity monitoring enabled.
type: boolean
enableSecureBoot:
description: EnableSecureBoot defines whether the instance has
Secure Boot enabled.
type: boolean
sandboxType:
description: SandboxType is type of the sandbox to use for the
node.
type: string
serviceAccount:
description: ServiceAccount specifies the identity details for
node pool.
properties:
email:
description: Email is the Google Cloud Platform Service Account
to be used by the node VMs.
type: string
scopes:
description: Scopes is a set of Google API scopes to be made
available on all of the node VMs under the "default" service
account.
items:
type: string
type: array
type: object
type: object
providerIDList:
description: ProviderIDList are the provider IDs of instances in the
managed instance group corresponding to the nodegroup represented
Expand Down
Loading
Loading