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

     1  package openstack
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  
     7  	"github.com/gophercloud/utils/v2/openstack/clientconfig"
     8  	corev1 "k8s.io/api/core/v1"
     9  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    10  	"k8s.io/utils/ptr"
    11  	capo "sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1"
    12  	"sigs.k8s.io/cluster-api-provider-openstack/pkg/utils/optional"
    13  	capi "sigs.k8s.io/cluster-api/api/v1beta1"
    14  	"sigs.k8s.io/yaml"
    15  
    16  	"github.com/openshift/installer/pkg/asset"
    17  	"github.com/openshift/installer/pkg/asset/installconfig"
    18  	"github.com/openshift/installer/pkg/asset/manifests/capiutils"
    19  )
    20  
    21  const (
    22  	cloudName = "openstack"
    23  )
    24  
    25  // GenerateClusterAssets generates the cluster manifests for the cluster-api.
    26  func GenerateClusterAssets(installConfig *installconfig.InstallConfig, clusterID *installconfig.ClusterID) (*capiutils.GenerateClusterAssetsOutput, error) {
    27  	manifests := []*asset.RuntimeFile{}
    28  	openstackInstallConfig := installConfig.Config.OpenStack
    29  
    30  	var (
    31  		externalNetwork        *capo.NetworkParam
    32  		disableExternalNetwork optional.Bool
    33  	)
    34  	if e := openstackInstallConfig.ExternalNetwork; e != "" {
    35  		externalNetwork = &capo.NetworkParam{Filter: &capo.NetworkFilter{Name: e}}
    36  	} else {
    37  		disableExternalNetwork = ptr.To(true)
    38  	}
    39  
    40  	openStackCluster := &capo.OpenStackCluster{
    41  		ObjectMeta: metav1.ObjectMeta{
    42  			Name:      clusterID.InfraID,
    43  			Namespace: capiutils.Namespace,
    44  			Labels: map[string]string{
    45  				capi.ClusterNameLabel: clusterID.InfraID,
    46  			},
    47  		},
    48  		Spec: capo.OpenStackClusterSpec{
    49  			IdentityRef: capo.OpenStackIdentityReference{
    50  				Name:      clusterID.InfraID + "-cloud-config",
    51  				CloudName: cloudName,
    52  			},
    53  			// We disable management of most networking resources since either
    54  			// we (the installer) will create them, or the user will have
    55  			// pre-created them as part of a "Bring Your Own Network (BYON)"
    56  			// configuration
    57  			ManagedSecurityGroups:      nil,
    58  			DisableAPIServerFloatingIP: ptr.To(true),
    59  			// TODO(stephenfin): update when we support dual-stack (there are
    60  			// potentially *two* IPs here)
    61  			APIServerFixedIP:       &openstackInstallConfig.APIVIPs[0],
    62  			ExternalNetwork:        externalNetwork,
    63  			DisableExternalNetwork: disableExternalNetwork,
    64  			Tags: []string{
    65  				fmt.Sprintf("openshiftClusterID=%s", clusterID.InfraID),
    66  			},
    67  		},
    68  	}
    69  	if cpPort := openstackInstallConfig.ControlPlanePort; cpPort != nil {
    70  		if networkID := cpPort.Network.ID; networkID != "" {
    71  			openStackCluster.Spec.Network = &capo.NetworkParam{ID: &networkID}
    72  		} else if networkName := cpPort.Network.Name; networkName != "" {
    73  			openStackCluster.Spec.Network = &capo.NetworkParam{Filter: &capo.NetworkFilter{Name: networkName}}
    74  		}
    75  		openStackCluster.Spec.Subnets = make([]capo.SubnetParam, len(cpPort.FixedIPs))
    76  		for i := range cpPort.FixedIPs {
    77  			if subnetID := cpPort.FixedIPs[i].Subnet.ID; subnetID != "" {
    78  				openStackCluster.Spec.Subnets[i] = capo.SubnetParam{ID: &subnetID}
    79  			} else {
    80  				openStackCluster.Spec.Subnets[i] = capo.SubnetParam{Filter: &capo.SubnetFilter{Name: cpPort.FixedIPs[i].Subnet.Name}}
    81  			}
    82  		}
    83  	} else {
    84  		openStackCluster.Spec.ManagedSubnets = []capo.SubnetSpec{
    85  			{
    86  				CIDR:           capiutils.CIDRFromInstallConfig(installConfig).String(),
    87  				DNSNameservers: openstackInstallConfig.ExternalDNS,
    88  			},
    89  		}
    90  	}
    91  	openStackCluster.SetGroupVersionKind(capo.GroupVersion.WithKind("OpenStackCluster"))
    92  
    93  	manifests = append(manifests, &asset.RuntimeFile{
    94  		Object: openStackCluster,
    95  		File:   asset.File{Filename: "02_infra-cluster.yaml"},
    96  	})
    97  
    98  	cloudConfig, err := generateCloudConfig(installConfig)
    99  	if err != nil {
   100  		return nil, err
   101  	}
   102  
   103  	openStackIdentity := &corev1.Secret{
   104  		ObjectMeta: metav1.ObjectMeta{
   105  			Name:      clusterID.InfraID + "-cloud-config",
   106  			Namespace: capiutils.Namespace,
   107  		},
   108  		Data: cloudConfig,
   109  	}
   110  	openStackIdentity.SetGroupVersionKind(corev1.SchemeGroupVersion.WithKind("Secret"))
   111  
   112  	manifests = append(manifests, &asset.RuntimeFile{
   113  		Object: openStackIdentity,
   114  		File:   asset.File{Filename: "02_openstack-cloud-config.yaml"},
   115  	})
   116  
   117  	return &capiutils.GenerateClusterAssetsOutput{
   118  		Manifests: manifests,
   119  		InfrastructureRefs: []*corev1.ObjectReference{
   120  			{
   121  				APIVersion: capo.GroupVersion.String(),
   122  				Kind:       "OpenStackCluster",
   123  				Name:       openStackCluster.Name,
   124  				Namespace:  openStackCluster.Namespace,
   125  			},
   126  		},
   127  	}, nil
   128  }
   129  
   130  func generateCloudConfig(installConfig *installconfig.InstallConfig) (map[string][]byte, error) {
   131  	opts := new(clientconfig.ClientOpts)
   132  	opts.Cloud = installConfig.Config.Platform.OpenStack.Cloud
   133  
   134  	cloud, err := clientconfig.GetCloudFromYAML(opts)
   135  	if err != nil {
   136  		return nil, err
   137  	}
   138  
   139  	// We need to replace the local cacert path with the one used by CAPO
   140  	caCert := []byte{}
   141  	if cloud.CACertFile != "" {
   142  		caCert, err = os.ReadFile(cloud.CACertFile)
   143  		if err != nil {
   144  			return nil, err
   145  		}
   146  
   147  		// TODO: Verify this path. This is taken from CAPO directly
   148  		// https://github.com/kubernetes-sigs/cluster-api-provider-openstack/blob/main/templates/env.rc
   149  		cloud.CACertFile = "/etc/certs/cacert"
   150  	}
   151  
   152  	clouds := make(map[string]map[string]*clientconfig.Cloud)
   153  	clouds["clouds"] = map[string]*clientconfig.Cloud{
   154  		cloudName: cloud,
   155  	}
   156  
   157  	cloudsYAML, err := yaml.Marshal(clouds)
   158  	if err != nil {
   159  		return nil, err
   160  	}
   161  
   162  	creds := map[string][]byte{
   163  		"clouds.yaml": cloudsYAML,
   164  	}
   165  	if len(caCert) != 0 {
   166  		creds["cacert"] = caCert
   167  	}
   168  
   169  	return creds, nil
   170  }