Skip to content

Commit

Permalink
switch to using getting identity values from internal type
Browse files Browse the repository at this point in the history
add values to azurecluster instead of expecting an azureidentity
  • Loading branch information
nader-ziada committed Dec 13, 2020
1 parent ea0133f commit 516cbd2
Show file tree
Hide file tree
Showing 28 changed files with 711 additions and 104 deletions.
2 changes: 1 addition & 1 deletion api/v1alpha2/azurecluster_conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func (src *AzureCluster) ConvertTo(dstRaw conversion.Hub) error { // nolint

dst.Status.FailureDomains = restored.Status.FailureDomains
dst.Spec.NetworkSpec.Vnet.CIDRBlocks = restored.Spec.NetworkSpec.Vnet.CIDRBlocks
dst.Spec.IdentityName = restored.Spec.IdentityName
dst.Spec.IdentityRef = restored.Spec.IdentityRef

for _, restoredSubnet := range restored.Spec.NetworkSpec.Subnets {
if restoredSubnet != nil {
Expand Down
2 changes: 1 addition & 1 deletion api/v1alpha2/zz_generated.conversion.go

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

5 changes: 3 additions & 2 deletions api/v1alpha3/azurecluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package v1alpha3

import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
clusterv1 "sigs.k8s.io/cluster-api/api/v1alpha3"
)
Expand Down Expand Up @@ -52,9 +53,9 @@ type AzureClusterSpec struct {
// +optional
AdditionalTags Tags `json:"additionalTags,omitempty"`

// IdentityName is a reference to a AzureIdentity to be used when reconciling this cluster
// IdentityRef is a reference to a AzureIdentity to be used when reconciling this cluster
// +optional
IdentityName *string `json:"identityName,omitempty"`
IdentityRef *corev1.ObjectReference `json:"identityRef,omitempty"`
}

// AzureClusterStatus defines the observed state of AzureCluster
Expand Down
105 changes: 105 additions & 0 deletions api/v1alpha3/azureclusteridentity_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
Copyright 2020 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 (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
clusterv1 "sigs.k8s.io/cluster-api/api/v1alpha3"
)

// AzureClusterIdentitySpec defines the parameters that are used to create an AzureIdentity
type AzureClusterIdentitySpec struct {
// UserAssignedMSI or Service Principal
Type IdentityType `json:"type"`
// User assigned MSI resource id.
// +optional
ResourceID string `json:"resourceID,omitempty"`
// Both User Assigned MSI and SP can use this field.
ClientID string `json:"clientID"`
// ClientSecret is a secret reference which should contain either a Service Principal password or certificate secret.
// +optional
ClientSecret corev1.SecretReference `json:"clientSecret,omitempty"`
// Service principal primary tenant id.
TenantID string `json:"tenantID"`
// AllowedNamespaces is an array of namespaces that AzureClusters can
// use this Identity from.
//
// An empty list (default) indicates that AzureClusters can use this
// Identity from any namespace. This field is intentionally not a
// pointer because the nil behavior (no namespaces) is undesirable here.
// +optional
AllowedNamespaces []string `json:"allowedNamespaces"`
}

// AzureClusterIdentityStatus defines the observed state of AzureClusterIdentity
type AzureClusterIdentityStatus struct {
// Conditions defines current service state of the AzureClusterIdentity.
// +optional
Conditions clusterv1.Conditions `json:"conditions,omitempty"`
}

// +kubebuilder:object:root=true
// +kubebuilder:resource:path=azureclusteridentities,scope=Namespaced,categories=cluster-api
// +kubebuilder:storageversion
// +kubebuilder:subresource:status

// AzureClusterIdentity is the Schema for the azureclustersidentities API
type AzureClusterIdentity struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec AzureClusterIdentitySpec `json:"spec,omitempty"`
Status AzureClusterIdentityStatus `json:"status,omitempty"`
}

// +kubebuilder:object:root=true

// AzureClusterIdentityList contains a list of AzureClusterIdentity
type AzureClusterIdentityList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []AzureClusterIdentity `json:"items"`
}

// GetConditions returns the list of conditions for an AzureClusterIdentity API object.
func (c *AzureClusterIdentity) GetConditions() clusterv1.Conditions {
return c.Status.Conditions
}

// SetConditions will set the given conditions on an AzureClusterIdentity object
func (c *AzureClusterIdentity) SetConditions(conditions clusterv1.Conditions) {
c.Status.Conditions = conditions
}

// ClusterNamespaceAllowed indicates if the cluster namespace is allowed
func (c *AzureClusterIdentity) ClusterNamespaceAllowed(namespace string) bool {
if len(c.Spec.AllowedNamespaces) == 0 {
return true
}
for _, v := range c.Spec.AllowedNamespaces {
if v == namespace {
return true
}
}

return false
}

func init() {
SchemeBuilder.Register(&AzureClusterIdentity{}, &AzureClusterIdentityList{})
}
71 changes: 71 additions & 0 deletions api/v1alpha3/azureclusteridentity_types_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
Copyright 2020 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 (
"testing"

. "github.com/onsi/gomega"
)

func TestAllowedNamespaces(t *testing.T) {
g := NewWithT(t)

tests := []struct {
name string
identity *AzureClusterIdentity
clusterNamespace string
expected bool
}{
{
name: "allow any cluster namespace when empty",
identity: &AzureClusterIdentity{
Spec: AzureClusterIdentitySpec{
AllowedNamespaces: []string{},
},
},
clusterNamespace: "default",
expected: true,
},
{
name: "allow cluster with namespace in list",
identity: &AzureClusterIdentity{
Spec: AzureClusterIdentitySpec{
AllowedNamespaces: []string{"namespace24", "namespace32"},
},
},
clusterNamespace: "namespace24",
expected: true,
},
{
name: "don't allow cluster with namespace not in list",
identity: &AzureClusterIdentity{
Spec: AzureClusterIdentitySpec{
AllowedNamespaces: []string{"namespace24", "namespace32"},
},
},
clusterNamespace: "namespace8",
expected: false,
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
actual := tc.identity.ClusterNamespaceAllowed(tc.clusterNamespace)
g.Expect(actual).To(Equal(tc.expected))
})
}
}
2 changes: 2 additions & 0 deletions api/v1alpha3/conditions_consts.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ const (
LoadBalancerProvisioningReason = "LoadBalancerProvisioning"
// LoadBalancerProvisioningFailedReason used for failure during provisioning of loadbalancer.
LoadBalancerProvisioningFailedReason = "LoadBalancerProvisioningFailed"
// NamespaceNotAllowedByIdentity used to indicate cluster in a namespace not allowed by identity
NamespaceNotAllowedByIdentity = "NamespaceNotAllowedByIdentity"
)

// AzureMachine Conditions and Reasons
Expand Down
12 changes: 12 additions & 0 deletions api/v1alpha3/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,18 @@ const (
AzureIdentityBindingSelector = "capz-controller-aadpodidentity-selector"
)

// IdentityType represents different types of identities.
// +kubebuilder:validation:Enum=ServicePrincipal;UserAssignedMSI
type IdentityType string

const (
// UserAssignedMSI represents a user-assigned identity.
UserAssignedMSI IdentityType = "UserAssignedMSI"

// ServicePrincipal represents a service principal.
ServicePrincipal IdentityType = "ServicePrincipal"
)

// OSDisk defines the operating system disk for a VM.
type OSDisk struct {
OSType string `json:"osType"`
Expand Down
108 changes: 105 additions & 3 deletions api/v1alpha3/zz_generated.deepcopy.go

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

4 changes: 2 additions & 2 deletions cloud/scope/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,13 @@ func NewClusterScope(ctx context.Context, params ClusterScopeParams) (*ClusterSc
params.Logger = klogr.New()
}

if params.AzureCluster.Spec.IdentityName == nil {
if params.AzureCluster.Spec.IdentityRef == nil {
err := params.AzureClients.setCredentials(params.AzureCluster.Spec.SubscriptionID)
if err != nil {
return nil, errors.Wrap(err, "failed to configure azure settings and credentials from environment")
}
} else {
credentailsProvider, err := NewAzureCredentialsProvider(ctx, params.Client, params.AzureCluster, to.String(params.AzureCluster.Spec.IdentityName), params.AzureCluster.Namespace)
credentailsProvider, err := NewAzureCredentialsProvider(ctx, params.Client, params.AzureCluster)
if err != nil {
return nil, errors.Wrap(err, "failed to init credentials provider")
}
Expand Down
Loading

0 comments on commit 516cbd2

Please sign in to comment.