Skip to content

Commit

Permalink
✨ allow other identity in vmmachine
Browse files Browse the repository at this point in the history
Signed-off-by: Jan Jansen <[email protected]>
  • Loading branch information
farodin91 committed May 3, 2023
1 parent 1834bea commit db9d2d7
Show file tree
Hide file tree
Showing 10 changed files with 116 additions and 24 deletions.
1 change: 1 addition & 0 deletions apis/v1alpha3/zz_generated.conversion.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions apis/v1alpha4/zz_generated.conversion.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions apis/v1beta1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,11 @@ type VirtualMachineCloneSpec struct {
// Check the compatibility with the ESXi version before setting the value.
// +optional
HardwareVersion string `json:"hardwareVersion,omitempty"`

// IdentityRef is a reference to either a Secret or VSphereClusterIdentity that contains
// the identity to use when reconciling the virtual machine.
// +optional
IdentityRef *VSphereIdentityReference `json:"identityRef,omitempty"`
}

// VSphereMachineTemplateResource describes the data needed to create a VSphereMachine from a template
Expand Down
5 changes: 5 additions & 0 deletions apis/v1beta1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -903,6 +903,25 @@ spec:
from which the virtual machine is cloned. Check the compatibility
with the ESXi version before setting the value.
type: string
identityRef:
description: IdentityRef is a reference to either a Secret or VSphereClusterIdentity
that contains the identity to use when reconciling the virtual machine.
properties:
kind:
description: Kind of the identity. Can either be VSphereClusterIdentity
or Secret
enum:
- VSphereClusterIdentity
- Secret
type: string
name:
description: Name of the identity.
minLength: 1
type: string
required:
- kind
- name
type: object
memoryMiB:
description: MemoryMiB is the size of a virtual machine's memory,
in MiB. Defaults to the eponymous property value in the template
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -789,6 +789,26 @@ spec:
Check the compatibility with the ESXi version before setting
the value.
type: string
identityRef:
description: IdentityRef is a reference to either a Secret
or VSphereClusterIdentity that contains the identity to
use when reconciling the virtual machine.
properties:
kind:
description: Kind of the identity. Can either be VSphereClusterIdentity
or Secret
enum:
- VSphereClusterIdentity
- Secret
type: string
name:
description: Name of the identity.
minLength: 1
type: string
required:
- kind
- name
type: object
memoryMiB:
description: MemoryMiB is the size of a virtual machine's
memory, in MiB. Defaults to the eponymous property value
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -950,6 +950,25 @@ spec:
from which the virtual machine is cloned. Check the compatibility
with the ESXi version before setting the value.
type: string
identityRef:
description: IdentityRef is a reference to either a Secret or VSphereClusterIdentity
that contains the identity to use when reconciling the virtual machine.
properties:
kind:
description: Kind of the identity. Can either be VSphereClusterIdentity
or Secret
enum:
- VSphereClusterIdentity
- Secret
type: string
name:
description: Name of the identity.
minLength: 1
type: string
required:
- kind
- name
type: object
memoryMiB:
description: MemoryMiB is the size of a virtual machine's memory,
in MiB. Defaults to the eponymous property value in the template
Expand Down
47 changes: 32 additions & 15 deletions controllers/vspherevm_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -529,28 +529,24 @@ func (r vmReconciler) retrieveVcenterSession(ctx goctx.Context, vsphereVM *infra
params := session.NewParams().
WithServer(vsphereVM.Spec.Server).
WithDatacenter(vsphereVM.Spec.Datacenter).
WithUserInfo(r.ControllerContext.Username, r.ControllerContext.Password).
WithThumbprint(vsphereVM.Spec.Thumbprint).
WithFeatures(session.Feature{
KeepAliveDuration: r.KeepAliveDuration,
})
cluster, err := clusterutilv1.GetClusterFromMetadata(r.ControllerContext, r.Client, vsphereVM.ObjectMeta)

vsphereCluster, err := r.retrieveCluster(vsphereVM)
if err != nil {
r.Logger.Info("VsphereVM is missing cluster label or cluster does not exist")
return session.GetOrCreate(r.Context,
params)
return nil, err
}

key := ctrlclient.ObjectKey{
Namespace: cluster.Namespace,
Name: cluster.Spec.InfrastructureRef.Name,
}
vsphereCluster := &infrav1.VSphereCluster{}
err = r.Client.Get(r, key, vsphereCluster)
if err != nil {
r.Logger.Info("VSphereCluster couldn't be retrieved")
return session.GetOrCreate(r.Context,
params)
if vsphereVM.Spec.IdentityRef != nil {
creds, err := identity.GetCredentialsWithExternalIdentity(ctx, r.Client, vsphereCluster, vsphereVM.Spec.IdentityRef, r.Namespace)
if err != nil {
return nil, err
}

params = params.WithUserInfo(creds.Username, creds.Password)
return session.GetOrCreate(ctx, params)
}

if vsphereCluster.Spec.IdentityRef != nil {
Expand All @@ -563,11 +559,32 @@ func (r vmReconciler) retrieveVcenterSession(ctx goctx.Context, vsphereVM *infra
params)
}

params = params.WithUserInfo(r.ControllerContext.Username, r.ControllerContext.Password)
// Fallback to using credentials provided to the manager
return session.GetOrCreate(r.Context,
params)
}

func (r vmReconciler) retrieveCluster(vsphereVM *infrav1.VSphereVM) (*infrav1.VSphereCluster, error) {
cluster, err := clusterutilv1.GetClusterFromMetadata(r.ControllerContext, r.Client, vsphereVM.ObjectMeta)
if err != nil {
r.Logger.Info("VsphereVM is missing cluster label or cluster does not exist")
return nil, err
}

key := ctrlclient.ObjectKey{
Namespace: cluster.Namespace,
Name: cluster.Spec.InfrastructureRef.Name,
}
vsphereCluster := &infrav1.VSphereCluster{}
err = r.Client.Get(r, key, vsphereCluster)
if err != nil {
r.Logger.Info("VSphereCluster couldn't be retrieved")
return nil, err
}
return vsphereCluster, nil
}

func (r vmReconciler) fetchClusterModuleInfo(clusterModInput fetchClusterModuleInput) (*string, error) {
var (
owner ctrlclient.Object
Expand Down
17 changes: 11 additions & 6 deletions pkg/identity/identity.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,11 @@ type Credentials struct {
Password string
}

func GetCredentials(ctx context.Context, c client.Client, cluster *infrav1.VSphereCluster, controllerNamespace string) (*Credentials, error) {
if err := validateInputs(c, cluster); err != nil {
func GetCredentialsWithExternalIdentity(ctx context.Context, c client.Client, cluster *infrav1.VSphereCluster, ref *infrav1.VSphereIdentityReference, controllerNamespace string) (*Credentials, error) {
if err := validateInputs(c, cluster, ref); err != nil {
return nil, err
}

ref := cluster.Spec.IdentityRef
secret := &apiv1.Secret{}
var secretKey client.ObjectKey

Expand Down Expand Up @@ -108,15 +107,21 @@ func GetCredentials(ctx context.Context, c client.Client, cluster *infrav1.VSphe
return credentials, nil
}

func validateInputs(c client.Client, cluster *infrav1.VSphereCluster) error {
func GetCredentials(ctx context.Context, c client.Client, cluster *infrav1.VSphereCluster, controllerNamespace string) (*Credentials, error) {
if err := validateInputs(c, cluster, cluster.Spec.IdentityRef); err != nil {
return nil, err
}
return GetCredentialsWithExternalIdentity(ctx, c, cluster, cluster.Spec.IdentityRef, controllerNamespace)
}

func validateInputs(c client.Client, cluster *infrav1.VSphereCluster, identityRef *infrav1.VSphereIdentityReference) error {
if c == nil {
return errors.New("kubernetes client is required")
}
if cluster == nil {
return errors.New("vsphere cluster is required")
}
ref := cluster.Spec.IdentityRef
if ref == nil {
if identityRef == nil {
return errors.New("IdentityRef is required")
}
return nil
Expand Down
6 changes: 3 additions & 3 deletions pkg/identity/identity_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,19 +236,19 @@ var _ = Describe("validateInputs", func() {

Context("If the client is missing", func() {
It("should error if client is missing", func() {
Expect(validateInputs(nil, cluster)).NotTo(Succeed())
Expect(validateInputs(nil, cluster, nil)).NotTo(Succeed())
})
})

Context("If the cluster is missing", func() {
It("should error if cluster is missing", func() {
Expect(validateInputs(k8sclient, nil)).NotTo(Succeed())
Expect(validateInputs(k8sclient, nil, nil)).NotTo(Succeed())
})
})

Context("If the identityRef is missing on cluster", func() {
It("should error if identityRef is missing on cluster", func() {
Expect(validateInputs(k8sclient, cluster)).NotTo(Succeed())
Expect(validateInputs(k8sclient, cluster, nil)).NotTo(Succeed())
})
})
})
Expand Down

0 comments on commit db9d2d7

Please sign in to comment.