diff --git a/.golangci.yml b/.golangci.yml index f19564f8f..423a173e1 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -73,6 +73,8 @@ linters-settings: pkg: github.com/vmware-tanzu/vm-operator/external/byok/api/v1alpha1 - alias: capv1 pkg: github.com/vmware-tanzu/vm-operator/external/capabilities/api/v1alpha1 + - alias: appv1a1 + pkg: github.com/vmware-tanzu/vm-operator/external/appplatform/api/v1alpha1 - alias: pkgcfg pkg: github.com/vmware-tanzu/vm-operator/pkg/config diff --git a/Makefile b/Makefile index 8fc009461..b821a7b7f 100644 --- a/Makefile +++ b/Makefile @@ -350,6 +350,9 @@ generate-go: ## Generate golang sources $(CONTROLLER_GEN) \ paths=github.com/vmware-tanzu/vm-operator/external/capabilities/... \ object:headerFile=./hack/boilerplate/boilerplate.generatego.txt + $(CONTROLLER_GEN) \ + paths=github.com/vmware-tanzu/vm-operator/external/appplatform/... \ + object:headerFile=./hack/boilerplate/boilerplate.generatego.txt $(MAKE) -C ./pkg/util/cloudinit/schema $@ .PHONY: generate-manifests @@ -406,6 +409,11 @@ generate-external-manifests: ## Generate manifests for the external types for te crd:crdVersions=v1 \ output:crd:dir=$(EXTERNAL_CRD_ROOT) \ output:none + $(CONTROLLER_GEN) \ + paths=github.com/vmware-tanzu/vm-operator/external/appplatform/... \ + crd:crdVersions=v1 \ + output:crd:dir=$(EXTERNAL_CRD_ROOT) \ + output:none .PHONY: generate-go-conversions generate-go-conversions: ## Generate conversions go code diff --git a/config/crd/external-crds/appplatform.vmware.com_supervisorproperties.yaml b/config/crd/external-crds/appplatform.vmware.com_supervisorproperties.yaml new file mode 100644 index 000000000..065e605da --- /dev/null +++ b/config/crd/external-crds/appplatform.vmware.com_supervisorproperties.yaml @@ -0,0 +1,127 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.1 + name: supervisorproperties.appplatform.vmware.com +spec: + group: appplatform.vmware.com + names: + kind: SupervisorProperties + listKind: SupervisorPropertiesList + plural: supervisorproperties + singular: supervisorproperty + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: SupervisorProperties is the Schema for the SupervisorProperties + API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: SupervisorPropertiesSpec defines the values of the properties + requested by a Supervisor Service Package. + properties: + apiServerDNSNames: + description: APIServerDNSNames indicates the API server DNS Names + associated with the supervisor. + items: + type: string + type: array + capabilities: + description: Capabilities defines the capabilities the Supervisor + has. The common case of the capability is the feature supported + of the vCenter. + items: + description: Capability defines the feature supported by the Supervisor. + properties: + name: + description: The name of the capability. + type: string + value: + default: false + description: The value indicates if the capability is supported. + type: boolean + required: + - name + - value + type: object + type: array + cloudVC: + description: CloudVCenter indicates if the vCenter is deployed on + cloud. + type: boolean + controlPlaneCount: + description: ControlPlaneCount indicates the number of control planes + enabled on the Supervisor. + type: integer + cpVMSize: + description: ControlPlaneVMSize indicates the capacity of the Supervisor + Control Plane. It's derived from Supervisor's tshirt size. + enum: + - TINY + - SMALL + - MEDIUM + - LARGE + type: string + namespacesCLIPluginVersion: + description: NamespacesCLIPluginVersion indicates the Supervisor recommended + namespaces CLIPlugin CR version. + type: string + networkProvider: + description: NetworkProvider indicates the Network Provider used on + Supervisor. (e.g. NSX, nsx-vpc, or vsphere-network) + type: string + podVMSupported: + description: PodVMSupported indicates if the Supervisor supports PodVMs. + type: boolean + ssoDomain: + description: SSODomain indicates the name of the default SSO domain + configured in vCenter. + type: string + stretchedSupervisor: + description: StretchedSupervisor indicates if the Supervisor is enabled + on a set of vSphere Zones. + type: boolean + tmcNamespace: + description: TMCNamespace indicates the namespace used for TMC to + be deployed. + type: string + vcPNID: + description: VCenterPNID indicates the Primary Network Identifier + of vCenter. + type: string + vcPort: + description: VCenterPort indicates the port of vCenter. + type: string + vcPublicKeys: + description: VCenterPublicKeys indicates the base64 encoded vCenter + OIDC issuer, client audience and the public keys in JWKS format. + type: string + virtualIP: + description: VirtualIP indicates the IP address of the Kubernetes + LoadBalancer type service fronting the apiservers. + type: string + type: object + type: object + served: true + storage: true diff --git a/config/rbac/appplatform_role.yaml b/config/rbac/appplatform_role.yaml new file mode 100644 index 000000000..7761569d6 --- /dev/null +++ b/config/rbac/appplatform_role.yaml @@ -0,0 +1,8 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: supervisor-properties-reader +rules: +- apiGroups: ["appplatform.vmware.com"] + resources: ["supervisorproperties"] + verbs: ["get", "list"] diff --git a/config/rbac/appplatform_role_binding.yaml b/config/rbac/appplatform_role_binding.yaml new file mode 100644 index 000000000..13350fb69 --- /dev/null +++ b/config/rbac/appplatform_role_binding.yaml @@ -0,0 +1,11 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: supervisor-properties-reader-binding +roleRef: + name: supervisor-properties-reader + kind: ClusterRole +subjects: +- kind: ServiceAccount + name: default + namespace: vmware-system-vmop diff --git a/controllers/virtualmachinewebconsolerequest/v1alpha1/webconsolerequest_controller.go b/controllers/virtualmachinewebconsolerequest/v1alpha1/webconsolerequest_controller.go index eb1c692b7..d14a50a88 100644 --- a/controllers/virtualmachinewebconsolerequest/v1alpha1/webconsolerequest_controller.go +++ b/controllers/virtualmachinewebconsolerequest/v1alpha1/webconsolerequest_controller.go @@ -1,4 +1,4 @@ -// Copyright (c) 2022-2023 VMware, Inc. All Rights Reserved. +// Copyright (c) 2022-2024 VMware, Inc. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 package v1alpha1 @@ -12,7 +12,6 @@ import ( "time" "github.com/go-logr/logr" - corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" @@ -26,14 +25,12 @@ import ( pkgctx "github.com/vmware-tanzu/vm-operator/pkg/context" "github.com/vmware-tanzu/vm-operator/pkg/providers" "github.com/vmware-tanzu/vm-operator/pkg/record" + "github.com/vmware-tanzu/vm-operator/pkg/util" ) const ( DefaultExpiryTime = time.Second * 120 UUIDLabelKey = "vmoperator.vmware.com/webconsolerequest-uuid" - - ProxyAddrServiceName = "kube-apiserver-lb-svc" - ProxyAddrServiceNamespace = "kube-system" ) // AddToManager adds this package's controller to the provided manager. @@ -187,18 +184,11 @@ func (r *Reconciler) ReconcileNormal(ctx *pkgctx.WebConsoleRequestContext) error ctx.WebConsoleRequest.Status.Response = ticket ctx.WebConsoleRequest.Status.ExpiryTime = metav1.NewTime(metav1.Now().Add(DefaultExpiryTime)) - // Retrieve the proxy address from the load balancer service ingress IP. - proxySvc := &corev1.Service{} - proxySvcObjectKey := client.ObjectKey{Name: ProxyAddrServiceName, Namespace: ProxyAddrServiceNamespace} - err = r.Get(ctx, proxySvcObjectKey, proxySvc) + proxyAddr, err := util.ProxyAddress(ctx, r) if err != nil { - return fmt.Errorf("failed to get proxy address service %s: %w", proxySvcObjectKey, err) - } - if len(proxySvc.Status.LoadBalancer.Ingress) == 0 { - return fmt.Errorf("no ingress found for proxy address service %s", proxySvcObjectKey) + return err } - - ctx.WebConsoleRequest.Status.ProxyAddr = proxySvc.Status.LoadBalancer.Ingress[0].IP + ctx.WebConsoleRequest.Status.ProxyAddr = proxyAddr // Add UUID as a Label to the current WebConsoleRequest resource after acquiring the ticket. // This will be used when validating the connection request from users to the web console URL. diff --git a/controllers/virtualmachinewebconsolerequest/v1alpha1/webconsolerequest_intg_test.go b/controllers/virtualmachinewebconsolerequest/v1alpha1/webconsolerequest_intg_test.go index 2e00d5bae..a48c5335d 100644 --- a/controllers/virtualmachinewebconsolerequest/v1alpha1/webconsolerequest_intg_test.go +++ b/controllers/virtualmachinewebconsolerequest/v1alpha1/webconsolerequest_intg_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2022 VMware, Inc. All Rights Reserved. +// Copyright (c) 2022-2024 VMware, Inc. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 package v1alpha1_test @@ -19,6 +19,7 @@ import ( vmopv1 "github.com/vmware-tanzu/vm-operator/api/v1alpha3" webconsolerequest "github.com/vmware-tanzu/vm-operator/controllers/virtualmachinewebconsolerequest/v1alpha1" "github.com/vmware-tanzu/vm-operator/pkg/constants/testlabels" + "github.com/vmware-tanzu/vm-operator/pkg/util" "github.com/vmware-tanzu/vm-operator/test/builder" ) @@ -82,8 +83,8 @@ func intgTestsReconcile() { proxySvc = &corev1.Service{ ObjectMeta: metav1.ObjectMeta{ - Name: webconsolerequest.ProxyAddrServiceName, - Namespace: webconsolerequest.ProxyAddrServiceNamespace, + Name: util.ProxyAddrServiceName, + Namespace: util.ProxyAddrServiceNamespace, }, Spec: corev1.ServiceSpec{ Type: corev1.ServiceTypeLoadBalancer, diff --git a/controllers/virtualmachinewebconsolerequest/v1alpha1/webconsolerequest_unit_test.go b/controllers/virtualmachinewebconsolerequest/v1alpha1/webconsolerequest_unit_test.go index 31509ba44..026adc9e4 100644 --- a/controllers/virtualmachinewebconsolerequest/v1alpha1/webconsolerequest_unit_test.go +++ b/controllers/virtualmachinewebconsolerequest/v1alpha1/webconsolerequest_unit_test.go @@ -17,9 +17,12 @@ import ( vmopv1a1 "github.com/vmware-tanzu/vm-operator/api/v1alpha1" vmopv1 "github.com/vmware-tanzu/vm-operator/api/v1alpha3" webconsolerequest "github.com/vmware-tanzu/vm-operator/controllers/virtualmachinewebconsolerequest/v1alpha1" + appv1a1 "github.com/vmware-tanzu/vm-operator/external/appplatform/api/v1alpha1" + pkgcfg "github.com/vmware-tanzu/vm-operator/pkg/config" "github.com/vmware-tanzu/vm-operator/pkg/constants/testlabels" pkgctx "github.com/vmware-tanzu/vm-operator/pkg/context" providerfake "github.com/vmware-tanzu/vm-operator/pkg/providers/fake" + "github.com/vmware-tanzu/vm-operator/pkg/util" "github.com/vmware-tanzu/vm-operator/test/builder" ) @@ -42,11 +45,12 @@ func unitTestsReconcile() { ctx *builder.UnitTestContextForController fakeVMProvider *providerfake.VMProvider - reconciler *webconsolerequest.Reconciler - wcrCtx *pkgctx.WebConsoleRequestContext - wcr *vmopv1a1.WebConsoleRequest - vm *vmopv1a1.VirtualMachine - proxySvc *corev1.Service + reconciler *webconsolerequest.Reconciler + wcrCtx *pkgctx.WebConsoleRequestContext + wcr *vmopv1a1.WebConsoleRequest + vm *vmopv1a1.VirtualMachine + proxySvc *corev1.Service + proxySvcDNS *appv1a1.SupervisorProperties ) BeforeEach(func() { @@ -68,8 +72,8 @@ func unitTestsReconcile() { proxySvc = &corev1.Service{ ObjectMeta: metav1.ObjectMeta{ - Name: webconsolerequest.ProxyAddrServiceName, - Namespace: webconsolerequest.ProxyAddrServiceNamespace, + Name: util.ProxyAddrServiceName, + Namespace: util.ProxyAddrServiceNamespace, }, Status: corev1.ServiceStatus{ LoadBalancer: corev1.LoadBalancerStatus{ @@ -141,5 +145,36 @@ func unitTestsReconcile() { // Checking the label key only because UID will not be set to a resource during unit test. Expect(wcrCtx.WebConsoleRequest.Labels).To(HaveKey(webconsolerequest.UUIDLabelKey)) }) + + When("SimplifiedEnablement is enabled", func() { + JustBeforeEach(func() { + pkgcfg.UpdateContext(ctx, + func(config *pkgcfg.Config) { + config.Features.SimplifiedEnablement = true + }, + ) + }) + + DescribeTable("DNS Names", + func(apiServerDNSName []string, expectedProxy string) { + proxySvcDNS = &appv1a1.SupervisorProperties{ + ObjectMeta: metav1.ObjectMeta{ + Name: "supervisor-env-props", + Namespace: "vmware-system-supervisor-services", + }, + Spec: appv1a1.SupervisorPropertiesSpec{ + APIServerDNSNames: apiServerDNSName, + }, + } + Expect(ctx.Client.Create(ctx, proxySvcDNS)).To(Succeed()) + + Expect(reconciler.ReconcileNormal(wcrCtx)).To(Succeed()) + Expect(wcrCtx.WebConsoleRequest.Status.ProxyAddr).To(Equal(expectedProxy)) + }, + Entry("API Server DNS Name is set", []string{"domain-1.test"}, "domain-1.test"), + Entry("API Server DNS Name is not set", []string{}, "dummy-proxy-ip"), + ) + }) }) + } diff --git a/controllers/virtualmachinewebconsolerequest/v1alpha2/webconsolerequest_controller.go b/controllers/virtualmachinewebconsolerequest/v1alpha2/webconsolerequest_controller.go index e880ab73c..390056b7a 100644 --- a/controllers/virtualmachinewebconsolerequest/v1alpha2/webconsolerequest_controller.go +++ b/controllers/virtualmachinewebconsolerequest/v1alpha2/webconsolerequest_controller.go @@ -1,4 +1,4 @@ -// Copyright (c) 2022-2023 VMware, Inc. All Rights Reserved. +// Copyright (c) 2022-2024 VMware, Inc. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 package v1alpha2 @@ -12,7 +12,6 @@ import ( "time" "github.com/go-logr/logr" - corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" @@ -25,14 +24,12 @@ import ( "github.com/vmware-tanzu/vm-operator/pkg/patch" "github.com/vmware-tanzu/vm-operator/pkg/providers" "github.com/vmware-tanzu/vm-operator/pkg/record" + "github.com/vmware-tanzu/vm-operator/pkg/util" ) const ( DefaultExpiryTime = time.Second * 120 UUIDLabelKey = "vmoperator.vmware.com/webconsolerequest-uuid" - - ProxyAddrServiceName = "kube-apiserver-lb-svc" - ProxyAddrServiceNamespace = "kube-system" ) // AddToManager adds this package's controller to the provided manager. @@ -179,18 +176,11 @@ func (r *Reconciler) ReconcileNormal(ctx *pkgctx.WebConsoleRequestContextV1) err ctx.WebConsoleRequest.Status.Response = ticket ctx.WebConsoleRequest.Status.ExpiryTime = metav1.NewTime(metav1.Now().Add(DefaultExpiryTime)) - // Retrieve the proxy address from the load balancer service ingress IP. - proxySvc := &corev1.Service{} - proxySvcObjectKey := client.ObjectKey{Name: ProxyAddrServiceName, Namespace: ProxyAddrServiceNamespace} - err = r.Get(ctx, proxySvcObjectKey, proxySvc) + proxyAddr, err := util.ProxyAddress(ctx, r) if err != nil { - return fmt.Errorf("failed to get proxy address service %s: %w", proxySvcObjectKey, err) - } - if len(proxySvc.Status.LoadBalancer.Ingress) == 0 { - return fmt.Errorf("no ingress found for proxy address service %s", proxySvcObjectKey) + return err } - - ctx.WebConsoleRequest.Status.ProxyAddr = proxySvc.Status.LoadBalancer.Ingress[0].IP + ctx.WebConsoleRequest.Status.ProxyAddr = proxyAddr // Add UUID as a Label to the current WebConsoleRequest resource after acquiring the ticket. // This will be used when validating the connection request from users to the web console URL. diff --git a/controllers/virtualmachinewebconsolerequest/v1alpha2/webconsolerequest_intg_test.go b/controllers/virtualmachinewebconsolerequest/v1alpha2/webconsolerequest_intg_test.go index 16d9c8569..ab8038f22 100644 --- a/controllers/virtualmachinewebconsolerequest/v1alpha2/webconsolerequest_intg_test.go +++ b/controllers/virtualmachinewebconsolerequest/v1alpha2/webconsolerequest_intg_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2022 VMware, Inc. All Rights Reserved. +// Copyright (c) 2022-2024 VMware, Inc. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 package v1alpha2_test @@ -18,6 +18,7 @@ import ( vmopv1 "github.com/vmware-tanzu/vm-operator/api/v1alpha3" webconsolerequest "github.com/vmware-tanzu/vm-operator/controllers/virtualmachinewebconsolerequest/v1alpha2" "github.com/vmware-tanzu/vm-operator/pkg/constants/testlabels" + "github.com/vmware-tanzu/vm-operator/pkg/util" "github.com/vmware-tanzu/vm-operator/test/builder" ) @@ -80,8 +81,8 @@ func intgTestsReconcile() { proxySvc = &corev1.Service{ ObjectMeta: metav1.ObjectMeta{ - Name: webconsolerequest.ProxyAddrServiceName, - Namespace: webconsolerequest.ProxyAddrServiceNamespace, + Name: util.ProxyAddrServiceName, + Namespace: util.ProxyAddrServiceNamespace, }, Spec: corev1.ServiceSpec{ Type: corev1.ServiceTypeLoadBalancer, diff --git a/controllers/virtualmachinewebconsolerequest/v1alpha2/webconsolerequest_unit_test.go b/controllers/virtualmachinewebconsolerequest/v1alpha2/webconsolerequest_unit_test.go index f513b95b7..9e701bfc5 100644 --- a/controllers/virtualmachinewebconsolerequest/v1alpha2/webconsolerequest_unit_test.go +++ b/controllers/virtualmachinewebconsolerequest/v1alpha2/webconsolerequest_unit_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2022 VMware, Inc. All Rights Reserved. +// Copyright (c) 2022-2024 VMware, Inc. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 package v1alpha2_test @@ -16,9 +16,12 @@ import ( vmopv1 "github.com/vmware-tanzu/vm-operator/api/v1alpha3" webconsolerequest "github.com/vmware-tanzu/vm-operator/controllers/virtualmachinewebconsolerequest/v1alpha2" + appv1a1 "github.com/vmware-tanzu/vm-operator/external/appplatform/api/v1alpha1" + pkgcfg "github.com/vmware-tanzu/vm-operator/pkg/config" "github.com/vmware-tanzu/vm-operator/pkg/constants/testlabels" pkgctx "github.com/vmware-tanzu/vm-operator/pkg/context" providerfake "github.com/vmware-tanzu/vm-operator/pkg/providers/fake" + "github.com/vmware-tanzu/vm-operator/pkg/util" "github.com/vmware-tanzu/vm-operator/test/builder" ) @@ -37,11 +40,12 @@ func unitTestsReconcile() { ctx *builder.UnitTestContextForController fakeVMProvider *providerfake.VMProvider - reconciler *webconsolerequest.Reconciler - wcrCtx *pkgctx.WebConsoleRequestContextV1 - wcr *vmopv1.VirtualMachineWebConsoleRequest - vm *vmopv1.VirtualMachine - proxySvc *corev1.Service + reconciler *webconsolerequest.Reconciler + wcrCtx *pkgctx.WebConsoleRequestContextV1 + wcr *vmopv1.VirtualMachineWebConsoleRequest + vm *vmopv1.VirtualMachine + proxySvc *corev1.Service + proxySvcDNS *appv1a1.SupervisorProperties ) BeforeEach(func() { @@ -63,8 +67,8 @@ func unitTestsReconcile() { proxySvc = &corev1.Service{ ObjectMeta: metav1.ObjectMeta{ - Name: webconsolerequest.ProxyAddrServiceName, - Namespace: webconsolerequest.ProxyAddrServiceNamespace, + Name: util.ProxyAddrServiceName, + Namespace: util.ProxyAddrServiceNamespace, }, Status: corev1.ServiceStatus{ LoadBalancer: corev1.LoadBalancerStatus{ @@ -131,5 +135,35 @@ func unitTestsReconcile() { Expect(wcrCtx.WebConsoleRequest.Labels).To(HaveKey(webconsolerequest.UUIDLabelKey)) }) }) + + When("SimplifiedEnablement is enabled", func() { + JustBeforeEach(func() { + pkgcfg.UpdateContext(ctx, + func(config *pkgcfg.Config) { + config.Features.SimplifiedEnablement = true + }, + ) + }) + + DescribeTable("DNS Names", + func(apiServerDNSName []string, expectedProxy string) { + proxySvcDNS = &appv1a1.SupervisorProperties{ + ObjectMeta: metav1.ObjectMeta{ + Name: "supervisor-env-props", + Namespace: "vmware-system-supervisor-services", + }, + Spec: appv1a1.SupervisorPropertiesSpec{ + APIServerDNSNames: apiServerDNSName, + }, + } + Expect(ctx.Client.Create(ctx, proxySvcDNS)).To(Succeed()) + + Expect(reconciler.ReconcileNormal(wcrCtx)).To(Succeed()) + Expect(wcrCtx.WebConsoleRequest.Status.ProxyAddr).To(Equal(expectedProxy)) + }, + Entry("API Server DNS Name is set", []string{"domain-1.test"}, "domain-1.test"), + Entry("API Server DNS Name is not set", []string{}, "dummy-proxy-ip"), + ) + }) }) } diff --git a/external/appplatform/api/v1alpha1/doc.go b/external/appplatform/api/v1alpha1/doc.go new file mode 100644 index 000000000..7e1c1940d --- /dev/null +++ b/external/appplatform/api/v1alpha1/doc.go @@ -0,0 +1,12 @@ +// Copyright (c) 2024 VMware, Inc. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +// Package v1alpha1 contains API Schema definitions for the appplatform.vmware.com v1alpha1 API group +// This is different from the older appplatform.wcp.vmware.com. +// +k8s:openapi-gen=true +// +k8s:deepcopy-gen=package,register +// +k8s:conversion-gen=wcp-appplatform-operator/api +// +k8s:defaulter-gen=TypeMeta +// +groupName=appplatform.vmware.com +// +versionName=v1alpha1 +package v1alpha1 diff --git a/external/appplatform/api/v1alpha1/register.go b/external/appplatform/api/v1alpha1/register.go new file mode 100644 index 000000000..25e97db6b --- /dev/null +++ b/external/appplatform/api/v1alpha1/register.go @@ -0,0 +1,34 @@ +// Copyright (c) 2024 VMware, Inc. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +// NOTE: Boilerplate only. Ignore this file. + +// Package v1alpha1 contains API Schema definitions for the appplatform v1alpha1 API group +// +k8s:openapi-gen=true +// +k8s:deepcopy-gen=package,register +// +k8s:conversion-gen=wcp-appplatform-operator/api +// +k8s:defaulter-gen=TypeMeta +// +groupName=appplatform.vmware.com +// +versionName=v1alpha1 +package v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // SchemeGroupVersion is group version used to register these objects + SchemeGroupVersion = schema.GroupVersion{Group: "appplatform.vmware.com", Version: "v1alpha1"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme + SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion} + + // AddToScheme is required by pkg/client/... + AddToScheme = SchemeBuilder.AddToScheme +) + +// Resource is required by pkg/client/listers/... +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} diff --git a/external/appplatform/api/v1alpha1/supervisorprops_types.go b/external/appplatform/api/v1alpha1/supervisorprops_types.go new file mode 100644 index 000000000..1808eb086 --- /dev/null +++ b/external/appplatform/api/v1alpha1/supervisorprops_types.go @@ -0,0 +1,103 @@ +// Copyright (c) 2024 VMware, Inc. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func init() { + SchemeBuilder.Register(&SupervisorProperties{}, &SupervisorPropertiesList{}) +} + +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. +// Important: Run "make" to regenerate code after modifying this file + +// +genclient +// +k8s:openapi-gen=true +// +kubebuilder:object:root=true +// +kubebuilder:resource:scope=Namespaced +// +kubebuilder:resource:singular=supervisorproperty +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// SupervisorProperties is the Schema for the SupervisorProperties API +type SupervisorProperties struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec SupervisorPropertiesSpec `json:"spec,omitempty"` +} + +// +kubebuilder:validation:Enum=TINY;SMALL;MEDIUM;LARGE +type ControlPlaneVMSize string + +// SupervisorPropertiesSpec defines the values of the properties requested by a Supervisor Service Package. +type SupervisorPropertiesSpec struct { + + // VCenterPublicKeys indicates the base64 encoded vCenter OIDC issuer, client audience and the public keys in JWKS format. + VCenterPublicKeys string `json:"vcPublicKeys,omitempty"` + + // VCenterPNID indicates the Primary Network Identifier of vCenter. + VCenterPNID string `json:"vcPNID,omitempty"` + + // NetworkProvider indicates the Network Provider used on Supervisor. (e.g. NSX, nsx-vpc, or vsphere-network) + NetworkProvider string `json:"networkProvider,omitempty"` + + // VCenterPort indicates the port of vCenter. + VCenterPort string `json:"vcPort,omitempty"` + + // VirtualIP indicates the IP address of the Kubernetes LoadBalancer type service fronting the apiservers. + VirtualIP string `json:"virtualIP,omitempty"` + + // SSODomain indicates the name of the default SSO domain configured in vCenter. + SSODomain string `json:"ssoDomain,omitempty"` + + // ControlPlaneVMSize indicates the capacity of the Supervisor Control Plane. It's derived from Supervisor's tshirt size. + ControlPlaneVMSize ControlPlaneVMSize `json:"cpVMSize,omitempty"` + + // TMCNamespace indicates the namespace used for TMC to be deployed. + TMCNamespace string `json:"tmcNamespace,omitempty"` + + // NamespacesCLIPluginVersion indicates the Supervisor recommended namespaces CLIPlugin CR version. + NamespacesCLIPluginVersion string `json:"namespacesCLIPluginVersion,omitempty"` + + // CloudVCenter indicates if the vCenter is deployed on cloud. + CloudVCenter bool `json:"cloudVC,omitempty"` + + // PodVMSupported indicates if the Supervisor supports PodVMs. + PodVMSupported bool `json:"podVMSupported,omitempty"` + + // StretchedSupervisor indicates if the Supervisor is enabled on a set of vSphere Zones. + StretchedSupervisor bool `json:"stretchedSupervisor,omitempty"` + + // ControlPlaneCount indicates the number of control planes enabled on the Supervisor. + ControlPlaneCount int `json:"controlPlaneCount,omitempty"` + + // Capabilities defines the capabilities the Supervisor has. The common case of the capability is the feature supported of the vCenter. + Capabilities []Capability `json:"capabilities,omitempty"` + + // APIServerDNSNames indicates the API server DNS Names associated with the supervisor. + APIServerDNSNames []string `json:"apiServerDNSNames,omitempty"` +} + +// Capability defines the feature supported by the Supervisor. +type Capability struct { + + // The name of the capability. + Name string `json:"name"` + + // +kubebuilder:default:=false + // The value indicates if the capability is supported. + Value bool `json:"value"` +} + +// +kubebuilder:object:root=true +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// SupervisorPropertiesList contains a list of SupervisorProperties +type SupervisorPropertiesList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []SupervisorProperties `json:"items"` +} diff --git a/external/appplatform/api/v1alpha1/zz_generated.deepcopy.go b/external/appplatform/api/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 000000000..ea86e6dfc --- /dev/null +++ b/external/appplatform/api/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,110 @@ +//go:build !ignore_autogenerated + +// Copyright (c) 2024 VMware, Inc. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +// Code generated by controller-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Capability) DeepCopyInto(out *Capability) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Capability. +func (in *Capability) DeepCopy() *Capability { + if in == nil { + return nil + } + out := new(Capability) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SupervisorProperties) DeepCopyInto(out *SupervisorProperties) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SupervisorProperties. +func (in *SupervisorProperties) DeepCopy() *SupervisorProperties { + if in == nil { + return nil + } + out := new(SupervisorProperties) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *SupervisorProperties) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SupervisorPropertiesList) DeepCopyInto(out *SupervisorPropertiesList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]SupervisorProperties, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SupervisorPropertiesList. +func (in *SupervisorPropertiesList) DeepCopy() *SupervisorPropertiesList { + if in == nil { + return nil + } + out := new(SupervisorPropertiesList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *SupervisorPropertiesList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SupervisorPropertiesSpec) DeepCopyInto(out *SupervisorPropertiesSpec) { + *out = *in + if in.Capabilities != nil { + in, out := &in.Capabilities, &out.Capabilities + *out = make([]Capability, len(*in)) + copy(*out, *in) + } + if in.APIServerDNSNames != nil { + in, out := &in.APIServerDNSNames, &out.APIServerDNSNames + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SupervisorPropertiesSpec. +func (in *SupervisorPropertiesSpec) DeepCopy() *SupervisorPropertiesSpec { + if in == nil { + return nil + } + out := new(SupervisorPropertiesSpec) + in.DeepCopyInto(out) + return out +} diff --git a/external/appplatform/go.mod b/external/appplatform/go.mod new file mode 100644 index 000000000..b5d781d39 --- /dev/null +++ b/external/appplatform/go.mod @@ -0,0 +1,27 @@ +module github.com/vmware-tanzu/vm-operator + +go 1.22.7 + +require ( + k8s.io/apimachinery v0.31.1 + sigs.k8s.io/controller-runtime v0.19.0 +) + +require ( + github.com/fxamacker/cbor/v2 v2.7.0 // indirect + github.com/go-logr/logr v1.4.2 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/google/gofuzz v1.2.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/x448/float16 v0.8.4 // indirect + golang.org/x/net v0.26.0 // indirect + golang.org/x/text v0.16.0 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + k8s.io/klog/v2 v2.130.1 // indirect + k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect + sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect +) diff --git a/external/appplatform/go.sum b/external/appplatform/go.sum new file mode 100644 index 000000000..3fc5c17fd --- /dev/null +++ b/external/appplatform/go.sum @@ -0,0 +1,104 @@ +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= +github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af h1:kmjWCqn2qkEml422C2Rrd27c3VGxi6a/6HNq8QmHRKM= +github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA= +github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To= +github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= +github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= +github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +k8s.io/api v0.31.0 h1:b9LiSjR2ym/SzTOlfMHm1tr7/21aD7fSkqgD/CVJBCo= +k8s.io/api v0.31.0/go.mod h1:0YiFF+JfFxMM6+1hQei8FY8M7s1Mth+z/q7eF1aJkTE= +k8s.io/apimachinery v0.31.1 h1:mhcUBbj7KUjaVhyXILglcVjuS4nYXiwC+KKFBgIVy7U= +k8s.io/apimachinery v0.31.1/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= +k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= +k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= +k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/controller-runtime v0.19.0 h1:nWVM7aq+Il2ABxwiCizrVDSlmDcshi9llbaFbC0ji/Q= +sigs.k8s.io/controller-runtime v0.19.0/go.mod h1:iRmWllt8IlaLjvTTDLhRBXIEtkCK6hwVBJJsYS9Ajf4= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= +sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= +sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= +sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= +sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/go.mod b/go.mod index 0d5a6d4b4..b1f381ddc 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ replace ( github.com/envoyproxy/go-control-plane => github.com/envoyproxy/go-control-plane v0.9.4 github.com/envoyproxy/protoc-gen-validate => github.com/envoyproxy/protoc-gen-validate v0.1.0 github.com/vmware-tanzu/vm-operator/api => ./api + github.com/vmware-tanzu/vm-operator/external/appplatform => ./external/appplatform github.com/vmware-tanzu/vm-operator/external/byok => ./external/byok github.com/vmware-tanzu/vm-operator/external/capabilities => ./external/capabilities github.com/vmware-tanzu/vm-operator/external/ncp => ./external/ncp @@ -27,8 +28,9 @@ require ( github.com/vmware-tanzu/net-operator-api v0.0.0-20240523152550-862e2c4eb0e0 github.com/vmware-tanzu/nsx-operator/pkg/apis v0.0.0-20240902045731-00a14868c72d github.com/vmware-tanzu/vm-operator/api v0.0.0-00010101000000-000000000000 - github.com/vmware-tanzu/vm-operator/external/byok v0.0.0-00010101000000-000000000000 github.com/vmware-tanzu/vm-operator/external/capabilities v0.0.0-00010101000000-000000000000 + github.com/vmware-tanzu/vm-operator/external/appplatform v0.0.0-00010101000000-000000000000 + github.com/vmware-tanzu/vm-operator/external/byok v0.0.0-00010101000000-000000000000 github.com/vmware-tanzu/vm-operator/external/ncp v0.0.0-00010101000000-000000000000 github.com/vmware-tanzu/vm-operator/external/storage-policy-quota v0.0.0-00010101000000-000000000000 github.com/vmware-tanzu/vm-operator/external/tanzu-topology v0.0.0-00010101000000-000000000000 diff --git a/pkg/manager/manager.go b/pkg/manager/manager.go index 8418f234b..337b1ee43 100644 --- a/pkg/manager/manager.go +++ b/pkg/manager/manager.go @@ -23,6 +23,7 @@ import ( vpcv1alpha1 "github.com/vmware-tanzu/nsx-operator/pkg/apis/vpc/v1alpha1" netopv1alpha1 "github.com/vmware-tanzu/net-operator-api/api/v1alpha1" + appv1a1 "github.com/vmware-tanzu/vm-operator/external/appplatform/api/v1alpha1" byokv1 "github.com/vmware-tanzu/vm-operator/external/byok/api/v1alpha1" capv1 "github.com/vmware-tanzu/vm-operator/external/capabilities/api/v1alpha1" ncpv1alpha1 "github.com/vmware-tanzu/vm-operator/external/ncp/api/v1alpha1" @@ -60,6 +61,7 @@ func New(ctx context.Context, opts Options) (Manager, error) { _ = spqv1.AddToScheme(opts.Scheme) _ = byokv1.AddToScheme(opts.Scheme) _ = capv1.AddToScheme(opts.Scheme) + _ = appv1a1.AddToScheme(opts.Scheme) _ = vmopv1a1.AddToScheme(opts.Scheme) _ = vmopv1a2.AddToScheme(opts.Scheme) diff --git a/pkg/util/proxy_address.go b/pkg/util/proxy_address.go new file mode 100644 index 000000000..0bddbc6e4 --- /dev/null +++ b/pkg/util/proxy_address.go @@ -0,0 +1,78 @@ +// Copyright (c) 2024 VMware, Inc. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package util + +import ( + "context" + "fmt" + + corev1 "k8s.io/api/core/v1" + "sigs.k8s.io/controller-runtime/pkg/client" + + appv1a1 "github.com/vmware-tanzu/vm-operator/external/appplatform/api/v1alpha1" + pkgcfg "github.com/vmware-tanzu/vm-operator/pkg/config" +) + +const ( + SupervisorServiceObjName = "supervisor-env-props" + SupervisorServiceObjNamespace = "vmware-system-supervisor-services" + + ProxyAddrServiceName = "kube-apiserver-lb-svc" + ProxyAddrServiceNamespace = "kube-system" +) + +// ProxyAddress first attempts to get the proxy address through the API Server DNS Names. +// If that is unset, though, fall back to using the virtual IP. +func ProxyAddress(ctx context.Context, r client.Client) (string, error) { + if !pkgcfg.FromContext(ctx).Features.SimplifiedEnablement { + return proxyAddressFromVirtualIP(ctx, r) + } + + // Attempt to use the API Server DNS Names to get the proxy address. + proxyAddress, err := proxyServiceDNSName(ctx, r) + if err != nil { + return "", fmt.Errorf("failed to get proxy service URL: %w", err) + } + + // If no API Server DNS Name exists, fall back to using the virtual IP. + if proxyAddress == "" { + return proxyAddressFromVirtualIP(ctx, r) + } + + return proxyAddress, nil +} + +// proxyServiceDNSName retrieves the first API server DNS name using the provided client by +// querying the appplatform CRD, if one exists. +func proxyServiceDNSName(ctx context.Context, r client.Client) (string, error) { + proxySvc := &appv1a1.SupervisorProperties{} + proxySvcObjectKey := client.ObjectKey{Name: SupervisorServiceObjName, Namespace: SupervisorServiceObjNamespace} + + if err := r.Get(ctx, proxySvcObjectKey, proxySvc); err != nil { + return "", fmt.Errorf("failed to get proxy address service %s: %w", proxySvcObjectKey, err) + } + + if len(proxySvc.Spec.APIServerDNSNames) == 0 { + return "", nil + } + + // Return the first FQDN by default + return proxySvc.Spec.APIServerDNSNames[0], nil +} + +// proxyAddressFromVirtualIP retrieves the virtual IP, which will be used as the Proxy Address. +func proxyAddressFromVirtualIP(ctx context.Context, r client.Client) (string, error) { + proxySvc := &corev1.Service{} + proxySvcObjectKey := client.ObjectKey{Name: ProxyAddrServiceName, Namespace: ProxyAddrServiceNamespace} + + if err := r.Get(ctx, proxySvcObjectKey, proxySvc); err != nil { + return "", fmt.Errorf("failed to get proxy address service %s: %w", proxySvcObjectKey, err) + } + + if len(proxySvc.Status.LoadBalancer.Ingress) == 0 { + return "", fmt.Errorf("no ingress found for proxy address service %s", proxySvcObjectKey) + } + + return proxySvc.Status.LoadBalancer.Ingress[0].IP, nil +} diff --git a/test/builder/fake.go b/test/builder/fake.go index fc0f224de..d0e1b2f1e 100644 --- a/test/builder/fake.go +++ b/test/builder/fake.go @@ -15,6 +15,7 @@ import ( netopv1alpha1 "github.com/vmware-tanzu/net-operator-api/api/v1alpha1" vpcv1alpha1 "github.com/vmware-tanzu/nsx-operator/pkg/apis/vpc/v1alpha1" + appv1a1 "github.com/vmware-tanzu/vm-operator/external/appplatform/api/v1alpha1" byokv1 "github.com/vmware-tanzu/vm-operator/external/byok/api/v1alpha1" capv1 "github.com/vmware-tanzu/vm-operator/external/capabilities/api/v1alpha1" ncpv1alpha1 "github.com/vmware-tanzu/vm-operator/external/ncp/api/v1alpha1" @@ -71,6 +72,7 @@ func KnownObjectTypes() []client.Object { &vpcv1alpha1.SubnetPort{}, &byokv1.EncryptionClass{}, &capv1.Capabilities{}, + &appv1a1.SupervisorProperties{}, } } @@ -88,6 +90,7 @@ func NewScheme() *runtime.Scheme { _ = vmopv1.AddToScheme(scheme) _ = capv1.AddToScheme(scheme) _ = byokv1.AddToScheme(scheme) + _ = appv1a1.AddToScheme(scheme) _ = ncpv1alpha1.AddToScheme(scheme) _ = cnsapis.AddToScheme(scheme) _ = spqv1.AddToScheme(scheme)