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

Commit f819811

Browse files
authored
refactor: combine PC host and port into a single url var (#36)
* 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
1 parent 0e91d4d commit f819811

File tree

12 files changed

+177
-48
lines changed

12 files changed

+177
-48
lines changed

api/openapi/patterns/anchored.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,7 @@ package patterns
66
func Anchored(pattern string) string {
77
return "^" + pattern + "$"
88
}
9+
10+
func HTTPSURL() string {
11+
return `^https://`
12+
}

api/v1alpha1/nutanix_clusterconfig_types.go

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ import (
88
"k8s.io/utils/ptr"
99
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
1010

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

1414
const (
15-
PrismCentralPort = 9440
15+
DefaultPrismCentralPort = 9440
1616
)
1717

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

4141
type NutanixPrismCentralEndpointSpec struct {
42-
// host is the DNS name or IP address of the Nutanix Prism Central
43-
Host string `json:"host"`
44-
45-
// port is the port number to access the Nutanix Prism Central
46-
Port int32 `json:"port"`
42+
// The URL of Nutanix Prism Central, can be DNS name or an IP address
43+
URL string `json:"url"`
4744

4845
// use insecure connection to Prism Central endpoint
4946
// +optional
@@ -65,17 +62,12 @@ func (NutanixPrismCentralEndpointSpec) VariableSchema() clusterv1.VariableSchema
6562
Description: "Nutanix Prism Central endpoint configuration",
6663
Type: "object",
6764
Properties: map[string]clusterv1.JSONSchemaProps{
68-
"host": {
69-
Description: "the DNS name or IP address of the Nutanix Prism Central",
65+
"url": {
66+
Description: "The URL of Nutanix Prism Central, can be DNS name or an IP address",
7067
Type: "string",
7168
MinLength: ptr.To[int64](1),
72-
},
73-
"port": {
74-
Description: "The port number to access the Nutanix Prism Central",
75-
Type: "integer",
76-
Default: variables.MustMarshal(PrismCentralPort),
77-
Minimum: ptr.To[int64](1),
78-
Maximum: ptr.To[int64](65535),
69+
Format: "uri",
70+
Pattern: patterns.HTTPSURL(),
7971
},
8072
"insecure": {
8173
Description: "Use insecure connection to Prism Central endpoint",
@@ -103,7 +95,7 @@ func (NutanixPrismCentralEndpointSpec) VariableSchema() clusterv1.VariableSchema
10395
Required: []string{"name"},
10496
},
10597
},
106-
Required: []string{"host", "port", "credentials"},
98+
Required: []string{"url", "credentials"},
10799
},
108100
}
109101
}

docs/content/customization/nutanix/prism-central-endpoint.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,8 @@ spec:
2222
prismCentralEndpoint:
2323
credentials:
2424
name: secret-name
25-
host: x.x.x.x
25+
url: https://x.x.x.x:9440
2626
insecure: false
27-
port: 9440
2827
```
2928
3029
Applying this configuration will result in the following value being set:

examples/capi-quick-start/nutanix-cluster-calico-crs.yaml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -365,9 +365,8 @@ spec:
365365
prismCentralEndpoint:
366366
credentials:
367367
name: ${CLUSTER_NAME}-pc-creds
368-
host: ${NUTANIX_ENDPOINT}
369368
insecure: ${NUTANIX_INSECURE}
370-
port: 9440
369+
url: https://${NUTANIX_ENDPOINT}:9440
371370
- name: workerConfig
372371
value:
373372
nutanix:

examples/capi-quick-start/nutanix-cluster-calico-helm-addon.yaml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -365,9 +365,8 @@ spec:
365365
prismCentralEndpoint:
366366
credentials:
367367
name: ${CLUSTER_NAME}-pc-creds
368-
host: ${NUTANIX_ENDPOINT}
369368
insecure: ${NUTANIX_INSECURE}
370-
port: 9440
369+
url: https://${NUTANIX_ENDPOINT}:9440
371370
- name: workerConfig
372371
value:
373372
nutanix:

examples/capi-quick-start/nutanix-cluster-cilium-crs.yaml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -365,9 +365,8 @@ spec:
365365
prismCentralEndpoint:
366366
credentials:
367367
name: ${CLUSTER_NAME}-pc-creds
368-
host: ${NUTANIX_ENDPOINT}
369368
insecure: ${NUTANIX_INSECURE}
370-
port: 9440
369+
url: https://${NUTANIX_ENDPOINT}:9440
371370
- name: workerConfig
372371
value:
373372
nutanix:

examples/capi-quick-start/nutanix-cluster-cilium-helm-addon.yaml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -365,9 +365,8 @@ spec:
365365
prismCentralEndpoint:
366366
credentials:
367367
name: ${CLUSTER_NAME}-pc-creds
368-
host: ${NUTANIX_ENDPOINT}
369368
insecure: ${NUTANIX_INSECURE}
370-
port: 9440
369+
url: https://${NUTANIX_ENDPOINT}:9440
371370
- name: workerConfig
372371
value:
373372
nutanix:

hack/examples/patches/nutanix/initialize-variables.yaml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,8 @@
1111
host: ${CONTROL_PLANE_ENDPOINT_IP}
1212
port: 6443
1313
prismCentralEndpoint:
14-
host: ${NUTANIX_ENDPOINT}
14+
url: https://${NUTANIX_ENDPOINT}:9440
1515
insecure: ${NUTANIX_INSECURE}
16-
port: 9440
1716
credentials:
1817
name: ${CLUSTER_NAME}-pc-creds
1918
- op: "add"

pkg/handlers/nutanix/mutation/controlplaneendpoint/variables_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package controlplaneendpoint
55

66
import (
7+
"fmt"
78
"testing"
89

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

20+
var testPrismCentralURL = fmt.Sprintf("https://prism-central.nutanix.com:%d", v1alpha1.DefaultPrismCentralPort)
21+
1922
func TestVariableValidation(t *testing.T) {
2023
capitest.ValidateDiscoverVariables(
2124
t,
@@ -33,8 +36,7 @@ func TestVariableValidation(t *testing.T) {
3336
},
3437
// PrismCentralEndpoint is a required field and must always be set
3538
PrismCentralEndpoint: v1alpha1.NutanixPrismCentralEndpointSpec{
36-
Host: "prism-central.nutanix.com",
37-
Port: v1alpha1.PrismCentralPort,
39+
URL: testPrismCentralURL,
3840
Credentials: corev1.LocalObjectReference{
3941
Name: "credentials",
4042
},
@@ -52,8 +54,7 @@ func TestVariableValidation(t *testing.T) {
5254
},
5355
// PrismCentralEndpoint is a required field and must always be set
5456
PrismCentralEndpoint: v1alpha1.NutanixPrismCentralEndpointSpec{
55-
Host: "prism-central.nutanix.com",
56-
Port: v1alpha1.PrismCentralPort,
57+
URL: testPrismCentralURL,
5758
Credentials: corev1.LocalObjectReference{
5859
Name: "credentials",
5960
},
@@ -72,8 +73,7 @@ func TestVariableValidation(t *testing.T) {
7273
},
7374
// PrismCentralEndpoint is a required field and must always be set
7475
PrismCentralEndpoint: v1alpha1.NutanixPrismCentralEndpointSpec{
75-
Host: "prism-central.nutanix.com",
76-
Port: v1alpha1.PrismCentralPort,
76+
URL: testPrismCentralURL,
7777
Credentials: corev1.LocalObjectReference{
7878
Name: "credentials",
7979
},

pkg/handlers/nutanix/mutation/prismcentralendpoint/inject.go

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import (
77
"context"
88
"encoding/base64"
99
"fmt"
10+
"net/url"
11+
"strconv"
1012

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

102+
var address string
103+
var port int32
104+
address, port, err = parsePrismCentralURL(prismCentralEndpointVar.URL)
105+
if err != nil {
106+
return err
107+
}
100108
prismCentral := &credentials.NutanixPrismEndpoint{
101-
Address: prismCentralEndpointVar.Host,
102-
Port: prismCentralEndpointVar.Port,
109+
Address: address,
110+
Port: port,
103111
Insecure: prismCentralEndpointVar.Insecure,
104112
CredentialRef: &credentials.NutanixCredentialReference{
105113
Kind: credentials.SecretKind,
@@ -130,3 +138,26 @@ func (h *nutanixPrismCentralEndpoint) Mutate(
130138
},
131139
)
132140
}
141+
142+
//nolint:gocritic // no need for named return values
143+
func parsePrismCentralURL(in string) (string, int32, error) {
144+
var prismCentralURL *url.URL
145+
prismCentralURL, err := url.Parse(in)
146+
if err != nil {
147+
return "", -1, fmt.Errorf("error parsing Prism Central URL: %w", err)
148+
}
149+
150+
hostname := prismCentralURL.Hostname()
151+
152+
// return early with the default port if no port is specified
153+
if prismCentralURL.Port() == "" {
154+
return hostname, v1alpha1.DefaultPrismCentralPort, nil
155+
}
156+
157+
port, err := strconv.ParseInt(prismCentralURL.Port(), 10, 32)
158+
if err != nil {
159+
return "", -1, fmt.Errorf("error converting port to int: %w", err)
160+
}
161+
162+
return hostname, int32(port), nil
163+
}

pkg/handlers/nutanix/mutation/prismcentralendpoint/inject_test.go

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,7 @@ var _ = Describe("Generate Nutanix Prism Central Endpoint patches", func() {
4444
capitest.VariableWithValue(
4545
clusterconfig.MetaVariableName,
4646
v1alpha1.NutanixPrismCentralEndpointSpec{
47-
Host: "prism-central.nutanix.com",
48-
Port: 9441,
47+
URL: "https://prism-central.nutanix.com:9441",
4948
Insecure: true,
5049
Credentials: corev1.LocalObjectReference{
5150
Name: "credentials",
@@ -73,14 +72,47 @@ var _ = Describe("Generate Nutanix Prism Central Endpoint patches", func() {
7372
},
7473
},
7574
},
75+
{
76+
Name: "all required fields set without port",
77+
Vars: []runtimehooksv1.Variable{
78+
capitest.VariableWithValue(
79+
clusterconfig.MetaVariableName,
80+
v1alpha1.NutanixPrismCentralEndpointSpec{
81+
URL: "https://prism-central.nutanix.com",
82+
Insecure: true,
83+
Credentials: corev1.LocalObjectReference{
84+
Name: "credentials",
85+
},
86+
},
87+
nutanixclusterconfig.NutanixVariableName,
88+
VariableName,
89+
),
90+
},
91+
RequestItem: request.NewNutanixClusterTemplateRequestItem(""),
92+
ExpectedPatchMatchers: []capitest.JSONPatchMatcher{
93+
{
94+
Operation: "replace",
95+
Path: "/spec/template/spec/prismCentral",
96+
ValueMatcher: gomega.SatisfyAll(
97+
gomega.HaveKeyWithValue(
98+
"address",
99+
gomega.BeEquivalentTo("prism-central.nutanix.com"),
100+
),
101+
gomega.HaveKeyWithValue("port", gomega.BeEquivalentTo(v1alpha1.DefaultPrismCentralPort)),
102+
gomega.HaveKeyWithValue("insecure", true),
103+
gomega.HaveKey("credentialRef"),
104+
gomega.Not(gomega.HaveKey("additionalTrustBundle")),
105+
),
106+
},
107+
},
108+
},
76109
{
77110
Name: "additional trust bundle is set",
78111
Vars: []runtimehooksv1.Variable{
79112
capitest.VariableWithValue(
80113
clusterconfig.MetaVariableName,
81114
v1alpha1.NutanixPrismCentralEndpointSpec{
82-
Host: "prism-central.nutanix.com",
83-
Port: 9441,
115+
URL: "https://prism-central.nutanix.com:9441",
84116
Insecure: true,
85117
Credentials: corev1.LocalObjectReference{
86118
Name: "credentials",

0 commit comments

Comments
 (0)