diff --git a/api/v1alpha3/zz_generated.deepcopy.go b/api/v1alpha3/zz_generated.deepcopy.go index 4741b94625..299ea37129 100644 --- a/api/v1alpha3/zz_generated.deepcopy.go +++ b/api/v1alpha3/zz_generated.deepcopy.go @@ -22,7 +22,7 @@ limitations under the License. package v1alpha3 import ( - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime" apiv1alpha3 "sigs.k8s.io/cluster-api/api/v1alpha3" "sigs.k8s.io/cluster-api/errors" diff --git a/api/v1alpha4/zz_generated.deepcopy.go b/api/v1alpha4/zz_generated.deepcopy.go index 34de4c2180..97ae2b10b3 100644 --- a/api/v1alpha4/zz_generated.deepcopy.go +++ b/api/v1alpha4/zz_generated.deepcopy.go @@ -22,7 +22,7 @@ limitations under the License. package v1alpha4 import ( - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime" apiv1alpha4 "sigs.k8s.io/cluster-api/api/v1alpha4" "sigs.k8s.io/cluster-api/errors" diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go index 97c66e8590..31b3f42d8b 100644 --- a/api/v1beta1/zz_generated.deepcopy.go +++ b/api/v1beta1/zz_generated.deepcopy.go @@ -22,7 +22,7 @@ limitations under the License. package v1beta1 import ( - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime" apiv1beta1 "sigs.k8s.io/cluster-api/api/v1beta1" "sigs.k8s.io/cluster-api/errors" diff --git a/cloud/scope/managedcontrolplane.go b/cloud/scope/managedcontrolplane.go index 0073d3382f..0f6ba7d769 100644 --- a/cloud/scope/managedcontrolplane.go +++ b/cloud/scope/managedcontrolplane.go @@ -173,6 +173,7 @@ func (s *ManagedControlPlaneScope) GetCredential() *Credential { return s.credential } +// GetAllNodePools gets all node pools for the control plane. func (s *ManagedControlPlaneScope) GetAllNodePools(ctx context.Context) ([]infrav1exp.GCPManagedMachinePool, error) { if s.AllNodePools == nil { opt1 := client.InNamespace(s.GCPManagedControlPlane.Namespace) @@ -190,18 +191,15 @@ func (s *ManagedControlPlaneScope) GetAllNodePools(ctx context.Context) ([]infra return s.AllNodePools, nil } -func parseLocation(location string) (region string, zone *string) { +func parseLocation(location string) string { parts := strings.Split(location, "-") - region = strings.Join(parts[:2], "-") - if len(parts) == 3 { - return region, &parts[2] - } - return region, nil + region := strings.Join(parts[:2], "-") + return region } // Region returns the region of the GKE cluster. func (s *ManagedControlPlaneScope) Region() string { - region, _ := parseLocation(s.GCPManagedControlPlane.Spec.Location) + region := parseLocation(s.GCPManagedControlPlane.Spec.Location) return region } diff --git a/cloud/scope/managedmachinepool.go b/cloud/scope/managedmachinepool.go index aec1722763..e4221c29dd 100644 --- a/cloud/scope/managedmachinepool.go +++ b/cloud/scope/managedmachinepool.go @@ -19,12 +19,13 @@ package scope import ( "context" "fmt" + "strings" + "google.golang.org/api/option" "sigs.k8s.io/cluster-api/util/conditions" - "strings" - "cloud.google.com/go/compute/apiv1" - "cloud.google.com/go/container/apiv1" + compute "cloud.google.com/go/compute/apiv1" + container "cloud.google.com/go/container/apiv1" "cloud.google.com/go/container/apiv1/containerpb" "github.com/pkg/errors" infrav1exp "sigs.k8s.io/cluster-api-provider-gcp/exp/api/v1beta1" @@ -35,13 +36,13 @@ import ( // ManagedMachinePoolScopeParams defines the input parameters used to create a new Scope. type ManagedMachinePoolScopeParams struct { - ManagedClusterClient *container.ClusterManagerClient + ManagedClusterClient *container.ClusterManagerClient InstanceGroupManagersClient *compute.InstanceGroupManagersClient - Client client.Client - Cluster *clusterv1.Cluster - GCPManagedCluster *infrav1exp.GCPManagedCluster - GCPManagedControlPlane *infrav1exp.GCPManagedControlPlane - GCPManagedMachinePool *infrav1exp.GCPManagedMachinePool + Client client.Client + Cluster *clusterv1.Cluster + GCPManagedCluster *infrav1exp.GCPManagedCluster + GCPManagedControlPlane *infrav1exp.GCPManagedControlPlane + GCPManagedMachinePool *infrav1exp.GCPManagedMachinePool } // NewManagedMachinePoolScope creates a new Scope from the supplied parameters. @@ -94,13 +95,13 @@ func NewManagedMachinePoolScope(ctx context.Context, params ManagedMachinePoolSc } return &ManagedMachinePoolScope{ - client: params.Client, - Cluster: params.Cluster, + client: params.Client, + Cluster: params.Cluster, GCPManagedControlPlane: params.GCPManagedControlPlane, GCPManagedMachinePool: params.GCPManagedMachinePool, - mcClient: params.ManagedClusterClient, - migClient: params.InstanceGroupManagersClient, - patchHelper: helper, + mcClient: params.ManagedClusterClient, + migClient: params.InstanceGroupManagersClient, + patchHelper: helper, }, nil } @@ -109,12 +110,12 @@ type ManagedMachinePoolScope struct { client client.Client patchHelper *patch.Helper - Cluster *clusterv1.Cluster + Cluster *clusterv1.Cluster GCPManagedCluster *infrav1exp.GCPManagedCluster GCPManagedControlPlane *infrav1exp.GCPManagedControlPlane - GCPManagedMachinePool *infrav1exp.GCPManagedMachinePool - mcClient *container.ClusterManagerClient - migClient *compute.InstanceGroupManagersClient + GCPManagedMachinePool *infrav1exp.GCPManagedMachinePool + mcClient *container.ClusterManagerClient + migClient *compute.InstanceGroupManagersClient } // PatchObject persists the managed control plane configuration and status. @@ -137,19 +138,23 @@ func (s *ManagedMachinePoolScope) Close() error { return s.PatchObject() } +// ConditionSetter return a condition setter (which is GCPManagedMachinePool itself). func (s *ManagedMachinePoolScope) ConditionSetter() conditions.Setter { return s.GCPManagedMachinePool } +// ManagedMachinePoolClient returns a client used to interact with GKE. func (s *ManagedMachinePoolScope) ManagedMachinePoolClient() *container.ClusterManagerClient { return s.mcClient } +// InstanceGroupManagersClient returns a client used to interact with GCP MIG. func (s *ManagedMachinePoolScope) InstanceGroupManagersClient() *compute.InstanceGroupManagersClient { return s.migClient } -func ParseInstanceGroupUrl(url string) (project string, zone string, mig string) { +// ParseInstanceGroupURL parses an instance group URL. +func ParseInstanceGroupURL(url string) (project string, zone string, mig string) { parts := strings.Split(url, "/") if len(parts) < 11 { return "", "", "" @@ -157,17 +162,18 @@ func ParseInstanceGroupUrl(url string) (project string, zone string, mig string) return parts[6], parts[8], parts[10] } +// ConvertToSdkNodePool convertsSetReplicas a node pool to format that is used by GCP SDK. func ConvertToSdkNodePool(nodePool infrav1exp.GCPManagedMachinePool) *containerpb.NodePool { nodePoolName := nodePool.Spec.NodePoolName if len(nodePoolName) == 0 { nodePoolName = nodePool.Name } sdkNodePool := containerpb.NodePool{ - Name: nodePoolName, + Name: nodePoolName, InitialNodeCount: nodePool.Spec.NodeCount, Config: &containerpb.NodeConfig{ - Labels: nodePool.Spec.KubernetesLabels, - Taints: infrav1exp.ConvertToSdkTaint(nodePool.Spec.KubernetesTaints), + Labels: nodePool.Spec.KubernetesLabels, + Taints: infrav1exp.ConvertToSdkTaint(nodePool.Spec.KubernetesTaints), Metadata: nodePool.Spec.AdditionalLabels, }, } @@ -177,6 +183,7 @@ func ConvertToSdkNodePool(nodePool infrav1exp.GCPManagedMachinePool) *containerp return &sdkNodePool } +// ConvertToSdkNodePools converts node pools to format that is used by GCP SDK. func ConvertToSdkNodePools(nodePools []infrav1exp.GCPManagedMachinePool) []*containerpb.NodePool { res := []*containerpb.NodePool{} for _, nodePool := range nodePools { @@ -185,27 +192,31 @@ func ConvertToSdkNodePools(nodePools []infrav1exp.GCPManagedMachinePool) []*cont return res } +// SetReplicas sets the replicas count in status. func (s *ManagedMachinePoolScope) SetReplicas(replicas int32) { s.GCPManagedMachinePool.Status.Replicas = replicas } +// NodePoolName returns the node pool name. func (s *ManagedMachinePoolScope) NodePoolName() string { if len(s.GCPManagedMachinePool.Spec.NodePoolName) > 0 { return s.GCPManagedMachinePool.Spec.NodePoolName - } else { - return s.GCPManagedMachinePool.Name } + return s.GCPManagedMachinePool.Name } +// Region returns the region of the GKE node pool. func (s *ManagedMachinePoolScope) Region() string { - region, _ := parseLocation(s.GCPManagedControlPlane.Spec.Location) + region := parseLocation(s.GCPManagedControlPlane.Spec.Location) return region } +// NodePoolLocation returns the location of the node pool. func (s *ManagedMachinePoolScope) NodePoolLocation() string { return fmt.Sprintf("projects/%s/locations/%s/clusters/%s", s.GCPManagedControlPlane.Spec.Project, s.Region(), s.GCPManagedControlPlane.Spec.ClusterName) } +// NodePoolFullName returns the full name of the node pool. func (s *ManagedMachinePoolScope) NodePoolFullName() string { return fmt.Sprintf("%s/nodePools/%s", s.NodePoolLocation(), s.NodePoolName()) } diff --git a/cloud/services/container/clusters/reconcile.go b/cloud/services/container/clusters/reconcile.go index 2d6533608f..aaa42bc623 100644 --- a/cloud/services/container/clusters/reconcile.go +++ b/cloud/services/container/clusters/reconcile.go @@ -19,6 +19,7 @@ package clusters import ( "context" "fmt" + "sigs.k8s.io/cluster-api-provider-gcp/cloud/scope" "cloud.google.com/go/container/apiv1/containerpb" @@ -216,7 +217,7 @@ func (s *Service) createCluster(ctx context.Context) error { nodePools, _ := s.scope.GetAllNodePools(ctx) cluster := &containerpb.Cluster{ - Name: s.scope.GCPManagedControlPlane.Spec.ClusterName, + Name: s.scope.GCPManagedControlPlane.Spec.ClusterName, Network: *s.scope.GCPManagedCluster.Spec.Network.Name, Autopilot: &containerpb.Autopilot{ Enabled: false, @@ -231,7 +232,7 @@ func (s *Service) createCluster(ctx context.Context) error { } createClusterRequest := &containerpb.CreateClusterRequest{ Cluster: cluster, - Parent: s.scope.ClusterLocation(), + Parent: s.scope.ClusterLocation(), } _, err := s.scope.ManagedControlPlaneClient().CreateCluster(ctx, createClusterRequest) if err != nil { diff --git a/cloud/services/container/nodepools/doc.go b/cloud/services/container/nodepools/doc.go index 743df9e2af..aa21dbe422 100644 --- a/cloud/services/container/nodepools/doc.go +++ b/cloud/services/container/nodepools/doc.go @@ -14,5 +14,5 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Package instances implements reconciler for GKE node pool components. +// Package nodepools implements reconciler for GKE node pool components. package nodepools diff --git a/cloud/services/container/nodepools/reconcile.go b/cloud/services/container/nodepools/reconcile.go index a2e7ef49e2..a22fe3a206 100644 --- a/cloud/services/container/nodepools/reconcile.go +++ b/cloud/services/container/nodepools/reconcile.go @@ -17,15 +17,17 @@ limitations under the License. package nodepools import ( - "cloud.google.com/go/container/apiv1/containerpb" "context" "fmt" - "github.com/googleapis/gax-go/v2/apierror" - "github.com/pkg/errors" + "reflect" + "google.golang.org/api/iterator" - computepb "google.golang.org/genproto/googleapis/cloud/compute/v1" "google.golang.org/grpc/codes" - "reflect" + + "cloud.google.com/go/compute/apiv1/computepb" + "cloud.google.com/go/container/apiv1/containerpb" + "github.com/googleapis/gax-go/v2/apierror" + "github.com/pkg/errors" "sigs.k8s.io/cluster-api-provider-gcp/cloud/scope" infrav1exp "sigs.k8s.io/cluster-api-provider-gcp/exp/api/v1beta1" "sigs.k8s.io/cluster-api-provider-gcp/util/reconciler" @@ -110,7 +112,7 @@ func (s *Service) Reconcile(ctx context.Context) (ctrl.Result, error) { return ctrl.Result{}, nil } - needUpdateVersionOrImage, nodePoolUpdateVersionOrImage := s.checkDiffAndPrepareUpdateVersionOrImage(*nodePool) + needUpdateVersionOrImage, nodePoolUpdateVersionOrImage := s.checkDiffAndPrepareUpdateVersionOrImage(nodePool) if needUpdateVersionOrImage { log.Info("Version/image update required") err = s.updateNodePoolVersionOrImage(ctx, nodePoolUpdateVersionOrImage) @@ -123,7 +125,7 @@ func (s *Service) Reconcile(ctx context.Context) (ctrl.Result, error) { return ctrl.Result{}, nil } - needUpdateSize, setNodePoolSizeRequest := s.checkDiffAndPrepareUpdateSize(*nodePool) + needUpdateSize, setNodePoolSizeRequest := s.checkDiffAndPrepareUpdateSize(nodePool) if needUpdateSize { log.Info("Size update required") err = s.updateNodePoolSize(ctx, setNodePoolSizeRequest) @@ -217,14 +219,14 @@ func (s *Service) getInstances(ctx context.Context, nodePool *containerpb.NodePo instances := []*computepb.ManagedInstance{} for _, url := range nodePool.InstanceGroupUrls { - project, zone, mig := scope.ParseInstanceGroupUrl(url) + project, zone, mig := scope.ParseInstanceGroupURL(url) if mig == "" { - return nil, errors.New(fmt.Sprintf("fail to parse instance group url %s", url)) + return nil, fmt.Errorf("fail to parse instance group url %s", url) } listManagedInstancesRequest := &computepb.ListManagedInstancesInstanceGroupManagersRequest{ InstanceGroupManager: mig, - Project: project, - Zone: zone, + Project: project, + Zone: zone, } iter := s.scope.InstanceGroupManagersClient().ListManagedInstances(ctx, listManagedInstancesRequest) for { @@ -245,7 +247,7 @@ func (s *Service) getInstances(ctx context.Context, nodePool *containerpb.NodePo func (s *Service) createNodePool(ctx context.Context) error { createNodePoolRequest := &containerpb.CreateNodePoolRequest{ NodePool: scope.ConvertToSdkNodePool(*s.scope.GCPManagedMachinePool), - Parent: s.scope.NodePoolLocation(), + Parent: s.scope.NodePoolLocation(), } _, err := s.scope.ManagedMachinePoolClient().CreateNodePool(ctx, createNodePoolRequest) if err != nil { @@ -285,7 +287,7 @@ func (s *Service) deleteNodePool(ctx context.Context) error { return nil } -func (s *Service) checkDiffAndPrepareUpdateVersionOrImage(existingNodePool containerpb.NodePool) (bool, *containerpb.UpdateNodePoolRequest) { +func (s *Service) checkDiffAndPrepareUpdateVersionOrImage(existingNodePool *containerpb.NodePool) (bool, *containerpb.UpdateNodePoolRequest) { needUpdate := false updateNodePoolRequest := containerpb.UpdateNodePoolRequest{ Name: s.scope.NodePoolFullName(), @@ -313,7 +315,7 @@ func (s *Service) checkDiffAndPrepareUpdateVersionOrImage(existingNodePool conta return needUpdate, &updateNodePoolRequest } -func (s *Service) checkDiffAndPrepareUpdateSize(existingNodePool containerpb.NodePool) (bool, *containerpb.SetNodePoolSizeRequest) { +func (s *Service) checkDiffAndPrepareUpdateSize(existingNodePool *containerpb.NodePool) (bool, *containerpb.SetNodePoolSizeRequest) { needUpdate := false setNodePoolSizeRequest := containerpb.SetNodePoolSizeRequest{ Name: s.scope.NodePoolFullName(), diff --git a/exp/api/v1beta1/types.go b/exp/api/v1beta1/types.go index 6b60c619cf..f4c87bb300 100644 --- a/exp/api/v1beta1/types.go +++ b/exp/api/v1beta1/types.go @@ -35,16 +35,6 @@ type Taint struct { // Taints is an array of Taints. type Taints []Taint -// MachinePoolMode represents the mode of operation for the machine pool. -type MachinePoolMode string - -const ( - // MachinePoolModeSystem represents a system machine pool. - MachinePoolModeSystem MachinePoolMode = "system" - // MachinePoolModeUser represenyts a user machine pool. - MachinePoolModeUser MachinePoolMode = "user" -) - func convertToSdkTaintEffect(effect TaintEffect) containerpb.NodeTaint_Effect { switch effect { case "NoSchedule": @@ -58,6 +48,7 @@ func convertToSdkTaintEffect(effect TaintEffect) containerpb.NodeTaint_Effect { } } +// ConvertToSdkTaint converts taints to format that is used by GCP SDK. func ConvertToSdkTaint(taints Taints) []*containerpb.NodeTaint { if taints == nil { return nil @@ -65,8 +56,8 @@ func ConvertToSdkTaint(taints Taints) []*containerpb.NodeTaint { res := []*containerpb.NodeTaint{} for _, taint := range taints { res = append(res, &containerpb.NodeTaint{ - Key: taint.Key, - Value: taint.Value, + Key: taint.Key, + Value: taint.Value, Effect: convertToSdkTaintEffect(taint.Effect), }) } diff --git a/exp/controllers/gcpmanagedmachinepool_controller.go b/exp/controllers/gcpmanagedmachinepool_controller.go index a4d740db8f..704fc0383e 100644 --- a/exp/controllers/gcpmanagedmachinepool_controller.go +++ b/exp/controllers/gcpmanagedmachinepool_controller.go @@ -19,6 +19,8 @@ package controllers import ( "context" "fmt" + "time" + "github.com/go-logr/logr" "github.com/googleapis/gax-go/v2/apierror" "github.com/pkg/errors" @@ -35,7 +37,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client/apiutil" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "sigs.k8s.io/controller-runtime/pkg/reconcile" - "time" "sigs.k8s.io/cluster-api-provider-gcp/cloud/scope" infrav1exp "sigs.k8s.io/cluster-api-provider-gcp/exp/api/v1beta1" @@ -57,7 +58,7 @@ import ( type GCPManagedMachinePoolReconciler struct { client.Client ReconcileTimeout time.Duration - Scheme *runtime.Scheme + Scheme *runtime.Scheme WatchFilterValue string } @@ -286,11 +287,11 @@ func (r *GCPManagedMachinePoolReconciler) Reconcile(ctx context.Context, req ctr } managedMachinePoolScope, err := scope.NewManagedMachinePoolScope(ctx, scope.ManagedMachinePoolScopeParams{ - Client: r.Client, - Cluster: cluster, - GCPManagedCluster: gcpManagedCluster, + Client: r.Client, + Cluster: cluster, + GCPManagedCluster: gcpManagedCluster, GCPManagedControlPlane: gcpManagedControlPlane, - GCPManagedMachinePool: gcpManagedMachinePool, + GCPManagedMachinePool: gcpManagedMachinePool, }) if err != nil { return ctrl.Result{}, errors.Errorf("failed to create scope: %+v", err) diff --git a/go.mod b/go.mod index b27ea5a546..8d16d7bea3 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,6 @@ require ( golang.org/x/mod v0.7.0 golang.org/x/net v0.5.0 google.golang.org/api v0.108.0 - google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef google.golang.org/grpc v1.51.0 k8s.io/api v0.25.5 k8s.io/apimachinery v0.25.5 @@ -123,6 +122,7 @@ require ( golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 // indirect gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef // indirect google.golang.org/protobuf v1.28.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect