Skip to content

Commit 7f21902

Browse files
committed
CORS-3213: GCP Cluster API Cluster Manifest Creation
* Added the cluster manifest for GCP. The manifest is not generated by default yet (until the manifests target includes capi manifests).
1 parent c2420d8 commit 7f21902

File tree

2 files changed

+178
-0
lines changed

2 files changed

+178
-0
lines changed

pkg/asset/manifests/clusterapi/cluster.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,13 @@ import (
1919
"github.com/openshift/installer/pkg/asset/manifests/aws"
2020
"github.com/openshift/installer/pkg/asset/manifests/azure"
2121
"github.com/openshift/installer/pkg/asset/manifests/capiutils"
22+
"github.com/openshift/installer/pkg/asset/manifests/gcp"
2223
"github.com/openshift/installer/pkg/asset/openshiftinstall"
2324
"github.com/openshift/installer/pkg/asset/rhcos"
2425
"github.com/openshift/installer/pkg/clusterapi"
2526
awstypes "github.com/openshift/installer/pkg/types/aws"
2627
azuretypes "github.com/openshift/installer/pkg/types/azure"
28+
gcptypes "github.com/openshift/installer/pkg/types/gcp"
2729
)
2830

2931
var _ asset.WritableRuntimeAsset = (*Cluster)(nil)
@@ -105,6 +107,12 @@ func (c *Cluster) Generate(dependencies asset.Parents) error {
105107
if err != nil {
106108
return errors.Wrap(err, "failed to generate Azure manifests")
107109
}
110+
case gcptypes.Name:
111+
var err error
112+
out, err = gcp.GenerateClusterAssets(installConfig, clusterID)
113+
if err != nil {
114+
return fmt.Errorf("failed to generate GCP manifests: %w", err)
115+
}
108116
default:
109117
return fmt.Errorf("unsupported platform %q", platform)
110118
}

pkg/asset/manifests/gcp/cluster.go

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
package gcp
2+
3+
import (
4+
"fmt"
5+
"net"
6+
7+
"github.com/apparentlymart/go-cidr/cidr"
8+
corev1 "k8s.io/api/core/v1"
9+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
10+
"k8s.io/apimachinery/pkg/util/sets"
11+
"k8s.io/utils/ptr"
12+
capg "sigs.k8s.io/cluster-api-provider-gcp/api/v1beta1"
13+
14+
"github.com/openshift/installer/pkg/asset"
15+
"github.com/openshift/installer/pkg/asset/installconfig"
16+
"github.com/openshift/installer/pkg/asset/manifests/capiutils"
17+
"github.com/openshift/installer/pkg/types/gcp"
18+
)
19+
20+
// GenerateClusterAssets generates the manifests for the cluster-api.
21+
func GenerateClusterAssets(installConfig *installconfig.InstallConfig, clusterID *installconfig.ClusterID) (*capiutils.GenerateClusterAssetsOutput, error) {
22+
manifests := []*asset.RuntimeFile{}
23+
24+
const (
25+
description = "Created By OpenShift Installer"
26+
)
27+
28+
networkName := fmt.Sprintf("%s-network", clusterID.InfraID)
29+
if installConfig.Config.GCP.Network != "" {
30+
networkName = installConfig.Config.GCP.Network
31+
}
32+
33+
masterSubnet := gcp.DefaultSubnetName(clusterID.InfraID, "master")
34+
if installConfig.Config.GCP.ControlPlaneSubnet != "" {
35+
masterSubnet = installConfig.Config.GCP.ControlPlaneSubnet
36+
}
37+
38+
master := capg.SubnetSpec{
39+
Name: masterSubnet,
40+
CidrBlock: "",
41+
Description: ptr.To(description),
42+
Region: installConfig.Config.GCP.Region,
43+
}
44+
45+
workerSubnet := gcp.DefaultSubnetName(clusterID.InfraID, "worker")
46+
if installConfig.Config.GCP.ComputeSubnet != "" {
47+
workerSubnet = installConfig.Config.GCP.ComputeSubnet
48+
}
49+
50+
worker := capg.SubnetSpec{
51+
Name: workerSubnet,
52+
CidrBlock: "",
53+
Description: ptr.To(description),
54+
Region: installConfig.Config.GCP.Region,
55+
}
56+
57+
// Add the CIDR information.
58+
machineV4CIDRs := []string{}
59+
for _, network := range installConfig.Config.Networking.MachineNetwork {
60+
if network.CIDR.IPNet.IP.To4() != nil {
61+
machineV4CIDRs = append(machineV4CIDRs, network.CIDR.IPNet.String())
62+
}
63+
}
64+
65+
if len(machineV4CIDRs) == 0 {
66+
return nil, fmt.Errorf("failed to parse machine CIDRs")
67+
}
68+
69+
_, ipv4Net, err := net.ParseCIDR(machineV4CIDRs[0])
70+
if err != nil {
71+
return nil, fmt.Errorf("failed to parse machine network CIDR: %w", err)
72+
}
73+
74+
if installConfig.Config.GCP.ControlPlaneSubnet == "" {
75+
masterCIDR, err := cidr.Subnet(ipv4Net, 1, 0)
76+
if err != nil {
77+
return nil, fmt.Errorf("failed to create the master subnet %w", err)
78+
}
79+
master.CidrBlock = masterCIDR.String()
80+
}
81+
82+
if installConfig.Config.GCP.ComputeSubnet == "" {
83+
workerCIDR, err := cidr.Subnet(ipv4Net, 1, 1)
84+
if err != nil {
85+
return nil, fmt.Errorf("failed to create the worker subnet %w", err)
86+
}
87+
worker.CidrBlock = workerCIDR.String()
88+
}
89+
90+
subnets := []capg.SubnetSpec{master, worker}
91+
92+
labels := map[string]string{}
93+
labels[fmt.Sprintf("kubernetes-io-cluster-%s", clusterID.InfraID)] = "owned"
94+
labels[fmt.Sprintf("capg-cluster-%s", clusterID.InfraID)] = "owned"
95+
for _, label := range installConfig.Config.GCP.UserLabels {
96+
labels[label.Key] = label.Value
97+
}
98+
99+
gcpCluster := &capg.GCPCluster{
100+
ObjectMeta: metav1.ObjectMeta{
101+
Name: clusterID.InfraID,
102+
Namespace: capiutils.Namespace,
103+
},
104+
Spec: capg.GCPClusterSpec{
105+
Project: installConfig.Config.GCP.ProjectID,
106+
Region: installConfig.Config.GCP.Region,
107+
Network: capg.NetworkSpec{
108+
// TODO: Need a network project for installs where the network resources will exist in another
109+
// project such as shared vpc installs
110+
Name: ptr.To(networkName),
111+
Subnets: subnets,
112+
},
113+
AdditionalLabels: labels,
114+
FailureDomains: findFailureDomains(installConfig),
115+
},
116+
}
117+
118+
manifests = append(manifests, &asset.RuntimeFile{
119+
Object: gcpCluster,
120+
File: asset.File{Filename: "02_gcp-cluster.yaml"},
121+
})
122+
123+
return &capiutils.GenerateClusterAssetsOutput{
124+
Manifests: manifests,
125+
InfrastructureRef: &corev1.ObjectReference{
126+
APIVersion: "infrastructure.cluster.x-k8s.io/v1beta1",
127+
Kind: "GCPCluster",
128+
Name: gcpCluster.Name,
129+
Namespace: gcpCluster.Namespace,
130+
},
131+
}, nil
132+
}
133+
134+
// findFailureDomains will find the failure domains or availability zones for the GCP platform.
135+
// When the default machine platform is defined, take any zone from the compute node(s) and
136+
// any defined in the control plane node(s). When the default machine platform is not defined,
137+
// only use zones if both the compute and control plane node availability zones exist.
138+
func findFailureDomains(installConfig *installconfig.InstallConfig) []string {
139+
zones := sets.New[string]()
140+
defaultMachinePlatformDefined := false
141+
if gcpPlatform := installConfig.Config.Platform.GCP; gcpPlatform != nil && gcpPlatform.DefaultMachinePlatform != nil {
142+
defaultMachinePlatformDefined = true
143+
for _, zone := range gcpPlatform.DefaultMachinePlatform.Zones {
144+
zones.Insert(zone)
145+
}
146+
147+
if installConfig.Config.ControlPlane.Platform.GCP != nil {
148+
for _, zone := range installConfig.Config.ControlPlane.Platform.GCP.Zones {
149+
zones.Insert(zone)
150+
}
151+
}
152+
if installConfig.Config.Compute[0].Platform.GCP != nil {
153+
for _, zone := range installConfig.Config.Compute[0].Platform.GCP.Zones {
154+
zones.Insert(zone)
155+
}
156+
}
157+
}
158+
if !defaultMachinePlatformDefined {
159+
if installConfig.Config.ControlPlane.Platform.GCP != nil && installConfig.Config.Compute[0].Platform.GCP != nil {
160+
for _, zone := range installConfig.Config.ControlPlane.Platform.GCP.Zones {
161+
zones.Insert(zone)
162+
}
163+
for _, zone := range installConfig.Config.Compute[0].Platform.GCP.Zones {
164+
zones.Insert(zone)
165+
}
166+
}
167+
}
168+
169+
return zones.UnsortedList()
170+
}

0 commit comments

Comments
 (0)