github.com/openshift/installer@v1.4.17/pkg/asset/machines/nutanix/capimachines.go (about) 1 // Package generates capi Machine objects for nutanix. 2 package nutanix 3 4 import ( 5 "fmt" 6 7 capnv1 "github.com/nutanix-cloud-native/cluster-api-provider-nutanix/api/v1beta1" 8 v1 "k8s.io/api/core/v1" 9 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 10 "k8s.io/utils/ptr" 11 capv1 "sigs.k8s.io/cluster-api/api/v1beta1" 12 13 machinev1 "github.com/openshift/api/machine/v1" 14 "github.com/openshift/installer/pkg/asset" 15 "github.com/openshift/installer/pkg/asset/manifests/capiutils" 16 "github.com/openshift/installer/pkg/types" 17 nutanixtypes "github.com/openshift/installer/pkg/types/nutanix" 18 ) 19 20 const ( 21 masterRole = "master" 22 ) 23 24 // GenerateMachines returns manifests and runtime objects to provision the control plane (including bootstrap, if applicable) nodes using CAPI. 25 func GenerateMachines(clusterID string, config *types.InstallConfig, pool *types.MachinePool, osImage string, role string) ([]*asset.RuntimeFile, error) { 26 machines, _, err := Machines(clusterID, config, pool, osImage, role, "") 27 if err != nil { 28 return nil, fmt.Errorf("unable to retrieve machines: %w", err) 29 } 30 31 categoryKey := nutanixtypes.CategoryKey(clusterID) 32 categoryIdentifiers := []capnv1.NutanixCategoryIdentifier{ 33 {Key: categoryKey, Value: nutanixtypes.CategoryValueOwned}, 34 } 35 ntxMachines := make([]*capnv1.NutanixMachine, 0, len(machines)) 36 result := make([]*asset.RuntimeFile, 0, 2*len(machines)) 37 38 for _, machine := range machines { 39 providerSpec, ok := machine.Spec.ProviderSpec.Value.Object.(*machinev1.NutanixMachineProviderConfig) 40 if !ok { 41 return nil, fmt.Errorf("unable to convert ProviderSpec to NutanixMachineProviderConfig") 42 } 43 44 // create the NutanixMachine object. 45 ntxMachine := generateNutanixMachine(machine.Name, providerSpec, categoryIdentifiers) 46 ntxMachines = append(ntxMachines, ntxMachine) 47 result = append(result, &asset.RuntimeFile{ 48 File: asset.File{Filename: fmt.Sprintf("10_inframachine_%s.yaml", ntxMachine.Name)}, 49 Object: ntxMachine, 50 }) 51 52 // create the capi Machine object. 53 capiMachine := &capv1.Machine{ 54 ObjectMeta: metav1.ObjectMeta{ 55 Namespace: capiutils.Namespace, 56 Name: ntxMachine.Name, 57 Labels: map[string]string{ 58 "cluster.x-k8s.io/control-plane": "", 59 }, 60 }, 61 Spec: capv1.MachineSpec{ 62 ClusterName: clusterID, 63 Bootstrap: capv1.Bootstrap{ 64 DataSecretName: ptr.To(fmt.Sprintf("%s-%s", clusterID, role)), 65 }, 66 InfrastructureRef: v1.ObjectReference{ 67 APIVersion: "infrastructure.cluster.x-k8s.io/v1beta1", 68 Kind: "NutanixMachine", 69 Name: ntxMachine.Name, 70 }, 71 }, 72 } 73 capiMachine.SetGroupVersionKind(capv1.GroupVersion.WithKind("Machine")) 74 75 result = append(result, &asset.RuntimeFile{ 76 File: asset.File{Filename: fmt.Sprintf("10_machine_%s.yaml", capiMachine.Name)}, 77 Object: capiMachine, 78 }) 79 } 80 81 // as part of provisioning control plane nodes, we need to create a bootstrap node as well. 82 if role == masterRole { 83 bootstrapSpec := ntxMachines[0].Spec.DeepCopy() 84 bootstrapSpec.VCPUsPerSocket = 4 85 bootstrapSpec.VCPUSockets = 1 86 bootstrapImgName := nutanixtypes.BootISOImageName(clusterID) 87 bootstrapSpec.BootstrapRef = &v1.ObjectReference{ 88 Kind: capnv1.NutanixMachineBootstrapRefKindImage, 89 Name: bootstrapImgName, 90 } 91 92 bootstrapNtxMachine := &capnv1.NutanixMachine{ 93 ObjectMeta: metav1.ObjectMeta{ 94 Namespace: capiutils.Namespace, 95 Name: capiutils.GenerateBoostrapMachineName(clusterID), 96 Labels: map[string]string{ 97 "cluster.x-k8s.io/control-plane": "", 98 "install.openshift.io/bootstrap": "", 99 }, 100 }, 101 Spec: *bootstrapSpec, 102 } 103 bootstrapNtxMachine.SetGroupVersionKind(capnv1.GroupVersion.WithKind("NutanixMachine")) 104 105 result = append(result, &asset.RuntimeFile{ 106 File: asset.File{Filename: fmt.Sprintf("10_inframachine_%s.yaml", bootstrapNtxMachine.Name)}, 107 Object: bootstrapNtxMachine, 108 }) 109 110 bootstrapCapiMachine := &capv1.Machine{ 111 ObjectMeta: metav1.ObjectMeta{ 112 Namespace: capiutils.Namespace, 113 Name: bootstrapNtxMachine.Name, 114 Labels: map[string]string{ 115 "cluster.x-k8s.io/control-plane": "", 116 }, 117 }, 118 Spec: capv1.MachineSpec{ 119 ClusterName: clusterID, 120 Bootstrap: capv1.Bootstrap{ 121 DataSecretName: ptr.To(fmt.Sprintf("%s-bootstrap", clusterID)), 122 }, 123 InfrastructureRef: v1.ObjectReference{ 124 APIVersion: "infrastructure.cluster.x-k8s.io/v1beta1", 125 Kind: "NutanixMachine", 126 Name: bootstrapNtxMachine.Name, 127 }, 128 }, 129 } 130 bootstrapCapiMachine.SetGroupVersionKind(capv1.GroupVersion.WithKind("Machine")) 131 132 result = append(result, &asset.RuntimeFile{ 133 File: asset.File{Filename: fmt.Sprintf("10_machine_%s.yaml", bootstrapCapiMachine.Name)}, 134 Object: bootstrapCapiMachine, 135 }) 136 } 137 138 return result, nil 139 } 140 141 func generateNutanixMachine(machineName string, providerSpec *machinev1.NutanixMachineProviderConfig, categoryIdentifiers []capnv1.NutanixCategoryIdentifier) *capnv1.NutanixMachine { 142 ntxMachine := &capnv1.NutanixMachine{ 143 ObjectMeta: metav1.ObjectMeta{ 144 Namespace: capiutils.Namespace, 145 Name: machineName, 146 Labels: map[string]string{ 147 "cluster.x-k8s.io/control-plane": "", 148 }, 149 }, 150 Spec: capnv1.NutanixMachineSpec{ 151 VCPUsPerSocket: providerSpec.VCPUsPerSocket, 152 VCPUSockets: providerSpec.VCPUSockets, 153 MemorySize: providerSpec.MemorySize, 154 SystemDiskSize: providerSpec.SystemDiskSize, 155 Image: capnv1.NutanixResourceIdentifier{ 156 Type: capnv1.NutanixIdentifierType(providerSpec.Image.Type), 157 Name: providerSpec.Image.Name, 158 UUID: providerSpec.Image.UUID, 159 }, 160 Cluster: capnv1.NutanixResourceIdentifier{ 161 Type: capnv1.NutanixIdentifierType(providerSpec.Cluster.Type), 162 Name: providerSpec.Cluster.Name, 163 UUID: providerSpec.Cluster.UUID, 164 }, 165 Subnets: []capnv1.NutanixResourceIdentifier{}, 166 AdditionalCategories: categoryIdentifiers, 167 }, 168 } 169 ntxMachine.SetGroupVersionKind(capnv1.GroupVersion.WithKind("NutanixMachine")) 170 171 for _, subnet := range providerSpec.Subnets { 172 ntxMachine.Spec.Subnets = append(ntxMachine.Spec.Subnets, capnv1.NutanixResourceIdentifier{ 173 Type: capnv1.NutanixIdentifierType(subnet.Type), 174 Name: subnet.Name, 175 UUID: subnet.UUID, 176 }) 177 } 178 179 for _, category := range providerSpec.Categories { 180 ntxMachine.Spec.AdditionalCategories = append(ntxMachine.Spec.AdditionalCategories, 181 capnv1.NutanixCategoryIdentifier{ 182 Key: category.Key, 183 Value: category.Value, 184 }) 185 } 186 187 switch providerSpec.BootType { 188 case machinev1.NutanixLegacyBoot: 189 ntxMachine.Spec.BootType = capnv1.NutanixBootTypeLegacy 190 case machinev1.NutanixUEFIBoot, machinev1.NutanixSecureBoot: 191 ntxMachine.Spec.BootType = capnv1.NutanixBootTypeUEFI 192 default: 193 // Use the default boot type 194 } 195 196 if providerSpec.Project.Type != "" { 197 ntxMachine.Spec.Project = &capnv1.NutanixResourceIdentifier{ 198 Type: capnv1.NutanixIdentifierType(providerSpec.Project.Type), 199 Name: providerSpec.Project.Name, 200 UUID: providerSpec.Project.UUID, 201 } 202 } 203 204 return ntxMachine 205 }