Skip to content

Commit

Permalink
Merge pull request #944 from akshay196-rafay/gcpmanagedmachinepool-ad…
Browse files Browse the repository at this point in the history
…ditional-fields

Add additional fields to GCPManagedMachinePool
  • Loading branch information
k8s-ci-robot authored Nov 5, 2023
2 parents 173d8a2 + a3bbeb3 commit d4689a3
Show file tree
Hide file tree
Showing 6 changed files with 474 additions and 15 deletions.
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
}
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

0 comments on commit d4689a3

Please sign in to comment.