github.com/openshift/installer@v1.4.17/pkg/asset/manifests/azure/cluster.go (about) 1 package azure 2 3 import ( 4 "fmt" 5 6 "github.com/Azure/azure-sdk-for-go/sdk/azcore/to" 7 "github.com/pkg/errors" 8 corev1 "k8s.io/api/core/v1" 9 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 10 "k8s.io/utils/ptr" 11 capz "sigs.k8s.io/cluster-api-provider-azure/api/v1beta1" 12 13 "github.com/openshift/installer/pkg/asset" 14 "github.com/openshift/installer/pkg/asset/installconfig" 15 azic "github.com/openshift/installer/pkg/asset/installconfig/azure" 16 "github.com/openshift/installer/pkg/asset/manifests/capiutils" 17 "github.com/openshift/installer/pkg/asset/manifests/capiutils/cidr" 18 "github.com/openshift/installer/pkg/types" 19 "github.com/openshift/installer/pkg/types/azure" 20 ) 21 22 // GenerateClusterAssets generates the manifests for the cluster-api. 23 func GenerateClusterAssets(installConfig *installconfig.InstallConfig, clusterID *installconfig.ClusterID) (*capiutils.GenerateClusterAssetsOutput, error) { 24 manifests := []*asset.RuntimeFile{} 25 mainCIDR := capiutils.CIDRFromInstallConfig(installConfig) 26 27 session, err := installConfig.Azure.Session() 28 if err != nil { 29 return nil, errors.Wrap(err, "failed to create Azure session") 30 } 31 32 subnets, err := cidr.SplitIntoSubnetsIPv4(mainCIDR.String(), 2) 33 if err != nil { 34 return nil, errors.Wrap(err, "failed to split CIDR into subnets") 35 } 36 37 // CAPZ expects the capz-system to be created. 38 azureNamespace := &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "capz-system"}} 39 azureNamespace.SetGroupVersionKind(corev1.SchemeGroupVersion.WithKind("Namespace")) 40 manifests = append(manifests, &asset.RuntimeFile{ 41 Object: azureNamespace, 42 File: asset.File{Filename: "00_azure-namespace.yaml"}, 43 }) 44 45 resourceGroup := installConfig.Config.Platform.Azure.ClusterResourceGroupName(clusterID.InfraID) 46 controlPlaneSubnet := installConfig.Config.Platform.Azure.ControlPlaneSubnetName(clusterID.InfraID) 47 computeSubnet := installConfig.Config.Platform.Azure.ComputeSubnetName(clusterID.InfraID) 48 networkSecurityGroup := installConfig.Config.Platform.Azure.NetworkSecurityGroupName(clusterID.InfraID) 49 50 controlPlaneOutboundLB := &capz.LoadBalancerSpec{ 51 Name: clusterID.InfraID, 52 FrontendIPsCount: to.Ptr(int32(1)), 53 } 54 if installConfig.Config.Platform.Azure.OutboundType == azure.UserDefinedRoutingOutboundType { 55 controlPlaneOutboundLB = nil 56 } 57 58 source := "*" 59 if installConfig.Config.Publish == types.InternalPublishingStrategy { 60 source = mainCIDR.String() 61 } 62 63 securityGroup := capz.SecurityGroup{ 64 Name: networkSecurityGroup, 65 SecurityGroupClass: capz.SecurityGroupClass{ 66 SecurityRules: []capz.SecurityRule{ 67 { 68 Name: "apiserver_in", 69 Protocol: capz.SecurityGroupProtocolTCP, 70 Direction: capz.SecurityRuleDirectionInbound, 71 Priority: 101, 72 SourcePorts: ptr.To("*"), 73 DestinationPorts: ptr.To("6443"), 74 Source: ptr.To(source), 75 Destination: ptr.To("*"), 76 Action: capz.SecurityRuleActionAllow, 77 }, 78 }, 79 }, 80 } 81 82 // Setting ID on the Subnet disables natgw creation. See: 83 // https://github.com/kubernetes-sigs/cluster-api-provider-azure/blob/21479a9a4c640b43e0bef028487c522c55605d06/api/v1beta1/azurecluster_default.go#L160 84 // CAPZ enables NAT Gateways by default, so we are using this hack to disable 85 // nat gateways when we prefer to use load balancers for node egress. 86 nodeSubnetID := "" 87 if installConfig.Config.Platform.Azure.OutboundType != azure.NatGatewayOutboundType { 88 // Because the node subnet does not already exist, we are using an arbitrary value. 89 // We could populate this with the proper subnet ID in the case of BYO VNET, but 90 // the value currently has no practical effect. 91 nodeSubnetID = "UNKNOWN" 92 } 93 94 azureCluster := &capz.AzureCluster{ 95 ObjectMeta: metav1.ObjectMeta{ 96 Name: clusterID.InfraID, 97 Namespace: capiutils.Namespace, 98 }, 99 Spec: capz.AzureClusterSpec{ 100 ResourceGroup: resourceGroup, 101 AzureClusterClassSpec: capz.AzureClusterClassSpec{ 102 SubscriptionID: session.Credentials.SubscriptionID, 103 Location: installConfig.Config.Azure.Region, 104 AdditionalTags: installConfig.Config.Platform.Azure.UserTags, 105 AzureEnvironment: string(installConfig.Azure.CloudName), 106 IdentityRef: &corev1.ObjectReference{ 107 APIVersion: capz.GroupVersion.String(), 108 Kind: "AzureClusterIdentity", 109 Name: clusterID.InfraID, 110 }, 111 }, 112 NetworkSpec: capz.NetworkSpec{ 113 NetworkClassSpec: capz.NetworkClassSpec{ 114 PrivateDNSZoneName: installConfig.Config.ClusterDomain(), 115 }, 116 Vnet: capz.VnetSpec{ 117 ResourceGroup: installConfig.Config.Azure.NetworkResourceGroupName, 118 Name: installConfig.Config.Azure.VirtualNetwork, 119 // The ID is set to virtual network here for existing vnets here. This is to force CAPZ to consider this resource as 120 // "not managed" which would prevent the creation of an additional nsg and route table in the network resource group. 121 // The ID field is not used for any other purpose in CAPZ except to set the "managed" status. 122 // See https://github.com/kubernetes-sigs/cluster-api-provider-azure/blob/main/azure/scope/cluster.go#L585 123 // https://github.com/kubernetes-sigs/cluster-api-provider-azure/commit/0f321e4089a3f4dc37f8420bf2ef6762c398c400 124 ID: installConfig.Config.Azure.VirtualNetwork, 125 VnetClassSpec: capz.VnetClassSpec{ 126 CIDRBlocks: []string{ 127 mainCIDR.String(), 128 }, 129 }, 130 }, 131 APIServerLB: capz.LoadBalancerSpec{ 132 Name: fmt.Sprintf("%s-internal", clusterID.InfraID), 133 BackendPool: capz.BackendPool{ 134 Name: fmt.Sprintf("%s-internal", clusterID.InfraID), 135 }, 136 LoadBalancerClassSpec: capz.LoadBalancerClassSpec{ 137 Type: capz.Internal, 138 }, 139 }, 140 ControlPlaneOutboundLB: controlPlaneOutboundLB, 141 Subnets: capz.Subnets{ 142 { 143 SubnetClassSpec: capz.SubnetClassSpec{ 144 Name: controlPlaneSubnet, 145 Role: capz.SubnetControlPlane, 146 CIDRBlocks: []string{ 147 subnets[0].String(), 148 }, 149 }, 150 SecurityGroup: securityGroup, 151 }, 152 { 153 ID: nodeSubnetID, 154 SubnetClassSpec: capz.SubnetClassSpec{ 155 Name: computeSubnet, 156 Role: capz.SubnetNode, 157 CIDRBlocks: []string{ 158 subnets[1].String(), 159 }, 160 }, 161 SecurityGroup: securityGroup, 162 }, 163 }, 164 }, 165 }, 166 } 167 azureCluster.SetGroupVersionKind(capz.GroupVersion.WithKind("AzureCluster")) 168 manifests = append(manifests, &asset.RuntimeFile{ 169 Object: azureCluster, 170 File: asset.File{Filename: "02_azure-cluster.yaml"}, 171 }) 172 173 azureClientSecret := &corev1.Secret{ 174 ObjectMeta: metav1.ObjectMeta{ 175 Name: clusterID.InfraID + "-azure-client-secret", 176 Namespace: capiutils.Namespace, 177 }, 178 StringData: map[string]string{ 179 "clientSecret": session.Credentials.ClientSecret, 180 }, 181 } 182 azureClientSecret.SetGroupVersionKind(corev1.SchemeGroupVersion.WithKind("Secret")) 183 manifests = append(manifests, &asset.RuntimeFile{ 184 Object: azureClientSecret, 185 File: asset.File{Filename: "01_azure-client-secret.yaml"}, 186 }) 187 188 id := &capz.AzureClusterIdentity{ 189 ObjectMeta: metav1.ObjectMeta{ 190 Name: clusterID.InfraID, 191 Namespace: capiutils.Namespace, 192 }, 193 Spec: capz.AzureClusterIdentitySpec{ 194 Type: capz.ServicePrincipal, 195 AllowedNamespaces: &capz.AllowedNamespaces{}, // Allow all namespaces. 196 ClientID: session.Credentials.ClientID, 197 ClientSecret: corev1.SecretReference{ 198 Name: azureClientSecret.Name, 199 Namespace: azureClientSecret.Namespace, 200 }, 201 TenantID: session.Credentials.TenantID, 202 }, 203 } 204 if session.AuthType == azic.ManagedIdentityAuth { 205 id.Spec.Type = capz.UserAssignedMSI 206 id.Spec.ClientSecret = corev1.SecretReference{} 207 } 208 id.SetGroupVersionKind(capz.GroupVersion.WithKind("AzureClusterIdentity")) 209 manifests = append(manifests, &asset.RuntimeFile{ 210 Object: id, 211 File: asset.File{Filename: "01_azure-cluster-controller-identity-default.yaml"}, 212 }) 213 214 return &capiutils.GenerateClusterAssetsOutput{ 215 Manifests: manifests, 216 InfrastructureRefs: []*corev1.ObjectReference{ 217 { 218 APIVersion: capz.GroupVersion.String(), 219 Kind: "AzureCluster", 220 Name: azureCluster.Name, 221 Namespace: azureCluster.Namespace, 222 }, 223 }, 224 }, nil 225 }