Skip to content

Commit

Permalink
Merge pull request #317 from crossplane/backport-314-to-release-0.18
Browse files Browse the repository at this point in the history
[Backport release-0.18] Reuse generated password for AKSCluster's Application
  • Loading branch information
ulucinar committed Dec 13, 2021
2 parents 7e7f436 + 9be20aa commit 159d0d8
Show file tree
Hide file tree
Showing 3 changed files with 167 additions and 5 deletions.
2 changes: 1 addition & 1 deletion pkg/clients/compute/aks.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ func (c AggregateClient) ensureApplication(ctx context.Context, name, secret str
return l.Value(), nil // nolint:staticcheck
}

url := fmt.Sprintf("https://%s.aks.crossplane.io", name)
url := fmt.Sprintf("api://%s.aks.crossplane.io", name)
p := graphrbac.ApplicationCreateParameters{
AvailableToOtherTenants: to.BoolPtr(false),
DisplayName: to.StringPtr(name),
Expand Down
39 changes: 35 additions & 4 deletions pkg/controller/compute/managed.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import (

"github.com/Azure/go-autorest/autorest/to"
"github.com/pkg/errors"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/client-go/util/workqueue"
ctrl "sigs.k8s.io/controller-runtime"
Expand Down Expand Up @@ -50,6 +52,7 @@ const (
errGetAKSCluster = "cannot get AKSCluster"
errGetKubeConfig = "cannot get AKSCluster kubeconfig"
errDeleteAKSCluster = "cannot delete AKSCluster"
errGetConnSecret = "cannot get connection secret"
)

// SetupAKSCluster adds a controller that reconciles AKSClusters.
Expand Down Expand Up @@ -143,14 +146,42 @@ func (e *external) Create(ctx context.Context, mg resource.Managed) (managed.Ext
return managed.ExternalCreation{}, errors.New(errNotAKSCluster)
}
cr.SetConditions(xpv1.Creating())
secret, err := e.newPasswordFn()

pw, err := e.getPassword(ctx, cr)
if err != nil {
return managed.ExternalCreation{}, errors.Wrap(err, errGenPassword)
return managed.ExternalCreation{}, err
}
if pw == "" {
pw, err = e.newPasswordFn()
if err != nil {
return managed.ExternalCreation{}, errors.Wrap(err, errGenPassword)
}
}
return managed.ExternalCreation{
ConnectionDetails: managed.ConnectionDetails{
xpv1.ResourceCredentialsSecretPasswordKey: []byte(pw),
},
}, errors.Wrap(e.client.EnsureManagedCluster(ctx, cr, pw), errCreateAKSCluster)
}

func (e *external) getPassword(ctx context.Context, cr *v1alpha3.AKSCluster) (string, error) {
if cr.Spec.WriteConnectionSecretToReference == nil ||
cr.Spec.WriteConnectionSecretToReference.Name == "" || cr.Spec.WriteConnectionSecretToReference.Namespace == "" {
return "", nil
}
return managed.ExternalCreation{}, errors.Wrap(e.client.EnsureManagedCluster(ctx, cr, secret), errCreateAKSCluster)

s := &v1.Secret{}
if err := e.kube.Get(ctx, types.NamespacedName{
Namespace: cr.Spec.WriteConnectionSecretToReference.Namespace,
Name: cr.Spec.WriteConnectionSecretToReference.Name,
}, s); err != nil {
return "", errors.Wrap(err, errGetConnSecret)
}

return string(s.Data[xpv1.ResourceCredentialsSecretPasswordKey]), nil
}

func (e *external) Update(ctx context.Context, mg resource.Managed) (managed.ExternalUpdate, error) {
func (e *external) Update(_ context.Context, _ resource.Managed) (managed.ExternalUpdate, error) {
// TODO(negz): Support updates.
return managed.ExternalUpdate{}, nil
}
Expand Down
131 changes: 131 additions & 0 deletions pkg/controller/compute/managed_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,11 @@ import (
"github.com/Azure/azure-sdk-for-go/services/containerservice/mgmt/2018-03-31/containerservice"
"github.com/Azure/go-autorest/autorest"
"github.com/Azure/go-autorest/autorest/to"
xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1"
"github.com/google/go-cmp/cmp"
"github.com/pkg/errors"
v1 "k8s.io/api/core/v1"
"sigs.k8s.io/controller-runtime/pkg/client"

"github.com/crossplane/crossplane-runtime/pkg/reconciler/managed"
"github.com/crossplane/crossplane-runtime/pkg/resource"
Expand All @@ -35,6 +38,11 @@ import (
"github.com/crossplane/provider-azure/pkg/clients/compute/fake"
)

const (
testPasswd = "pass123"
testExistingSecret = "existingSecret"
)

type modifier func(*v1alpha3.AKSCluster)

func withState(state string) modifier {
Expand All @@ -55,6 +63,12 @@ func withEndpoint(ep string) modifier {
}
}

func withConnectionSecretRef(ref *xpv1.SecretReference) modifier {
return func(c *v1alpha3.AKSCluster) {
c.Spec.WriteConnectionSecretToReference = ref
}
}

func aksCluster(m ...modifier) *v1alpha3.AKSCluster {
ac := &v1alpha3.AKSCluster{}

Expand Down Expand Up @@ -254,6 +268,123 @@ func TestCreate(t *testing.T) {
},
want: want{
err: errors.Wrap(errBoom, errCreateAKSCluster),
ec: managed.ExternalCreation{
ConnectionDetails: map[string][]byte{
"password": {},
},
},
},
},
"SuccessEnsureCluster": {
e: &external{
newPasswordFn: func() (string, error) { return testPasswd, nil },
client: fake.AKSClient{
MockEnsureManagedCluster: func(_ context.Context, _ *v1alpha3.AKSCluster, _ string) error {
return nil
},
},
},
args: args{
ctx: context.Background(),
mg: aksCluster(),
},
want: want{
ec: managed.ExternalCreation{
ConnectionDetails: map[string][]byte{
"password": []byte(testPasswd),
},
},
},
},
"SuccessExistingEmptyAppSecret": {
e: &external{
newPasswordFn: func() (string, error) { return testPasswd, nil },
client: fake.AKSClient{
MockEnsureManagedCluster: func(_ context.Context, _ *v1alpha3.AKSCluster, _ string) error {
return nil
},
},
kube: &test.MockClient{
MockGet: func(_ context.Context, _ client.ObjectKey, o client.Object) error {
s, ok := o.(*v1.Secret)
if !ok {
t.Fatalf("not a *v1.Secret")
}
s.Data = map[string][]byte{"password": {}}
return nil
},
},
},
args: args{
ctx: context.Background(),
mg: aksCluster(withConnectionSecretRef(&xpv1.SecretReference{
Name: "test-secret",
Namespace: "test-ns",
})),
},
want: want{
ec: managed.ExternalCreation{
ConnectionDetails: map[string][]byte{
"password": []byte(testPasswd),
},
},
},
},
"SuccessExistingNonEmptyAppSecret": {
e: &external{
newPasswordFn: func() (string, error) { return testPasswd, nil },
client: fake.AKSClient{
MockEnsureManagedCluster: func(_ context.Context, _ *v1alpha3.AKSCluster, _ string) error {
return nil
},
},
kube: &test.MockClient{
MockGet: func(_ context.Context, _ client.ObjectKey, o client.Object) error {
s, ok := o.(*v1.Secret)
if !ok {
t.Fatalf("not a *v1.Secret")
}
s.Data = map[string][]byte{"password": []byte(testExistingSecret)}
return nil
},
},
},
args: args{
ctx: context.Background(),
mg: aksCluster(withConnectionSecretRef(&xpv1.SecretReference{
Name: "test-secret",
Namespace: "test-ns",
})),
},
want: want{
ec: managed.ExternalCreation{
ConnectionDetails: map[string][]byte{
"password": []byte(testExistingSecret),
},
},
},
},
"ErrExistingAppSecret": {
e: &external{
newPasswordFn: func() (string, error) { return testPasswd, nil },
client: fake.AKSClient{
MockEnsureManagedCluster: func(_ context.Context, _ *v1alpha3.AKSCluster, _ string) error {
return nil
},
},
kube: &test.MockClient{
MockGet: test.NewMockGetFn(errBoom),
},
},
args: args{
ctx: context.Background(),
mg: aksCluster(withConnectionSecretRef(&xpv1.SecretReference{
Name: "test-secret",
Namespace: "test-ns",
})),
},
want: want{
err: errors.Wrap(errBoom, errGetConnSecret),
},
},
}
Expand Down

0 comments on commit 159d0d8

Please sign in to comment.