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

Commit

Permalink
refactor: combine PC host and port into a single url var (#36)
Browse files Browse the repository at this point in the history
* refactor: combine PC host and port into a single url var

This makes it simpler for clients to provide a single input field
and not have to do any parsing to split the hostname and port.
It also allows us to use API validation for bad input.

* fixup! refactor: combine PC host and port into a single url var

* fixup! refactor: combine PC host and port into a single url var

* fixup! refactor: combine PC host and port into a single url var
  • Loading branch information
dkoshkin authored Apr 9, 2024
1 parent 0e91d4d commit f819811
Show file tree
Hide file tree
Showing 12 changed files with 177 additions and 48 deletions.
4 changes: 4 additions & 0 deletions api/openapi/patterns/anchored.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,7 @@ package patterns
func Anchored(pattern string) string {
return "^" + pattern + "$"
}

func HTTPSURL() string {
return `^https://`
}
26 changes: 9 additions & 17 deletions api/v1alpha1/nutanix_clusterconfig_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ import (
"k8s.io/utils/ptr"
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"

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

const (
PrismCentralPort = 9440
DefaultPrismCentralPort = 9440
)

// NutanixSpec defines the desired state of NutanixCluster.
Expand All @@ -39,11 +39,8 @@ func (NutanixSpec) VariableSchema() clusterv1.VariableSchema {
}

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"`
// The URL of Nutanix Prism Central, can be DNS name or an IP address
URL string `json:"url"`

// use insecure connection to Prism Central endpoint
// +optional
Expand All @@ -65,17 +62,12 @@ func (NutanixPrismCentralEndpointSpec) VariableSchema() clusterv1.VariableSchema
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",
"url": {
Description: "The URL of Nutanix Prism Central, can be DNS name or an IP address",
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),
Format: "uri",
Pattern: patterns.HTTPSURL(),
},
"insecure": {
Description: "Use insecure connection to Prism Central endpoint",
Expand Down Expand Up @@ -103,7 +95,7 @@ func (NutanixPrismCentralEndpointSpec) VariableSchema() clusterv1.VariableSchema
Required: []string{"name"},
},
},
Required: []string{"host", "port", "credentials"},
Required: []string{"url", "credentials"},
},
}
}
3 changes: 1 addition & 2 deletions docs/content/customization/nutanix/prism-central-endpoint.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,8 @@ spec:
prismCentralEndpoint:
credentials:
name: secret-name
host: x.x.x.x
url: https://x.x.x.x:9440
insecure: false
port: 9440
```
Applying this configuration will result in the following value being set:
Expand Down
3 changes: 1 addition & 2 deletions examples/capi-quick-start/nutanix-cluster-calico-crs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -365,9 +365,8 @@ spec:
prismCentralEndpoint:
credentials:
name: ${CLUSTER_NAME}-pc-creds
host: ${NUTANIX_ENDPOINT}
insecure: ${NUTANIX_INSECURE}
port: 9440
url: https://${NUTANIX_ENDPOINT}:9440
- name: workerConfig
value:
nutanix:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -365,9 +365,8 @@ spec:
prismCentralEndpoint:
credentials:
name: ${CLUSTER_NAME}-pc-creds
host: ${NUTANIX_ENDPOINT}
insecure: ${NUTANIX_INSECURE}
port: 9440
url: https://${NUTANIX_ENDPOINT}:9440
- name: workerConfig
value:
nutanix:
Expand Down
3 changes: 1 addition & 2 deletions examples/capi-quick-start/nutanix-cluster-cilium-crs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -365,9 +365,8 @@ spec:
prismCentralEndpoint:
credentials:
name: ${CLUSTER_NAME}-pc-creds
host: ${NUTANIX_ENDPOINT}
insecure: ${NUTANIX_INSECURE}
port: 9440
url: https://${NUTANIX_ENDPOINT}:9440
- name: workerConfig
value:
nutanix:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -365,9 +365,8 @@ spec:
prismCentralEndpoint:
credentials:
name: ${CLUSTER_NAME}-pc-creds
host: ${NUTANIX_ENDPOINT}
insecure: ${NUTANIX_INSECURE}
port: 9440
url: https://${NUTANIX_ENDPOINT}:9440
- name: workerConfig
value:
nutanix:
Expand Down
3 changes: 1 addition & 2 deletions hack/examples/patches/nutanix/initialize-variables.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@
host: ${CONTROL_PLANE_ENDPOINT_IP}
port: 6443
prismCentralEndpoint:
host: ${NUTANIX_ENDPOINT}
url: https://${NUTANIX_ENDPOINT}:9440
insecure: ${NUTANIX_INSECURE}
port: 9440
credentials:
name: ${CLUSTER_NAME}-pc-creds
- op: "add"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package controlplaneendpoint

import (
"fmt"
"testing"

corev1 "k8s.io/api/core/v1"
Expand All @@ -16,6 +17,8 @@ import (
nutanixclusterconfig "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/nutanix/clusterconfig"
)

var testPrismCentralURL = fmt.Sprintf("https://prism-central.nutanix.com:%d", v1alpha1.DefaultPrismCentralPort)

func TestVariableValidation(t *testing.T) {
capitest.ValidateDiscoverVariables(
t,
Expand All @@ -33,8 +36,7 @@ func TestVariableValidation(t *testing.T) {
},
// PrismCentralEndpoint is a required field and must always be set
PrismCentralEndpoint: v1alpha1.NutanixPrismCentralEndpointSpec{
Host: "prism-central.nutanix.com",
Port: v1alpha1.PrismCentralPort,
URL: testPrismCentralURL,
Credentials: corev1.LocalObjectReference{
Name: "credentials",
},
Expand All @@ -52,8 +54,7 @@ func TestVariableValidation(t *testing.T) {
},
// PrismCentralEndpoint is a required field and must always be set
PrismCentralEndpoint: v1alpha1.NutanixPrismCentralEndpointSpec{
Host: "prism-central.nutanix.com",
Port: v1alpha1.PrismCentralPort,
URL: testPrismCentralURL,
Credentials: corev1.LocalObjectReference{
Name: "credentials",
},
Expand All @@ -72,8 +73,7 @@ func TestVariableValidation(t *testing.T) {
},
// PrismCentralEndpoint is a required field and must always be set
PrismCentralEndpoint: v1alpha1.NutanixPrismCentralEndpointSpec{
Host: "prism-central.nutanix.com",
Port: v1alpha1.PrismCentralPort,
URL: testPrismCentralURL,
Credentials: corev1.LocalObjectReference{
Name: "credentials",
},
Expand Down
35 changes: 33 additions & 2 deletions pkg/handlers/nutanix/mutation/prismcentralendpoint/inject.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
"context"
"encoding/base64"
"fmt"
"net/url"
"strconv"

"github.com/nutanix-cloud-native/prism-go-client/environment/credentials"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
Expand Down Expand Up @@ -97,9 +99,15 @@ func (h *nutanixPrismCentralEndpoint) Mutate(
"patchedObjectName", client.ObjectKeyFromObject(obj),
).Info("setting prismCentralEndpoint in NutanixCluster spec")

var address string
var port int32
address, port, err = parsePrismCentralURL(prismCentralEndpointVar.URL)
if err != nil {
return err
}
prismCentral := &credentials.NutanixPrismEndpoint{
Address: prismCentralEndpointVar.Host,
Port: prismCentralEndpointVar.Port,
Address: address,
Port: port,
Insecure: prismCentralEndpointVar.Insecure,
CredentialRef: &credentials.NutanixCredentialReference{
Kind: credentials.SecretKind,
Expand Down Expand Up @@ -130,3 +138,26 @@ func (h *nutanixPrismCentralEndpoint) Mutate(
},
)
}

//nolint:gocritic // no need for named return values
func parsePrismCentralURL(in string) (string, int32, error) {
var prismCentralURL *url.URL
prismCentralURL, err := url.Parse(in)
if err != nil {
return "", -1, fmt.Errorf("error parsing Prism Central URL: %w", err)
}

hostname := prismCentralURL.Hostname()

// return early with the default port if no port is specified
if prismCentralURL.Port() == "" {
return hostname, v1alpha1.DefaultPrismCentralPort, nil
}

port, err := strconv.ParseInt(prismCentralURL.Port(), 10, 32)
if err != nil {
return "", -1, fmt.Errorf("error converting port to int: %w", err)
}

return hostname, int32(port), nil
}
40 changes: 36 additions & 4 deletions pkg/handlers/nutanix/mutation/prismcentralendpoint/inject_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@ var _ = Describe("Generate Nutanix Prism Central Endpoint patches", func() {
capitest.VariableWithValue(
clusterconfig.MetaVariableName,
v1alpha1.NutanixPrismCentralEndpointSpec{
Host: "prism-central.nutanix.com",
Port: 9441,
URL: "https://prism-central.nutanix.com:9441",
Insecure: true,
Credentials: corev1.LocalObjectReference{
Name: "credentials",
Expand Down Expand Up @@ -73,14 +72,47 @@ var _ = Describe("Generate Nutanix Prism Central Endpoint patches", func() {
},
},
},
{
Name: "all required fields set without port",
Vars: []runtimehooksv1.Variable{
capitest.VariableWithValue(
clusterconfig.MetaVariableName,
v1alpha1.NutanixPrismCentralEndpointSpec{
URL: "https://prism-central.nutanix.com",
Insecure: true,
Credentials: corev1.LocalObjectReference{
Name: "credentials",
},
},
nutanixclusterconfig.NutanixVariableName,
VariableName,
),
},
RequestItem: request.NewNutanixClusterTemplateRequestItem(""),
ExpectedPatchMatchers: []capitest.JSONPatchMatcher{
{
Operation: "replace",
Path: "/spec/template/spec/prismCentral",
ValueMatcher: gomega.SatisfyAll(
gomega.HaveKeyWithValue(
"address",
gomega.BeEquivalentTo("prism-central.nutanix.com"),
),
gomega.HaveKeyWithValue("port", gomega.BeEquivalentTo(v1alpha1.DefaultPrismCentralPort)),
gomega.HaveKeyWithValue("insecure", true),
gomega.HaveKey("credentialRef"),
gomega.Not(gomega.HaveKey("additionalTrustBundle")),
),
},
},
},
{
Name: "additional trust bundle is set",
Vars: []runtimehooksv1.Variable{
capitest.VariableWithValue(
clusterconfig.MetaVariableName,
v1alpha1.NutanixPrismCentralEndpointSpec{
Host: "prism-central.nutanix.com",
Port: 9441,
URL: "https://prism-central.nutanix.com:9441",
Insecure: true,
Credentials: corev1.LocalObjectReference{
Name: "credentials",
Expand Down
Loading

0 comments on commit f819811

Please sign in to comment.