Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions mocks/pkg/types/service_controller.go

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

21 changes: 17 additions & 4 deletions pkg/runtime/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,28 @@ func (c *serviceController) NewAWSConfig(
endpointURL *string,
roleARN ackv1alpha1.AWSResourceName,
groupVersionKind schema.GroupVersionKind,
labels map[string]string,
) (aws.Config, error) {

extra := []string{
"GitCommit/" + c.VersionInfo.GitCommit,
"BuildDate/" + c.VersionInfo.BuildDate,
"CRDKind/" + groupVersionKind.Kind,
"CRDVersion/" + groupVersionKind.Version,
}

// Add kro managed info if managed by kro
if isKROManaged(labels) {
extra = append(extra, "ManagedBy/kro")
if kroVersion := getKROVersion(labels); kroVersion != "" {
extra = append(extra, "KROVersion/"+kroVersion)
}
}

val := formatUserAgent(
appName,
groupVersionKind.Group+"-"+c.VersionInfo.GitVersion,
"GitCommit/"+c.VersionInfo.GitCommit,
"BuildDate/"+c.VersionInfo.BuildDate,
"CRDKind/"+groupVersionKind.Kind,
"CRDVersion/"+groupVersionKind.Version,
extra...,
)

client := &clientWithUserAgent{
Expand Down
234 changes: 234 additions & 0 deletions pkg/runtime/config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"). You may
// not use this file except in compliance with the License. A copy of the
// License is located at
//
// http://aws.amazon.com/apache2.0/
//
// or in the "license" file accompanying this file. This file 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 runtime

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestFormatUserAgent(t *testing.T) {
tests := []struct {
name string
appName string
version string
extra []string
expected string
}{
{
name: "basic user agent without extras",
appName: "aws-controllers-k8s",
version: "s3-v1.2.3",
extra: nil,
expected: "aws-controllers-k8s/s3-v1.2.3",
},
{
name: "user agent with single extra",
appName: "aws-controllers-k8s",
version: "s3-v1.2.3",
extra: []string{"GitCommit/abc123"},
expected: "aws-controllers-k8s/s3-v1.2.3 (GitCommit/abc123)",
},
{
name: "user agent with multiple extras",
appName: "aws-controllers-k8s",
version: "dynamodb-v1.2.3",
extra: []string{
"GitCommit/abc123",
"BuildDate/2024-01-01",
"CRDKind/Table",
"CRDVersion/v1alpha1",
},
expected: "aws-controllers-k8s/dynamodb-v1.2.3 (GitCommit/abc123; BuildDate/2024-01-01; CRDKind/Table; CRDVersion/v1alpha1)",
},
{
name: "user agent with kro managed info",
appName: "aws-controllers-k8s",
version: "s3-v1.2.3",
extra: []string{
"GitCommit/abc123",
"BuildDate/2024-01-01",
"CRDKind/Bucket",
"CRDVersion/v1alpha1",
"ManagedBy/kro",
"KROVersion/v0.1.0",
},
expected: "aws-controllers-k8s/s3-v1.2.3 (GitCommit/abc123; BuildDate/2024-01-01; CRDKind/Bucket; CRDVersion/v1alpha1; ManagedBy/kro; KROVersion/v0.1.0)",
},
{
name: "user agent with kro managed but no version",
appName: "aws-controllers-k8s",
version: "s3-v1.2.3",
extra: []string{
"GitCommit/abc123",
"BuildDate/2024-01-01",
"CRDKind/Bucket",
"CRDVersion/v1alpha1",
"ManagedBy/kro",
},
expected: "aws-controllers-k8s/s3-v1.2.3 (GitCommit/abc123; BuildDate/2024-01-01; CRDKind/Bucket; CRDVersion/v1alpha1; ManagedBy/kro)",
},
{
name: "empty extra slice",
appName: "test-app",
version: "v1.0.0",
extra: []string{},
expected: "test-app/v1.0.0",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := formatUserAgent(tt.appName, tt.version, tt.extra...)
assert.Equal(t, tt.expected, result)
})
}
}

func TestIsKROManaged(t *testing.T) {
tests := []struct {
name string
labels map[string]string
expected bool
}{
{
name: "managed by kro",
labels: map[string]string{
LabelManagedBy: "kro",
},
expected: true,
},
{
name: "managed by kro with other labels",
labels: map[string]string{
"app": "myapp",
LabelManagedBy: "kro",
"env": "prod",
},
expected: true,
},
{
name: "managed by different controller",
labels: map[string]string{
LabelManagedBy: "helm",
},
expected: false,
},
{
name: "managed-by label not present",
labels: map[string]string{
"app": "myapp",
"env": "prod",
},
expected: false,
},
{
name: "nil labels",
labels: nil,
expected: false,
},
{
name: "empty labels",
labels: map[string]string{},
expected: false,
},
{
name: "legacy kro.run/owned label (backward compatibility)",
labels: map[string]string{
LabelKroOwned: "true",
},
expected: true,
},
{
name: "legacy kro.run/owned false",
labels: map[string]string{
LabelKroOwned: "false",
},
expected: false,
},
{
name: "standard label takes precedence over legacy",
labels: map[string]string{
LabelManagedBy: "kro",
LabelKroOwned: "false",
},
expected: true,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := isKROManaged(tt.labels)
assert.Equal(t, tt.expected, result)
})
}
}

func TestGetKROVersion(t *testing.T) {
tests := []struct {
name string
labels map[string]string
expected string
}{
{
name: "kro version present",
labels: map[string]string{
LabelKroVersion: "v0.1.0",
},
expected: "v0.1.0",
},
{
name: "kro version with other labels",
labels: map[string]string{
"app": "myapp",
LabelKroVersion: "v1.2.3",
"env": "prod",
},
expected: "v1.2.3",
},
{
name: "kro version not present",
labels: map[string]string{
"app": "myapp",
"env": "prod",
},
expected: "",
},
{
name: "nil labels",
labels: nil,
expected: "",
},
{
name: "empty labels",
labels: map[string]string{},
expected: "",
},
{
name: "kro version with empty value",
labels: map[string]string{
LabelKroVersion: "",
},
expected: "",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := getKROVersion(tt.labels)
assert.Equal(t, tt.expected, result)
})
}
}
3 changes: 2 additions & 1 deletion pkg/runtime/reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ func (r *resourceReconciler) Reconcile(ctx context.Context, req ctrlrt.Request)

// The config pivot to the roleARN will happen if it is not empty.
// in the NewResourceManager
clientConfig, err := r.sc.NewAWSConfig(ctx, region, &endpointURL, roleARN, gvk)
clientConfig, err := r.sc.NewAWSConfig(ctx, region, &endpointURL, roleARN, gvk, desired.MetaObject().GetLabels())
if err != nil {
return ctrlrt.Result{}, err
}
Expand Down Expand Up @@ -1173,6 +1173,7 @@ func (r *resourceReconciler) setResourceManaged(
rlog.Debug("marked resource as managed")
return nil
}

// setResourceManagedAndAdopted marks the underlying CR in the supplied AWSResource with
// a finalizer and adopted annotation that indicates the object is under ACK management and will not
// be deleted until that finalizer is removed (in setResourceUnmanaged())
Expand Down
1 change: 1 addition & 0 deletions pkg/runtime/reconciler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1813,6 +1813,7 @@ func TestReconcile_AccountDrifted(t *testing.T) {
mock.Anything,
mock.AnythingOfType("v1alpha1.AWSResourceName"),
mock.AnythingOfType("schema.GroupVersionKind"),
mock.Anything, // labels map[string]string
).Return(aws.Config{}, nil)

// Get fakeLogger
Expand Down
20 changes: 19 additions & 1 deletion pkg/runtime/tags.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,20 @@ var ACKResourceTagFormats = map[string]resolveTagFormat{
gvk := obj.GetObjectKind().GroupVersionKind()
return gvk.Kind
},

acktags.ManagedByTagFormat: func(
obj rtclient.Object,
md acktypes.ServiceControllerMetadata,
) string {
return getManagedBy(obj.GetLabels())
},

acktags.KROVersionTagFormat: func(
obj rtclient.Object,
md acktypes.ServiceControllerMetadata,
) string {
return getKROVersion(obj.GetLabels())
},
}

// GetDefaultTags provides Default tags (key value pairs) for given resource
Expand All @@ -105,7 +119,11 @@ func GetDefaultTags(
if key == "" || val == "" {
continue
}
defaultTags[key] = expandTagValue(val, obj, md)
expandedVal := expandTagValue(val, obj, md)
// Skip tags where the expanded value is empty
if expandedVal != "" {
defaultTags[key] = expandedVal
}
}
return defaultTags
}
Expand Down
10 changes: 10 additions & 0 deletions pkg/runtime/tags_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ import (
"testing"

"github.com/stretchr/testify/assert"
"k8s.io/apimachinery/pkg/runtime/schema"

mocks "github.com/aws-controllers-k8s/runtime/mocks/controller-runtime/pkg/client"
schemaMocks "github.com/aws-controllers-k8s/runtime/mocks/apimachinery/pkg/runtime/schema"
"github.com/aws-controllers-k8s/runtime/pkg/config"
acktags "github.com/aws-controllers-k8s/runtime/pkg/tags"
acktypes "github.com/aws-controllers-k8s/runtime/pkg/types"
Expand All @@ -30,6 +32,14 @@ func TestGetDefaultTags(t *testing.T) {
obj := mocks.Object{}
obj.On("GetNamespace").Return("ns")
obj.On("GetName").Return("res")
obj.On("GetLabels").Return(map[string]string{})

// Mock GetObjectKind to return a mock ObjectKind
mockObjectKind := &schemaMocks.ObjectKind{}
mockObjectKind.On("GroupVersionKind").Return(schema.GroupVersionKind{
Kind: "Table",
})
obj.On("GetObjectKind").Return(mockObjectKind)

cfg := config.Config{}

Expand Down
Loading