Skip to content

Commit

Permalink
Add suport for GKE Autopilot
Browse files Browse the repository at this point in the history
(cherry picked from commit c0e21ad)
  • Loading branch information
mjura committed Dec 18, 2023
1 parent eadc0f4 commit a3e3dce
Show file tree
Hide file tree
Showing 7 changed files with 141 additions and 22 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ MOCKGEN_BIN := mockgen
MOCKGEN := $(BIN_DIR)/$(MOCKGEN_BIN)-$(MOCKGEN_VER)
MOCKGEN_PKG := github.com/golang/mock/mockgen

GINKGO_VER := v2.12.0
GINKGO_VER := v2.13.2
GINKGO_BIN := ginkgo
GINKGO := $(BIN_DIR)/$(GINKGO_BIN)-$(GINKGO_VER)

Expand Down
6 changes: 6 additions & 0 deletions charts/gke-operator-crd/templates/crds.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ spec:
properties:
spec:
properties:
autopilotConfig:
nullable: true
properties:
enabled:
type: boolean
type: object
clusterAddons:
nullable: true
properties:
Expand Down
8 changes: 7 additions & 1 deletion controller/gke-cluster-config-handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ func (h *Handler) updateUpstreamClusterState(config *gkev1.GKEClusterConfig, ups
return h.enqueueUpdate(config)
}

if config.Spec.NodePools != nil {
if config.Spec.NodePools != nil && (config.Spec.AutopilotConfig == nil || !config.Spec.AutopilotConfig.Enabled) {
downstreamNodePools, err := buildNodePoolMap(config.Spec.NodePools, config.Name)
if err != nil {
return config, err
Expand Down Expand Up @@ -636,6 +636,12 @@ func BuildUpstreamClusterState(cluster *gkeapi.Cluster) (*gkev1.GKEClusterConfig
newSpec.MaintenanceWindow = &cluster.MaintenancePolicy.Window.DailyMaintenanceWindow.StartTime
}

if cluster.Autopilot != nil && cluster.Autopilot.Enabled {
newSpec.AutopilotConfig = &gkev1.GKEAutopilotConfig{
Enabled: cluster.Autopilot.Enabled,
}
}

// build node groups
newSpec.NodePools = make([]gkev1.GKENodePoolConfig, 0, len(cluster.NodePools))

Expand Down
9 changes: 9 additions & 0 deletions pkg/apis/gke.cattle.io/v1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@ type GKEClusterConfigSpec struct {
// MaintenanceWindow is the maintenance window configuration.
// +optional
MaintenanceWindow *string `json:"maintenanceWindow,omitempty" norman:"pointer"`

// GKE Autopilot is a mode of operation in GKE in which Google manages your cluster configuration,
// including your nodes, scaling, security, and other preconfigured settings.
// +optional
AutopilotConfig *GKEAutopilotConfig `json:"autopilotConfig,omitempty"`
}

type GKEIPAllocationPolicy struct {
Expand Down Expand Up @@ -350,3 +355,7 @@ type GKENodePoolManagement struct {
// +kubebuilder:default=false
AutoUpgrade bool `json:"autoUpgrade,omitempty"`
}

type GKEAutopilotConfig struct {
Enabled bool `json:"enabled,omitempty"`
}
21 changes: 21 additions & 0 deletions pkg/apis/gke.cattle.io/v1/zz_generated_deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

50 changes: 30 additions & 20 deletions pkg/gke/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,29 +98,35 @@ func newClusterCreateRequest(config *gkev1.GKEClusterConfig) *gkeapi.CreateClust
}
}

addons := config.Spec.ClusterAddons
request.Cluster.AddonsConfig.HttpLoadBalancing = &gkeapi.HttpLoadBalancing{Disabled: !addons.HTTPLoadBalancing}
request.Cluster.AddonsConfig.HorizontalPodAutoscaling = &gkeapi.HorizontalPodAutoscaling{Disabled: !addons.HorizontalPodAutoscaling}
request.Cluster.AddonsConfig.NetworkPolicyConfig = &gkeapi.NetworkPolicyConfig{Disabled: !addons.NetworkPolicyConfig}
if config.Spec.AutopilotConfig != nil && config.Spec.AutopilotConfig.Enabled {
request.Cluster.Autopilot = &gkeapi.Autopilot{
Enabled: config.Spec.AutopilotConfig.Enabled,
}
} else {
addons := config.Spec.ClusterAddons
request.Cluster.AddonsConfig.HttpLoadBalancing = &gkeapi.HttpLoadBalancing{Disabled: !addons.HTTPLoadBalancing}
request.Cluster.AddonsConfig.HorizontalPodAutoscaling = &gkeapi.HorizontalPodAutoscaling{Disabled: !addons.HorizontalPodAutoscaling}
request.Cluster.AddonsConfig.NetworkPolicyConfig = &gkeapi.NetworkPolicyConfig{Disabled: !addons.NetworkPolicyConfig}

request.Cluster.NodePools = make([]*gkeapi.NodePool, 0, len(config.Spec.NodePools))
request.Cluster.NodePools = make([]*gkeapi.NodePool, 0, len(config.Spec.NodePools))

for np := range config.Spec.NodePools {
nodePool := newGKENodePoolFromConfig(&config.Spec.NodePools[np], config)
request.Cluster.NodePools = append(request.Cluster.NodePools, nodePool)
}

if config.Spec.MasterAuthorizedNetworksConfig != nil {
blocks := make([]*gkeapi.CidrBlock, len(config.Spec.MasterAuthorizedNetworksConfig.CidrBlocks))
for _, b := range config.Spec.MasterAuthorizedNetworksConfig.CidrBlocks {
blocks = append(blocks, &gkeapi.CidrBlock{
CidrBlock: b.CidrBlock,
DisplayName: b.DisplayName,
})
for np := range config.Spec.NodePools {
nodePool := newGKENodePoolFromConfig(&config.Spec.NodePools[np], config)
request.Cluster.NodePools = append(request.Cluster.NodePools, nodePool)
}
request.Cluster.MasterAuthorizedNetworksConfig = &gkeapi.MasterAuthorizedNetworksConfig{
Enabled: config.Spec.MasterAuthorizedNetworksConfig.Enabled,
CidrBlocks: blocks,

if config.Spec.MasterAuthorizedNetworksConfig != nil {
blocks := make([]*gkeapi.CidrBlock, len(config.Spec.MasterAuthorizedNetworksConfig.CidrBlocks))
for _, b := range config.Spec.MasterAuthorizedNetworksConfig.CidrBlocks {
blocks = append(blocks, &gkeapi.CidrBlock{
CidrBlock: b.CidrBlock,
DisplayName: b.DisplayName,
})
}
request.Cluster.MasterAuthorizedNetworksConfig = &gkeapi.MasterAuthorizedNetworksConfig{
Enabled: config.Spec.MasterAuthorizedNetworksConfig.Enabled,
CidrBlocks: blocks,
}
}
}

Expand Down Expand Up @@ -163,6 +169,10 @@ func validateCreateRequest(ctx context.Context, gkeClient services.GKEClusterSer
return fmt.Errorf("cluster name is required")
}

if len(config.Spec.NodePools) != 0 && config.Spec.AutopilotConfig != nil && config.Spec.AutopilotConfig.Enabled {
return fmt.Errorf("cannot create node pools for autopilot clusters")
}

nodeP := map[string]bool{}
for _, np := range config.Spec.NodePools {
if np.Name == nil {
Expand Down
67 changes: 67 additions & 0 deletions pkg/gke/create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,73 @@ var _ = Describe("CreateCluster", func() {
Expect(err).To(HaveOccurred())
})

It("should successfully create autopilot cluster", func() {
config.Spec.ClusterName = "test-autopilot-cluster"
config.Spec.AutopilotConfig = &gkev1.GKEAutopilotConfig{
Enabled: true,
}

createClusterRequest := newClusterCreateRequest(config)
clusterServiceMock.EXPECT().
ClusterCreate(
ctx,
LocationRRN(config.Spec.ProjectID, Location(config.Spec.Region, config.Spec.Zone)),
createClusterRequest).
Return(&gkeapi.Operation{}, nil)

clusterServiceMock.EXPECT().
ClusterList(
ctx,
LocationRRN(config.Spec.ProjectID, Location(config.Spec.Region, config.Spec.Zone))).
Return(&gkeapi.ListClustersResponse{}, nil)

err := Create(ctx, clusterServiceMock, config)
Expect(err).ToNot(HaveOccurred())

clusterServiceMock.EXPECT().
ClusterGet(
ctx,
ClusterRRN(config.Spec.ProjectID, Location(config.Spec.Region, config.Spec.Zone),
config.Spec.ClusterName)).
Return(
&gkeapi.Cluster{
Name: "test-autopilot-cluster",
}, nil)

managedCluster, err := GetCluster(ctx, clusterServiceMock, &config.Spec)
Expect(err).ToNot(HaveOccurred())
Expect(managedCluster.Name).To(Equal(config.Spec.ClusterName))
})

It("should fail to create autopilot cluster with nodepools", func() {
config.Spec.ClusterName = "test-autopilot-cluster"
config.Spec.AutopilotConfig = &gkev1.GKEAutopilotConfig{
Enabled: true,
}

config.Spec.NodePools = []gkev1.GKENodePoolConfig{
{
Name: &nodePoolName,
InitialNodeCount: &initialNodeCount,
Version: &k8sVersion,
MaxPodsConstraint: &maxPodsConstraint,
Config: &gkev1.GKENodeConfig{},
Autoscaling: &gkev1.GKENodePoolAutoscaling{
Enabled: true,
MinNodeCount: 3,
MaxNodeCount: 5,
},
Management: &gkev1.GKENodePoolManagement{
AutoRepair: true,
AutoUpgrade: true,
},
},
}

err := Create(ctx, clusterServiceMock, config)
Expect(err).To(HaveOccurred())
})

It("should fail to create cluster with duplicated nodepool names", func() {
config.Spec.NodePools = []gkev1.GKENodePoolConfig{
{
Expand Down

0 comments on commit a3e3dce

Please sign in to comment.