Skip to content

Commit

Permalink
Merge pull request kubernetes-sigs#1181 from gab-satchi/multi-tenancy
Browse files Browse the repository at this point in the history
Add multi-tenancy support
  • Loading branch information
k8s-ci-robot authored Jun 24, 2021
2 parents 34bbb00 + 5484460 commit f9baaa9
Show file tree
Hide file tree
Showing 28 changed files with 2,413 additions and 43 deletions.
29 changes: 21 additions & 8 deletions api/v1alpha3/condition_consts.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,6 @@ const (
// while installing the container storage interface addon; those kind of errors are usually transient
// the operation is automatically re-tried by the controller.
CSIProvisioningFailedReason = "CSIProvisioningFailed"

// VCenterAvailableCondition documents the connectivity with vcenter
// for a given VSphereCluster
VCenterAvailableCondition clusterv1.ConditionType = "VCenterAvailable"

// VCenterUnreachableReason (Severity=Error) documents a VSphereCluster controller detecting
// issues with VCenter reachability;
VCenterUnreachableReason = "VCenterUnreachable"
)

// Conditions and condition Reasons for the VSphereMachine and the VSphereVM object.
Expand Down Expand Up @@ -108,3 +100,24 @@ const (
// NOTE: This reason does not apply to VSphereVM (this state happens after the VSphereVM is in ready state).
WaitingForNetworkAddressesReason = "WaitingForNetworkAddresses"
)

// Conditions and Reasons related to utilizing a VSphereIdentity to make connections to a VCenter. Can currently be used by VSphereCluster and VSphereVM

const (
// VCenterAvailableCondition documents the connectivity with vcenter
// for a given VSphereCluster
VCenterAvailableCondition clusterv1.ConditionType = "VCenterAvailable"

// VCenterUnreachableReason (Severity=Error) documents a VSphereCluster controller detecting
// issues with VCenter reachability;
VCenterUnreachableReason = "VCenterUnreachable"

// CredentialsAvailableCondidtion is used by VSphereClusterIdentity when a credential secret is available and unused by other VSphereClusterIdentities
CredentialsAvailableCondidtion clusterv1.ConditionType = "CredentialsAvailable"

// SecretNotAvailableReason is used when the secret referenced by the VSphereClusterIdentity cannot be found
SecretNotAvailableReason = "SecretNotAvailable"

// SecretAlreadyInUseReason is used when another VSphereClusterIdentity is using the secret
SecretAlreadyInUseReason = "SecretInUse"
)
30 changes: 28 additions & 2 deletions api/v1alpha3/vspherecluster_conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,42 @@ limitations under the License.
package v1alpha3

import (
apiconversion "k8s.io/apimachinery/pkg/conversion"
infrav1alpha4 "sigs.k8s.io/cluster-api-provider-vsphere/api/v1alpha4"
utilconversion "sigs.k8s.io/cluster-api/util/conversion"
"sigs.k8s.io/controller-runtime/pkg/conversion"
)

// ConvertTo converts this VSphereCluster to the Hub version (v1alpha4).
func (src *VSphereCluster) ConvertTo(dstRaw conversion.Hub) error { // nolint
dst := dstRaw.(*infrav1alpha4.VSphereCluster)
return Convert_v1alpha3_VSphereCluster_To_v1alpha4_VSphereCluster(src, dst, nil)
if err := Convert_v1alpha3_VSphereCluster_To_v1alpha4_VSphereCluster(src, dst, nil); err != nil {
return err
}

// Manually restore data.
restored := &infrav1alpha4.VSphereCluster{}
if ok, err := utilconversion.UnmarshalData(src, restored); err != nil || !ok {
return err
}
if restored.Spec.IdentityRef != nil {
dst.Spec.IdentityRef = restored.Spec.IdentityRef
}
return nil
}

// ConvertFrom converts from the Hub version (v1alpha4) to this VSphereCluster.
func (dst *VSphereCluster) ConvertFrom(srcRaw conversion.Hub) error { // nolint
src := srcRaw.(*infrav1alpha4.VSphereCluster)
return Convert_v1alpha4_VSphereCluster_To_v1alpha3_VSphereCluster(src, dst, nil)
if err := Convert_v1alpha4_VSphereCluster_To_v1alpha3_VSphereCluster(src, dst, nil); err != nil {
return err
}

// Preserve Hub data on down-conversion.
if err := utilconversion.MarshalData(src, dst); err != nil {
return err
}
return nil
}

// ConvertTo converts this VSphereClusterList to the Hub version (v1alpha4).
Expand All @@ -44,3 +66,7 @@ func (dst *VSphereClusterList) ConvertFrom(srcRaw conversion.Hub) error { // nol
src := srcRaw.(*infrav1alpha4.VSphereClusterList)
return Convert_v1alpha4_VSphereClusterList_To_v1alpha3_VSphereClusterList(src, dst, nil)
}

func Convert_v1alpha4_VSphereClusterSpec_To_v1alpha3_VSphereClusterSpec(in *infrav1alpha4.VSphereClusterSpec, out *VSphereClusterSpec, s apiconversion.Scope) error { // nolint
return autoConvert_v1alpha4_VSphereClusterSpec_To_v1alpha3_VSphereClusterSpec(in, out, s)
}
5 changes: 5 additions & 0 deletions api/v1alpha3/vspherecluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ type VSphereClusterSpec struct {
// DEPRECATED: will be removed in v1alpha4
// +optional
LoadBalancerRef *corev1.ObjectReference `json:"loadBalancerRef,omitempty"`

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

// VSphereClusterStatus defines the observed state of VSphereClusterSpec
Expand Down
103 changes: 103 additions & 0 deletions api/v1alpha3/vsphereclusteridentity_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/*
Copyright 2021 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1alpha3

import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
clusterv1 "sigs.k8s.io/cluster-api/api/v1alpha3"
)

const (
SecretIdentitySetFinalizer = "vspherecluster/infrastructure.cluster.x-k8s.io"
)

type VSphereClusterIdentitySpec struct {
// SecretName references a Secret inside the controller namespace with the credentials to use
// +kubebuilder:validation:MinLength=1
SecretName string `json:"secretName,omitempty"`

// AllowedNamespaces is used to identify which namespaces are allowed to use this account.
// Namespaces can be selected with a label selector.
// If this object is nil, no namespaces will be allowed
// +optional
AllowedNamespaces *AllowedNamespaces `json:"allowedNamespaces,omitempty"`
}

type VSphereClusterIdentityStatus struct {
// +optional
Ready bool `json:"ready,omitempty"`

// Conditions defines current service state of the VSphereCluster.
// +optional
Conditions clusterv1.Conditions `json:"conditions,omitempty"`
}

type AllowedNamespaces struct {
// Selector is a standard Kubernetes LabelSelector. A label query over a set of resources.
// +optional
Selector metav1.LabelSelector `json:"selector"`
}

type VSphereIdentityKind string

var (
VSphereClusterIdentityKind = VSphereIdentityKind("VSphereClusterIdentity")
SecretKind = VSphereIdentityKind("Secret")
)

type VSphereIdentityReference struct {
// Kind of the identity. Can either be VSphereClusterIdentity or Secret
// +kubebuilder:validation:Enum=VSphereClusterIdentity;Secret
Kind VSphereIdentityKind `json:"kind"`

// Name of the identity.
// +kubebuilder:validation:MinLength=1
Name string `json:"name"`
}

func (c *VSphereClusterIdentity) GetConditions() clusterv1.Conditions {
return c.Status.Conditions
}

func (c *VSphereClusterIdentity) SetConditions(conditions clusterv1.Conditions) {
c.Status.Conditions = conditions
}

// +kubebuilder:object:root=true
// +kubebuilder:resource:path=vsphereclusteridentities,scope=Cluster,categories=cluster-api
// +kubebuilder:subresource:status

// VSphereClusterIdentity defines the account to be used for reconciling clusters
type VSphereClusterIdentity struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec VSphereClusterIdentitySpec `json:"spec,omitempty"`
Status VSphereClusterIdentityStatus `json:"status,omitempty"`
}

// +kubebuilder:object:root=true
// VSphereClusterIdentityList contains a list of VSphereClusterIdentity
type VSphereClusterIdentityList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []VSphereClusterIdentity `json:"items"`
}

func init() {
SchemeBuilder.Register(&VSphereClusterIdentity{}, &VSphereClusterIdentityList{})
}
Loading

0 comments on commit f9baaa9

Please sign in to comment.