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

     1  package powervs
     2  
     3  import (
     4  	"context"
     5  	"crypto/rand"
     6  	"fmt"
     7  	"math/big"
     8  
     9  	"github.com/sirupsen/logrus"
    10  	corev1 "k8s.io/api/core/v1"
    11  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    12  	"k8s.io/utils/ptr"
    13  	capibm "sigs.k8s.io/cluster-api-provider-ibmcloud/api/v1beta2"
    14  
    15  	"github.com/openshift/installer/pkg/asset"
    16  	"github.com/openshift/installer/pkg/asset/installconfig"
    17  	"github.com/openshift/installer/pkg/asset/manifests/capiutils"
    18  	"github.com/openshift/installer/pkg/types"
    19  	powervstypes "github.com/openshift/installer/pkg/types/powervs"
    20  )
    21  
    22  // GenerateClusterAssets generates the manifests for the cluster-api.
    23  func GenerateClusterAssets(installConfig *installconfig.InstallConfig, clusterID *installconfig.ClusterID, bucket string, object string) (*capiutils.GenerateClusterAssetsOutput, error) {
    24  	var (
    25  		manifests          []*asset.RuntimeFile
    26  		network            string
    27  		dhcpSubnet         = "192.168.0.0/24"
    28  		service            capibm.IBMPowerVSResourceReference
    29  		vpcName            string
    30  		vpcRegion          string
    31  		transitGatewayName string
    32  		cosName            string
    33  		cosRegion          string
    34  		imageName          string
    35  		bucketName         string
    36  		err                error
    37  		powerVSCluster     *capibm.IBMPowerVSCluster
    38  		powerVSImage       *capibm.IBMPowerVSImage
    39  	)
    40  
    41  	defer func() {
    42  		logrus.Debugf("GenerateClusterAssets: installConfig = %+v, clusterID = %v, bucket = %v, object = %v", installConfig, *clusterID, bucket, object)
    43  		logrus.Debugf("GenerateClusterAssets: ic.ObjectMeta = %+v", installConfig.Config.ObjectMeta.Name)
    44  		logrus.Debugf("GenerateClusterAssets: installConfig.Config.PowerVS = %+v", *installConfig.Config.PowerVS)
    45  		logrus.Debugf("GenerateClusterAssets: vpcName = %v", vpcName)
    46  		logrus.Debugf("GenerateClusterAssets: vpcRegion = %v", vpcRegion)
    47  		logrus.Debugf("GenerateClusterAssets: transitGatewayName = %v", transitGatewayName)
    48  		logrus.Debugf("GenerateClusterAssets: cosName = %v", cosName)
    49  		logrus.Debugf("GenerateClusterAssets: cosRegion = %v", cosRegion)
    50  		logrus.Debugf("GenerateClusterAssets: imageName = %v", imageName)
    51  		logrus.Debugf("GenerateClusterAssets: bucketName = %v", bucketName)
    52  		logrus.Debugf("GenerateClusterAssets: powerVSCluster.Spec.ControlPlaneEndpoint.Host = %v", powerVSCluster.Spec.ControlPlaneEndpoint.Host)
    53  	}()
    54  
    55  	manifests = []*asset.RuntimeFile{}
    56  
    57  	network = fmt.Sprintf("%s-network", clusterID.InfraID)
    58  
    59  	n, err := rand.Int(rand.Reader, big.NewInt(253))
    60  	if err != nil {
    61  		return nil, fmt.Errorf("failed to generate random subnet: %w", err)
    62  	}
    63  	dhcpSubnet = fmt.Sprintf("192.168.%d.0/24", n.Int64())
    64  
    65  	if installConfig.Config.PowerVS.ServiceInstanceGUID == "" {
    66  		serviceName := fmt.Sprintf("%s-power-iaas", clusterID.InfraID)
    67  
    68  		service = capibm.IBMPowerVSResourceReference{
    69  			Name: &serviceName,
    70  		}
    71  	} else {
    72  		service = capibm.IBMPowerVSResourceReference{
    73  			ID: &installConfig.Config.PowerVS.ServiceInstanceGUID,
    74  		}
    75  	}
    76  
    77  	vpcName = installConfig.Config.Platform.PowerVS.VPCName
    78  	if vpcName == "" {
    79  		vpcName = fmt.Sprintf("vpc-%s", clusterID.InfraID)
    80  	}
    81  
    82  	vpcRegion = installConfig.Config.Platform.PowerVS.VPCRegion
    83  	if vpcRegion == "" {
    84  		if vpcRegion, err = powervstypes.VPCRegionForPowerVSRegion(installConfig.Config.PowerVS.Region); err != nil {
    85  			return nil, fmt.Errorf("unable to derive vpcRegion from region: %s %w", installConfig.Config.PowerVS.Region, err)
    86  		}
    87  	}
    88  
    89  	transitGatewayName = fmt.Sprintf("%s-tg", clusterID.InfraID)
    90  
    91  	cosName = fmt.Sprintf("%s-cos", clusterID.InfraID)
    92  
    93  	if cosRegion, err = powervstypes.COSRegionForPowerVSRegion(installConfig.Config.PowerVS.Region); err != nil {
    94  		return nil, fmt.Errorf("unable to derive cosRegion from region: %s %w", installConfig.Config.PowerVS.Region, err)
    95  	}
    96  
    97  	imageName = fmt.Sprintf("rhcos-%s", clusterID.InfraID)
    98  
    99  	bucketName = fmt.Sprintf("%s-bootstrap-ign", clusterID.InfraID)
   100  
   101  	powerVSCluster = &capibm.IBMPowerVSCluster{
   102  		TypeMeta: metav1.TypeMeta{
   103  			APIVersion: capibm.GroupVersion.String(),
   104  			Kind:       "IBMPowerVSCluster",
   105  		},
   106  		ObjectMeta: metav1.ObjectMeta{
   107  			Name:      clusterID.InfraID,
   108  			Namespace: capiutils.Namespace,
   109  			Annotations: map[string]string{
   110  				"powervs.cluster.x-k8s.io/create-infra": "true",
   111  			},
   112  		},
   113  		Spec: capibm.IBMPowerVSClusterSpec{
   114  			Network: capibm.IBMPowerVSResourceReference{
   115  				Name: &network,
   116  			},
   117  			DHCPServer: &capibm.DHCPServer{
   118  				Cidr: &dhcpSubnet,
   119  			},
   120  			ServiceInstance: &service,
   121  			Zone:            &installConfig.Config.Platform.PowerVS.Zone,
   122  			ResourceGroup: &capibm.IBMPowerVSResourceReference{
   123  				Name: &installConfig.Config.Platform.PowerVS.PowerVSResourceGroup,
   124  			},
   125  			VPC: &capibm.VPCResourceReference{
   126  				Name:   &vpcName,
   127  				Region: &vpcRegion,
   128  			},
   129  			TransitGateway: &capibm.TransitGateway{
   130  				Name: &transitGatewayName,
   131  			},
   132  			LoadBalancers: []capibm.VPCLoadBalancerSpec{
   133  				{
   134  					Name:   fmt.Sprintf("%s-loadbalancer", clusterID.InfraID),
   135  					Public: ptr.To(true),
   136  					AdditionalListeners: []capibm.AdditionalListenerSpec{
   137  						{
   138  							Port: 22,
   139  						},
   140  						// @BUG We should be able to specify this:
   141  						// capibm.AdditionalListenerSpec{
   142  						//	Port: 6443,
   143  						// },
   144  					},
   145  				},
   146  				{
   147  					Name:   fmt.Sprintf("%s-loadbalancer-int", clusterID.InfraID),
   148  					Public: ptr.To(false),
   149  					AdditionalListeners: []capibm.AdditionalListenerSpec{
   150  						// @BUG We should be able to specify this:
   151  						// capibm.AdditionalListenerSpec{
   152  						//	Port: 6443,
   153  						// },
   154  						{
   155  							Port: 22623,
   156  						},
   157  					},
   158  				},
   159  			},
   160  			CosInstance: &capibm.CosInstance{
   161  				Name:         cosName,
   162  				BucketName:   bucketName,
   163  				BucketRegion: cosRegion,
   164  			},
   165  			Ignition: &capibm.Ignition{
   166  				Version: "3.4",
   167  			},
   168  		},
   169  	}
   170  
   171  	// Use a custom resolver if using an Internal publishing strategy
   172  	if installConfig.Config.Publish == types.InternalPublishingStrategy {
   173  		dnsServerIP, err := installConfig.PowerVS.GetDNSServerIP(context.TODO(), installConfig.Config.PowerVS.VPCName)
   174  		if err != nil {
   175  			return nil, fmt.Errorf("unable to find a DNS server for specified VPC: %s %w", installConfig.Config.PowerVS.VPCName, err)
   176  		}
   177  
   178  		powerVSCluster.Spec.DHCPServer.DNSServer = &dnsServerIP
   179  		// TODO(mjturek): Restore once work is finished in 4.18 for disconnected scenario.
   180  		if !(len(installConfig.Config.DeprecatedImageContentSources) == 0 && len(installConfig.Config.ImageDigestSources) == 0) {
   181  			return nil, fmt.Errorf("deploying a disconnected cluster directly in 4.17 is not supported for Power VS. Please deploy disconnected in 4.16 and upgrade to 4.17")
   182  		}
   183  	}
   184  
   185  	// If a VPC was specified, pass all subnets in it to cluster API
   186  	if installConfig.Config.Platform.PowerVS.VPCName != "" {
   187  		logrus.Debugf("GenerateClusterAssets: VPCName = %s", installConfig.Config.Platform.PowerVS.VPCName)
   188  		if installConfig.Config.Publish == types.InternalPublishingStrategy {
   189  			err = installConfig.PowerVS.EnsureVPCIsPermittedNetwork(context.TODO(), installConfig.Config.PowerVS.VPCName)
   190  		}
   191  		if err != nil {
   192  			return nil, fmt.Errorf("error ensuring VPC is permitted: %s %w", installConfig.Config.PowerVS.VPCName, err)
   193  		}
   194  		subnets, err := installConfig.PowerVS.GetVPCSubnets(context.TODO(), vpcName)
   195  		if err != nil {
   196  			return nil, fmt.Errorf("error getting subnets in specified VPC: %s %w", installConfig.Config.PowerVS.VPCName, err)
   197  		}
   198  		for _, subnet := range subnets {
   199  			powerVSCluster.Spec.VPCSubnets = append(powerVSCluster.Spec.VPCSubnets,
   200  				capibm.Subnet{
   201  					ID:   subnet.ID,
   202  					Name: subnet.Name,
   203  				})
   204  		}
   205  		logrus.Debugf("GenerateClusterAssets: subnets = %+v", powerVSCluster.Spec.VPCSubnets)
   206  	}
   207  
   208  	manifests = append(manifests, &asset.RuntimeFile{
   209  		Object: powerVSCluster,
   210  		File:   asset.File{Filename: "02_powervs-cluster.yaml"},
   211  	})
   212  
   213  	powerVSImage = &capibm.IBMPowerVSImage{
   214  		TypeMeta: metav1.TypeMeta{
   215  			APIVersion: capibm.GroupVersion.String(),
   216  			Kind:       "IBMPowerVSImage",
   217  		},
   218  		ObjectMeta: metav1.ObjectMeta{
   219  			Name:      imageName,
   220  			Namespace: capiutils.Namespace,
   221  		},
   222  		Spec: capibm.IBMPowerVSImageSpec{
   223  			ClusterName:     clusterID.InfraID,
   224  			ServiceInstance: &service,
   225  			Bucket:          &bucket,
   226  			Object:          &object,
   227  			Region:          &cosRegion,
   228  		},
   229  	}
   230  
   231  	manifests = append(manifests, &asset.RuntimeFile{
   232  		Object: powerVSImage,
   233  		File:   asset.File{Filename: "03_powervs-image.yaml"},
   234  	})
   235  
   236  	return &capiutils.GenerateClusterAssetsOutput{
   237  		Manifests: manifests,
   238  		InfrastructureRefs: []*corev1.ObjectReference{
   239  			{
   240  				APIVersion: "infrastructure.cluster.x-k8s.io/v1beta2",
   241  				Kind:       "IBMPowerVSCluster",
   242  				Name:       powerVSCluster.Name,
   243  				Namespace:  powerVSCluster.Namespace,
   244  			},
   245  		},
   246  	}, nil
   247  }