diff --git a/cloud/services/compute/subnets/reconcile.go b/cloud/services/compute/subnets/reconcile.go index 403c49fb7..99042d542 100644 --- a/cloud/services/compute/subnets/reconcile.go +++ b/cloud/services/compute/subnets/reconcile.go @@ -18,7 +18,6 @@ package subnets import ( "context" - "github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/meta" "google.golang.org/api/compute/v1" "sigs.k8s.io/cluster-api-provider-gcp/cloud/gcperrors" @@ -43,7 +42,7 @@ func (s *Service) Delete(ctx context.Context) error { logger := log.FromContext(ctx) for _, subnetSpec := range s.scope.SubnetSpecs() { logger.V(2).Info("Deleting a subnet", "name", subnetSpec.Name) - subnetKey := meta.RegionalKey(subnetSpec.Name, s.scope.Region()) + subnetKey := meta.RegionalKey(subnetSpec.Name, subnetSpec.Region) err := s.subnets.Delete(ctx, subnetKey) if err != nil && !gcperrors.IsNotFound(err) { logger.Error(err, "Error deleting subnet", "name", subnetSpec.Name) @@ -60,7 +59,7 @@ func (s *Service) createOrGetSubnets(ctx context.Context) ([]*compute.Subnetwork subnets := []*compute.Subnetwork{} for _, subnetSpec := range s.scope.SubnetSpecs() { logger.V(2).Info("Looking for subnet", "name", subnetSpec.Name) - subnetKey := meta.RegionalKey(subnetSpec.Name, s.scope.Region()) + subnetKey := meta.RegionalKey(subnetSpec.Name, subnetSpec.Region) subnet, err := s.subnets.Get(ctx, subnetKey) if err != nil { if !gcperrors.IsNotFound(err) { diff --git a/cloud/services/container/clusters/reconcile.go b/cloud/services/container/clusters/reconcile.go index 4317e058b..dab921e62 100644 --- a/cloud/services/container/clusters/reconcile.go +++ b/cloud/services/container/clusters/reconcile.go @@ -248,10 +248,10 @@ func (s *Service) createCluster(ctx context.Context, log *logr.Logger) error { } isRegional := shared.IsRegional(s.scope.Region()) - cluster := &containerpb.Cluster{ - Name: s.scope.ClusterName(), - Network: *s.scope.GCPManagedCluster.Spec.Network.Name, + Name: s.scope.ClusterName(), + Network: *s.scope.GCPManagedCluster.Spec.Network.Name, + Subnetwork: s.getSubnetName(), Autopilot: &containerpb.Autopilot{ Enabled: s.scope.GCPManagedControlPlane.Spec.EnableAutopilot, }, @@ -281,6 +281,15 @@ func (s *Service) createCluster(ctx context.Context, log *logr.Logger) error { return nil } +func (s *Service) getSubnetName() string { + for _, subnet := range s.scope.GCPManagedCluster.Spec.Network.Subnets { + if subnet.Region == s.scope.Region() { + return subnet.Name + } + } + return "" +} + func (s *Service) updateCluster(ctx context.Context, updateClusterRequest *containerpb.UpdateClusterRequest, log *logr.Logger) error { _, err := s.scope.ManagedControlPlaneClient().UpdateCluster(ctx, updateClusterRequest) if err != nil { diff --git a/exp/api/v1beta1/gcpmanagedcluster_webhook.go b/exp/api/v1beta1/gcpmanagedcluster_webhook.go index 4b2c33844..09191bd69 100644 --- a/exp/api/v1beta1/gcpmanagedcluster_webhook.go +++ b/exp/api/v1beta1/gcpmanagedcluster_webhook.go @@ -20,6 +20,7 @@ import ( "github.com/google/go-cmp/cmp" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime" + kerrors "k8s.io/apimachinery/pkg/util/errors" "k8s.io/apimachinery/pkg/util/validation/field" ctrl "sigs.k8s.io/controller-runtime" logf "sigs.k8s.io/controller-runtime/pkg/log" @@ -52,7 +53,7 @@ var _ webhook.Validator = &GCPManagedCluster{} func (r *GCPManagedCluster) ValidateCreate() error { gcpmanagedclusterlog.Info("validate create", "name", r.Name) - return nil + return r.validate() } // ValidateUpdate implements webhook.Validator so a webhook will be registered for the type. @@ -95,3 +96,36 @@ func (r *GCPManagedCluster) ValidateDelete() error { return nil } + +func (r *GCPManagedCluster) validate() error { + validators := []func() error{ + r.validateCustomSubnet, + } + + var errs []error + for _, validator := range validators { + if err := validator(); err != nil { + errs = append(errs, err) + } + } + + return kerrors.NewAggregate(errs) +} + +func (r *GCPManagedCluster) validateCustomSubnet() error { + gcpmanagedclusterlog.Info("validate custom subnet", "name", r.Name) + if r.Spec.Network.AutoCreateSubnetworks == nil || *r.Spec.Network.AutoCreateSubnetworks { + return nil + } + var isSubnetExistInClusterRegion = false + for _, subnet := range r.Spec.Network.Subnets { + if subnet.Region == r.Spec.Region { + isSubnetExistInClusterRegion = true + } + } + + if !isSubnetExistInClusterRegion { + return field.Required(field.NewPath("spec", "network", "subnet"), "at least one given subnets region should be same as spec.network.region when spec.network.autoCreateSubnetworks is false") + } + return nil +}