Skip to content
This repository has been archived by the owner on Apr 11, 2024. It is now read-only.

feat: Add support for CAPX #6

Merged
merged 18 commits into from
Apr 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions api/v1alpha1/clusterconfig_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ type ClusterConfigSpec struct {
AWS *AWSSpec `json:"aws,omitempty"`
// +optional
Docker *DockerSpec `json:"docker,omitempty"`
// +optional
Nutanix *NutanixSpec `json:"nutanix,omitempty"`

GenericClusterConfig `json:",inline"`

Expand Down Expand Up @@ -76,6 +78,16 @@ func (s ClusterConfigSpec) VariableSchema() clusterv1.VariableSchema { //nolint:
}.VariableSchema().OpenAPIV3Schema,
},
)
case s.Nutanix != nil:
maps.Copy(
clusterConfigProps.OpenAPIV3Schema.Properties,
map[string]clusterv1.JSONSchemaProps{
NutanixVariableName: NutanixSpec{}.VariableSchema().OpenAPIV3Schema,
"controlPlane": NodeConfigSpec{
Nutanix: &NutanixNodeSpec{},
}.VariableSchema().OpenAPIV3Schema,
},
)
}

return clusterConfigProps
Expand Down
37 changes: 37 additions & 0 deletions api/v1alpha1/common_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,17 @@

package v1alpha1

import (
"k8s.io/utils/ptr"
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"

"github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/api/variables"
)

const (
APIServerPort = 6443
)

// ObjectMeta is metadata that all persisted resources must have, which includes all objects
// users must create. This is a copy of customizable fields from metav1.ObjectMeta.
//
Expand All @@ -23,3 +34,29 @@ type ObjectMeta struct {
// +optional
Annotations map[string]string `json:"annotations,omitempty"`
}

type ControlPlaneEndpointSpec clusterv1.APIEndpoint

func (ControlPlaneEndpointSpec) VariableSchema() clusterv1.VariableSchema {
return clusterv1.VariableSchema{
OpenAPIV3Schema: clusterv1.JSONSchemaProps{
Description: "Kubernetes control-plane endpoint configuration",
Type: "object",
Properties: map[string]clusterv1.JSONSchemaProps{
"host": {
Description: "host ip/fqdn for control plane API Server",
Type: "string",
MinLength: ptr.To[int64](1),
},
"port": {
Description: "port for control plane API Server",
Type: "integer",
Default: variables.MustMarshal(APIServerPort),
Minimum: ptr.To[int64](1),
Maximum: ptr.To[int64](65535),
},
},
Required: []string{"host", "port"},
},
}
}
2 changes: 2 additions & 0 deletions api/v1alpha1/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,6 @@ const (
ClusterAutoscalerVariableName = "clusterAutoscaler"
// AWSVariableName is the AWS config patch variable name.
AWSVariableName = "aws"
// NutanixVariableName is the Nutanix config patch variable name.
NutanixVariableName = "nutanix"
)
9 changes: 9 additions & 0 deletions api/v1alpha1/node_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ type NodeConfigSpec struct {
AWS *AWSNodeSpec `json:"aws,omitempty"`
// +optional
Docker *DockerNodeSpec `json:"docker,omitempty"`
// +optional
Nutanix *NutanixNodeSpec `json:"nutanix,omitempty"`
}

func (s NodeConfigSpec) VariableSchema() clusterv1.VariableSchema {
Expand All @@ -49,6 +51,13 @@ func (s NodeConfigSpec) VariableSchema() clusterv1.VariableSchema {
"docker": DockerNodeSpec{}.VariableSchema().OpenAPIV3Schema,
},
)
case s.Nutanix != nil:
maps.Copy(
nodeConfigProps.OpenAPIV3Schema.Properties,
map[string]clusterv1.JSONSchemaProps{
"nutanix": NutanixNodeSpec{}.VariableSchema().OpenAPIV3Schema,
},
)
}

return nodeConfigProps
Expand Down
115 changes: 115 additions & 0 deletions api/v1alpha1/nutanix_clusterconfig_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
// Copyright 2024 D2iQ, Inc. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

package v1alpha1

import (
corev1 "k8s.io/api/core/v1"
"k8s.io/utils/ptr"
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"

"github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/api/variables"
)

const (
PrismCentralPort = 9440
)

// NutanixSpec defines the desired state of NutanixCluster.
type NutanixSpec struct {
// ControlPlaneEndpoint represents the endpoint used to communicate with the control plane.
// host can be either DNS name or ip address
ControlPlaneEndpoint clusterv1.APIEndpoint `json:"controlPlaneEndpoint"`

// Nutanix Prism Central endpoint configuration.
PrismCentralEndpoint NutanixPrismCentralEndpointSpec `json:"prismCentralEndpoint"`
}

func (NutanixSpec) VariableSchema() clusterv1.VariableSchema {
return clusterv1.VariableSchema{
OpenAPIV3Schema: clusterv1.JSONSchemaProps{
Description: "Nutanix cluster configuration",
Type: "object",
Properties: map[string]clusterv1.JSONSchemaProps{
"controlPlaneEndpoint": ControlPlaneEndpointSpec{}.VariableSchema().OpenAPIV3Schema,
"prismCentralEndpoint": NutanixPrismCentralEndpointSpec{}.VariableSchema().OpenAPIV3Schema,
},
},
}
}

type NutanixPrismCentralEndpointSpec struct {
// host is the DNS name or IP address of the Nutanix Prism Central
Host string `json:"host"`

// port is the port number to access the Nutanix Prism Central
Port int32 `json:"port"`

// use insecure connection to Prism Central endpoint
// +optional
Insecure bool `json:"insecure"`

// A reference to the ConfigMap containing a PEM encoded x509 cert for the RootCA that was used to create
// the certificate for a Prism Central that uses certificates that were issued by a non-publicly trusted RootCA.
// The trust bundle is added to the cert pool used to authenticate the TLS connection to the Prism Central.
// +optional
AdditionalTrustBundle *corev1.LocalObjectReference `json:"additionalTrustBundle,omitempty"`

// A reference to the Secret for credential information for the target Prism Central instance
Credentials corev1.LocalObjectReference `json:"credentials"`
}

func (NutanixPrismCentralEndpointSpec) VariableSchema() clusterv1.VariableSchema {
return clusterv1.VariableSchema{
OpenAPIV3Schema: clusterv1.JSONSchemaProps{
Description: "Nutanix Prism Central endpoint configuration",
Type: "object",
Properties: map[string]clusterv1.JSONSchemaProps{
"host": {
Description: "the DNS name or IP address of the Nutanix Prism Central",
Type: "string",
MinLength: ptr.To[int64](1),
},
"port": {
Description: "The port number to access the Nutanix Prism Central",
Type: "integer",
Default: variables.MustMarshal(PrismCentralPort),
Minimum: ptr.To[int64](1),
Maximum: ptr.To[int64](65535),
},
"insecure": {
Description: "Use insecure connection to Prism Central endpoint",
Type: "boolean",
},
"additionalTrustBundle": {
Description: "A reference to the ConfigMap containing a PEM encoded x509 cert for the RootCA " +
"that was used to create the certificate for a Prism Central that uses certificates " +
"that were issued by a non-publicly trusted RootCA." +
"The trust bundle is added to the cert pool used to authenticate the TLS connection " +
"to the Prism Central.",
Type: "object",
Properties: map[string]clusterv1.JSONSchemaProps{
"name": {
Description: "The name of the ConfigMap",
Type: "string",
},
},
Required: []string{"name"},
},
"credentials": {
Description: "A reference to the Secret for credential information" +
"for the target Prism Central instance",
Type: "object",
Properties: map[string]clusterv1.JSONSchemaProps{
"name": {
Description: "The name of the Secret",
Type: "string",
},
},
Required: []string{"name"},
},
},
Required: []string{"host", "port", "credentials"},
},
}
}
163 changes: 163 additions & 0 deletions api/v1alpha1/nutanix_node_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
// Copyright 2024 D2iQ, Inc. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

package v1alpha1

import (
"k8s.io/apimachinery/pkg/api/resource"
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"

capxv1 "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/api/external/github.com/nutanix-cloud-native/cluster-api-provider-nutanix/api/v1beta1"
"github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/api/variables"
)

type NutanixNodeSpec struct {
MachineDetails NutanixMachineDetails `json:"machineDetails"`
}

func (NutanixNodeSpec) VariableSchema() clusterv1.VariableSchema {
return clusterv1.VariableSchema{
OpenAPIV3Schema: clusterv1.JSONSchemaProps{
Description: "Nutanix Node configuration",
Type: "object",
Properties: map[string]clusterv1.JSONSchemaProps{
"machineDetails": NutanixMachineDetails{}.VariableSchema().OpenAPIV3Schema,
},
Required: []string{"machineDetails"},
},
}
}

type NutanixMachineDetails struct {
// vcpusPerSocket is the number of vCPUs per socket of the VM
VCPUsPerSocket int32 `json:"vcpusPerSocket"`

// vcpuSockets is the number of vCPU sockets of the VM
VCPUSockets int32 `json:"vcpuSockets"`

// memorySize is the memory size (in Quantity format) of the VM
MemorySize resource.Quantity `json:"memorySize"`

// image is to identify the rhcos image uploaded to the Prism Central (PC)
// The image identifier (uuid or name) can be obtained from the Prism Central console
// or using the prism_central API.
Image NutanixResourceIdentifier `json:"image"`

// cluster is to identify the cluster (the Prism Element under management
// of the Prism Central), in which the Machine's VM will be created.
// The cluster identifier (uuid or name) can be obtained from the Prism Central console
// or using the prism_central API.
Cluster NutanixResourceIdentifier `json:"cluster"`

// subnet is to identify the cluster's network subnet to use for the Machine's VM
// The cluster identifier (uuid or name) can be obtained from the Prism Central console
// or using the prism_central API.
Subnets NutanixResourceIdentifiers `json:"subnets"`

// Defines the boot type of the virtual machine. Only supports UEFI and Legacy
BootType NutanixBootType `json:"bootType,omitempty"`

// systemDiskSize is size (in Quantity format) of the system disk of the VM
// The minimum systemDiskSize is 20Gi bytes
SystemDiskSize resource.Quantity `json:"systemDiskSize"`
}

func (NutanixMachineDetails) VariableSchema() clusterv1.VariableSchema {
return clusterv1.VariableSchema{
OpenAPIV3Schema: clusterv1.JSONSchemaProps{
Description: "Nutanix Machine configuration",
Type: "object",
Properties: map[string]clusterv1.JSONSchemaProps{
"vcpusPerSocket": {
Description: "vcpusPerSocket is the number of vCPUs per socket of the VM",
Type: "integer",
},
"vcpuSockets": {
Description: "vcpuSockets is the number of vCPU sockets of the VM",
Type: "integer",
},
"memorySize": {
Description: "memorySize is the memory size (in Quantity format) of the VM eg. 4Gi",
Type: "string",
},
"image": NutanixResourceIdentifier{}.VariableSchema().OpenAPIV3Schema,
"cluster": NutanixResourceIdentifier{}.VariableSchema().OpenAPIV3Schema,
"subnets": NutanixResourceIdentifiers{}.VariableSchema().OpenAPIV3Schema,
"bootType": NutanixBootType(capxv1.NutanixBootTypeLegacy).VariableSchema().OpenAPIV3Schema,
"systemDiskSize": {
Description: "systemDiskSize is size (in Quantity format) of the system disk of the VM eg. 20Gi",
Type: "string",
},
},
Required: []string{"vcpusPerSocket", "vcpuSockets", "memorySize", "image", "cluster", "subnets", "systemDiskSize"},
},
}
}

// NutanixIdentifierType is an enumeration of different resource identifier types.
type NutanixIdentifierType capxv1.NutanixIdentifierType

func (NutanixIdentifierType) VariableSchema() clusterv1.VariableSchema {
return clusterv1.VariableSchema{
OpenAPIV3Schema: clusterv1.JSONSchemaProps{
Type: "string",
Description: "NutanixIdentifierType is an enumeration of different resource identifier types",
Enum: variables.MustMarshalValuesToEnumJSON(
capxv1.NutanixIdentifierUUID,
capxv1.NutanixIdentifierName,
),
},
}
}

// NutanixBootType is an enumeration of different boot types.
type NutanixBootType capxv1.NutanixBootType

func (NutanixBootType) VariableSchema() clusterv1.VariableSchema {
return clusterv1.VariableSchema{
OpenAPIV3Schema: clusterv1.JSONSchemaProps{
Type: "string",
Description: "NutanixBootType is an enumeration of different boot types.",
Enum: variables.MustMarshalValuesToEnumJSON(
capxv1.NutanixBootTypeLegacy,
capxv1.NutanixBootTypeUEFI,
),
},
}
}

type NutanixResourceIdentifier capxv1.NutanixResourceIdentifier

func (NutanixResourceIdentifier) VariableSchema() clusterv1.VariableSchema {
return clusterv1.VariableSchema{
OpenAPIV3Schema: clusterv1.JSONSchemaProps{
Description: "Nutanix Resource Identifier",
Type: "object",
Properties: map[string]clusterv1.JSONSchemaProps{
"type": NutanixIdentifierType(capxv1.NutanixIdentifierName).VariableSchema().OpenAPIV3Schema,
"uuid": {
Type: "string",
Description: "uuid is the UUID of the resource in the PC.",
},
"name": {
Type: "string",
Description: "name is the resource name in the PC.",
},
},
},
}
}

type NutanixResourceIdentifiers []NutanixResourceIdentifier

func (NutanixResourceIdentifiers) VariableSchema() clusterv1.VariableSchema {
resourceSchema := NutanixResourceIdentifier{}.VariableSchema().OpenAPIV3Schema

return clusterv1.VariableSchema{
OpenAPIV3Schema: clusterv1.JSONSchemaProps{
Description: "Nutanix resource identifier",
Type: "array",
Items: &resourceSchema,
},
}
}
Loading
Loading