github.com/openshift/installer@v1.4.17/pkg/asset/manifests/aws/cluster.go (about)

     1  package aws
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"time"
     7  
     8  	corev1 "k8s.io/api/core/v1"
     9  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    10  	"k8s.io/utils/ptr"
    11  	capa "sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2"
    12  
    13  	"github.com/openshift/installer/pkg/asset"
    14  	"github.com/openshift/installer/pkg/asset/installconfig"
    15  	"github.com/openshift/installer/pkg/asset/machines/aws"
    16  	"github.com/openshift/installer/pkg/asset/manifests/capiutils"
    17  )
    18  
    19  // BootstrapSSHDescription is the description for the
    20  // ingress rule that provides SSH access to the bootstrap node
    21  // & identifies the rule for removal during bootstrap destroy.
    22  const BootstrapSSHDescription = "Bootstrap SSH Access"
    23  
    24  // GenerateClusterAssets generates the manifests for the cluster-api.
    25  func GenerateClusterAssets(ic *installconfig.InstallConfig, clusterID *installconfig.ClusterID) (*capiutils.GenerateClusterAssetsOutput, error) {
    26  	manifests := []*asset.RuntimeFile{}
    27  
    28  	tags, err := aws.CapaTagsFromUserTags(clusterID.InfraID, ic.Config.AWS.UserTags)
    29  	if err != nil {
    30  		return nil, fmt.Errorf("failed to get user tags: %w", err)
    31  	}
    32  
    33  	sshRuleCidr := []string{"0.0.0.0/0"}
    34  	if !ic.Config.PublicAPI() {
    35  		sshRuleCidr = []string{capiutils.CIDRFromInstallConfig(ic).String()}
    36  	}
    37  
    38  	awsCluster := &capa.AWSCluster{
    39  		ObjectMeta: metav1.ObjectMeta{
    40  			Name:      clusterID.InfraID,
    41  			Namespace: capiutils.Namespace,
    42  		},
    43  		Spec: capa.AWSClusterSpec{
    44  			Region: ic.Config.AWS.Region,
    45  			NetworkSpec: capa.NetworkSpec{
    46  				CNI: &capa.CNISpec{
    47  					CNIIngressRules: capa.CNIIngressRules{
    48  						{
    49  							Description: "ICMP",
    50  							Protocol:    capa.SecurityGroupProtocolICMP,
    51  							FromPort:    -1,
    52  							ToPort:      -1,
    53  						},
    54  						{
    55  							Description: "Port 22 (TCP)",
    56  							Protocol:    capa.SecurityGroupProtocolTCP,
    57  							FromPort:    22,
    58  							ToPort:      22,
    59  						},
    60  						{
    61  							Description: "Port 4789 (UDP) for VXLAN",
    62  							Protocol:    capa.SecurityGroupProtocolUDP,
    63  							FromPort:    4789,
    64  							ToPort:      4789,
    65  						},
    66  						{
    67  							Description: "Port 6081 (UDP) for geneve",
    68  							Protocol:    capa.SecurityGroupProtocolUDP,
    69  							FromPort:    6081,
    70  							ToPort:      6081,
    71  						},
    72  						{
    73  							Description: "Port 500 (UDP) for IKE",
    74  							Protocol:    capa.SecurityGroupProtocolUDP,
    75  							FromPort:    500,
    76  							ToPort:      500,
    77  						},
    78  						{
    79  							Description: "Port 4500 (UDP) for IKE NAT",
    80  							Protocol:    capa.SecurityGroupProtocolUDP,
    81  							FromPort:    4500,
    82  							ToPort:      4500,
    83  						},
    84  						{
    85  							Description: "ESP",
    86  							Protocol:    capa.SecurityGroupProtocolESP,
    87  							FromPort:    -1,
    88  							ToPort:      -1,
    89  						},
    90  						{
    91  							Description: "Port 6441-6442 (TCP) for ovndb",
    92  							Protocol:    capa.SecurityGroupProtocolTCP,
    93  							FromPort:    6441,
    94  							ToPort:      6442,
    95  						},
    96  						{
    97  							Description: "Port 9000-9999 for node ports (TCP)",
    98  							Protocol:    capa.SecurityGroupProtocolTCP,
    99  							FromPort:    9000,
   100  							ToPort:      9999,
   101  						},
   102  						{
   103  							Description: "Port 9000-9999 for node ports (UDP)",
   104  							Protocol:    capa.SecurityGroupProtocolUDP,
   105  							FromPort:    9000,
   106  							ToPort:      9999,
   107  						},
   108  						{
   109  							Description: "Service node ports (TCP)",
   110  							Protocol:    capa.SecurityGroupProtocolTCP,
   111  							FromPort:    30000,
   112  							ToPort:      32767,
   113  						},
   114  						{
   115  							Description: "Service node ports (UDP)",
   116  							Protocol:    capa.SecurityGroupProtocolUDP,
   117  							FromPort:    30000,
   118  							ToPort:      32767,
   119  						},
   120  					},
   121  				},
   122  				AdditionalControlPlaneIngressRules: []capa.IngressRule{
   123  					{
   124  						Description:              "MCS traffic from cluster network",
   125  						Protocol:                 capa.SecurityGroupProtocolTCP,
   126  						FromPort:                 22623,
   127  						ToPort:                   22623,
   128  						SourceSecurityGroupRoles: []capa.SecurityGroupRole{"node", "controlplane"},
   129  					},
   130  					{
   131  						Description:              "controller-manager",
   132  						Protocol:                 capa.SecurityGroupProtocolTCP,
   133  						FromPort:                 10257,
   134  						ToPort:                   10257,
   135  						SourceSecurityGroupRoles: []capa.SecurityGroupRole{"controlplane", "node"},
   136  					},
   137  					{
   138  						Description:              "kube-scheduler",
   139  						Protocol:                 capa.SecurityGroupProtocolTCP,
   140  						FromPort:                 10259,
   141  						ToPort:                   10259,
   142  						SourceSecurityGroupRoles: []capa.SecurityGroupRole{"controlplane", "node"},
   143  					},
   144  					{
   145  						Description: BootstrapSSHDescription,
   146  						Protocol:    capa.SecurityGroupProtocolTCP,
   147  						FromPort:    22,
   148  						ToPort:      22,
   149  						CidrBlocks:  sshRuleCidr,
   150  					},
   151  				},
   152  			},
   153  			S3Bucket: &capa.S3Bucket{
   154  				Name:                    GetIgnitionBucketName(clusterID.InfraID),
   155  				PresignedURLDuration:    &metav1.Duration{Duration: 1 * time.Hour},
   156  				BestEffortDeleteObjects: ptr.To(ic.Config.AWS.BestEffortDeleteIgnition),
   157  			},
   158  			ControlPlaneLoadBalancer: &capa.AWSLoadBalancerSpec{
   159  				Name:                   ptr.To(clusterID.InfraID + "-int"),
   160  				LoadBalancerType:       capa.LoadBalancerTypeNLB,
   161  				Scheme:                 &capa.ELBSchemeInternal,
   162  				CrossZoneLoadBalancing: true,
   163  				HealthCheckProtocol:    &capa.ELBProtocolHTTPS,
   164  				HealthCheck: &capa.TargetGroupHealthCheckAPISpec{
   165  					IntervalSeconds:         ptr.To[int64](10),
   166  					TimeoutSeconds:          ptr.To[int64](10),
   167  					ThresholdCount:          ptr.To[int64](2),
   168  					UnhealthyThresholdCount: ptr.To[int64](2),
   169  				},
   170  				AdditionalListeners: []capa.AdditionalListenerSpec{
   171  					{
   172  						Port:     22623,
   173  						Protocol: capa.ELBProtocolTCP,
   174  						HealthCheck: &capa.TargetGroupHealthCheckAdditionalSpec{
   175  							Protocol:                ptr.To[string](capa.ELBProtocolHTTPS.String()),
   176  							Port:                    ptr.To[string]("22623"),
   177  							Path:                    ptr.To[string]("/healthz"),
   178  							IntervalSeconds:         ptr.To[int64](10),
   179  							TimeoutSeconds:          ptr.To[int64](10),
   180  							ThresholdCount:          ptr.To[int64](2),
   181  							UnhealthyThresholdCount: ptr.To[int64](2),
   182  						},
   183  					},
   184  				},
   185  				IngressRules: []capa.IngressRule{
   186  					{
   187  						Description: "Machine Config Server internal traffic from cluster",
   188  						Protocol:    capa.SecurityGroupProtocolTCP,
   189  						FromPort:    22623,
   190  						ToPort:      22623,
   191  						CidrBlocks:  []string{capiutils.CIDRFromInstallConfig(ic).String()},
   192  					},
   193  				},
   194  			},
   195  			AdditionalTags: tags,
   196  		},
   197  	}
   198  	awsCluster.SetGroupVersionKind(capa.GroupVersion.WithKind("AWSCluster"))
   199  
   200  	if ic.Config.PublicAPI() {
   201  		awsCluster.Spec.SecondaryControlPlaneLoadBalancer = &capa.AWSLoadBalancerSpec{
   202  			Name:                   ptr.To(clusterID.InfraID + "-ext"),
   203  			LoadBalancerType:       capa.LoadBalancerTypeNLB,
   204  			Scheme:                 &capa.ELBSchemeInternetFacing,
   205  			CrossZoneLoadBalancing: true,
   206  			HealthCheckProtocol:    &capa.ELBProtocolHTTPS,
   207  			HealthCheck: &capa.TargetGroupHealthCheckAPISpec{
   208  				IntervalSeconds:         ptr.To[int64](10),
   209  				TimeoutSeconds:          ptr.To[int64](10),
   210  				ThresholdCount:          ptr.To[int64](2),
   211  				UnhealthyThresholdCount: ptr.To[int64](2),
   212  			},
   213  			IngressRules: []capa.IngressRule{
   214  				{
   215  					Description: "Kubernetes API Server traffic for public access",
   216  					Protocol:    capa.SecurityGroupProtocolTCP,
   217  					FromPort:    6443,
   218  					ToPort:      6443,
   219  					CidrBlocks:  []string{"0.0.0.0/0"},
   220  				},
   221  			},
   222  		}
   223  	} else {
   224  		awsCluster.Spec.ControlPlaneLoadBalancer.IngressRules = append(
   225  			awsCluster.Spec.ControlPlaneLoadBalancer.IngressRules,
   226  			capa.IngressRule{
   227  				Description: "Kubernetes API Server traffic",
   228  				Protocol:    capa.SecurityGroupProtocolTCP,
   229  				FromPort:    6443,
   230  				ToPort:      6443,
   231  				CidrBlocks:  []string{"0.0.0.0/0"},
   232  			},
   233  		)
   234  	}
   235  
   236  	// Set the NetworkSpec.Subnets from VPC and zones (managed)
   237  	// or subnets (BYO VPC) based in the install-config.yaml.
   238  	err = setSubnets(context.TODO(), &zonesInput{
   239  		InstallConfig: ic,
   240  		ClusterID:     clusterID,
   241  		Cluster:       awsCluster,
   242  	})
   243  	if err != nil {
   244  		return nil, fmt.Errorf("failed to set cluster zones or subnets: %w", err)
   245  	}
   246  
   247  	// Enable BYO Public IPv4 when defined on install-config.yaml
   248  	if len(ic.Config.Platform.AWS.PublicIpv4Pool) > 0 {
   249  		awsCluster.Spec.NetworkSpec.VPC.ElasticIPPool = &capa.ElasticIPPool{
   250  			PublicIpv4Pool:              ptr.To(ic.Config.Platform.AWS.PublicIpv4Pool),
   251  			PublicIpv4PoolFallBackOrder: ptr.To(capa.PublicIpv4PoolFallbackOrderAmazonPool),
   252  		}
   253  	}
   254  
   255  	manifests = append(manifests, &asset.RuntimeFile{
   256  		Object: awsCluster,
   257  		File:   asset.File{Filename: "02_infra-cluster.yaml"},
   258  	})
   259  
   260  	id := &capa.AWSClusterControllerIdentity{
   261  		ObjectMeta: metav1.ObjectMeta{
   262  			Name:      "default",
   263  			Namespace: capiutils.Namespace,
   264  		},
   265  		Spec: capa.AWSClusterControllerIdentitySpec{
   266  			AWSClusterIdentitySpec: capa.AWSClusterIdentitySpec{
   267  				AllowedNamespaces: &capa.AllowedNamespaces{}, // Allow all namespaces.
   268  			},
   269  		},
   270  	}
   271  	id.SetGroupVersionKind(capa.GroupVersion.WithKind("AWSClusterControllerIdentity"))
   272  	manifests = append(manifests, &asset.RuntimeFile{
   273  		Object: id,
   274  		File:   asset.File{Filename: "01_aws-cluster-controller-identity-default.yaml"},
   275  	})
   276  
   277  	return &capiutils.GenerateClusterAssetsOutput{
   278  		Manifests: manifests,
   279  		InfrastructureRefs: []*corev1.ObjectReference{
   280  			{
   281  				APIVersion: capa.GroupVersion.String(),
   282  				Kind:       "AWSCluster",
   283  				Name:       awsCluster.Name,
   284  				Namespace:  awsCluster.Namespace,
   285  			},
   286  		},
   287  	}, nil
   288  }
   289  
   290  // GetIgnitionBucketName returns the name of the bucket for the given cluster.
   291  func GetIgnitionBucketName(infraID string) string {
   292  	return fmt.Sprintf("openshift-bootstrap-data-%s", infraID)
   293  }