Skip to content

Commit c3008de

Browse files
committed
feat: automatically copy manifests for non specified provider versions
1 parent 9f6de5c commit c3008de

File tree

15 files changed

+276
-213
lines changed

15 files changed

+276
-213
lines changed

README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,29 @@ To run the test, you need to have following cli installed: `kind`, `kubectl`, [`
7878
--use-cluster-context my-cluster
7979
```
8080

81+
### Auto-Copy Feature for New Versions
82+
83+
When testing upgrades from a provider version that doesn't have test manifests yet, the tool automatically helps by copying manifests from the latest available version that is lower than your specified source version.
84+
85+
**How it works:**
86+
1. If the specified `--source-dir` doesn't exist, the tool checks if the Docker image exists in the registry
87+
2. If the image exists, it finds the latest known version lower than your source version
88+
3. Copies the test manifests from that version to your specified version
89+
4. Displays: *"Could not be found - copying manifests from latest known version and applying them to this version"*
90+
5. Continues with the upgrade test
91+
92+
**Example:**
93+
```bash
94+
# Testing upgrade from v1.0.5 (source) to v1.1.0 (newly released target)
95+
# where v1.0.5 doesn't have manifests yet
96+
./provider-test.sh upgrade-test \
97+
--source crossplane/provider-btp:v1.0.5 \
98+
--target crossplane/provider-btp:v1.1.0 \
99+
--source-dir provider-btp/v1.0.5
100+
```
101+
102+
This feature unblocks testing when you need to upgrade from a version that doesn't have manifests, allowing you to test the upgrade path to newly released versions.
103+
81104
## Development
82105
Understanding the details of the tool is beneficial to developers.
83106

functions.sh

Lines changed: 114 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,82 @@ PURPLE='\033[0;35m'
99
NC='\033[0m' # No Color (reset)
1010

1111

12+
# Check if a Docker image exists in a registry
13+
check_docker_image_exists() {
14+
local registry_url=$1
15+
print_color_message ${BLUE} "Checking if image exists: $registry_url"
16+
17+
# For private registries, we might need authentication
18+
# Try to check if we need to login first (for ghcr.io or other private registries)
19+
if [[ "$registry_url" == *"ghcr.io"* ]] && [ -n "$GITHUB_TOKEN" ]; then
20+
echo "$GITHUB_TOKEN" | docker login ghcr.io -u "$GITHUB_USERNAME" --password-stdin >/dev/null 2>&1
21+
fi
22+
23+
# Use docker manifest inspect to check if image exists
24+
# Suppress error output but capture return code
25+
if docker manifest inspect "$registry_url" >/dev/null 2>&1; then
26+
print_color_message ${GREEN} "✓ Image exists: $registry_url"
27+
return 0 # Image exists
28+
else
29+
print_color_message ${YELLOW} "✗ Image not found: $registry_url"
30+
return 1 # Image does not exist
31+
fi
32+
}
33+
34+
# Find the latest known version directory for a provider that is lower than the specified version
35+
find_latest_known_version() {
36+
local provider_name=$1
37+
local target_version=$2
38+
local provider_dir="./providers/$provider_name"
39+
40+
if [ ! -d "$provider_dir" ]; then
41+
return 1
42+
fi
43+
44+
# Find all version directories, filter those lower than target, and get the highest one
45+
local latest_lower_version=""
46+
for version_dir in "$provider_dir"/*/; do
47+
if [ -d "$version_dir" ]; then
48+
local version=$(basename "$version_dir")
49+
50+
# Compare versions: check if current version is lower than target version
51+
if printf '%s\n%s\n' "$version" "$target_version" | sort -V | head -n1 | grep -q "^$version$" && [ "$version" != "$target_version" ]; then
52+
# This version is lower than target version
53+
if [ -z "$latest_lower_version" ]; then
54+
latest_lower_version="$version"
55+
else
56+
# Check if this version is higher than our current latest_lower_version
57+
if printf '%s\n%s\n' "$latest_lower_version" "$version" | sort -V | tail -n1 | grep -q "^$version$"; then
58+
latest_lower_version="$version"
59+
fi
60+
fi
61+
fi
62+
fi
63+
done
64+
65+
echo "$latest_lower_version"
66+
}
67+
68+
# Copy manifests from latest known version to a new version directory
69+
copy_manifests_from_latest() {
70+
local provider_name=$1
71+
local target_version=$2
72+
local latest_version=$3
73+
74+
local source_path="./providers/$provider_name/$latest_version"
75+
local target_path="./providers/$provider_name/$target_version"
76+
77+
print_color_message ${YELLOW} "Copying manifests from latest known version $latest_version to $target_version..."
78+
79+
# Create target directory
80+
mkdir -p "$target_path"
81+
82+
# Copy all files from latest version
83+
cp -r "$source_path"/* "$target_path/"
84+
85+
print_color_message ${GREEN} "Successfully copied manifests from $latest_version to $target_version"
86+
}
87+
1288
check_resource_status() {
1389
local api_version=$1
1490
local kind=$2
@@ -124,6 +200,7 @@ check_required_command_exists() {
124200
command -v sed >/dev/null 2>&1 || { echo >&2 "sed is not installed. Aborting."; exit 1; }
125201
command -v yq >/dev/null 2>&1 || { echo >&2 "yq is not installed. Aborting."; exit 1; }
126202
command -v jq >/dev/null 2>&1 || { echo >&2 "jq is not installed. Aborting."; exit 1; }
203+
command -v docker >/dev/null 2>&1 || { echo >&2 "docker is not installed. Aborting."; exit 1; }
127204

128205
}
129206

@@ -252,9 +329,39 @@ exec_params_check() {
252329
exit 1
253330
fi
254331

332+
# Check if source directory exists
255333
if [ ! -d "./providers/$SOURCE_DIR" ] || [ ! -f "./providers/$SOURCE_DIR/chainsaw-test.yaml" ]; then
256-
print_color_message ${RED} "Error: couldn't find test resource under source-dir: $SOURCE_DIR."
257-
exit 1
334+
print_color_message ${YELLOW} "Warning: Couldn't find test resource under source-dir: $SOURCE_DIR."
335+
336+
# Extract provider name and version from SOURCE_DIR (e.g., provider-btp/v1.0.5)
337+
local provider_name=$(dirname "$SOURCE_DIR")
338+
local requested_version=$(basename "$SOURCE_DIR")
339+
340+
print_color_message ${BLUE} "Checking if Docker image exists for version $requested_version..."
341+
342+
# Check if the Docker image exists in the registry
343+
if check_docker_image_exists "$SOURCE_REGISTRY"; then
344+
print_color_message ${GREEN} "Docker image found: $SOURCE_REGISTRY"
345+
346+
# Find the latest known version that is lower than the requested version
347+
local latest_version=$(find_latest_known_version "$provider_name" "$requested_version")
348+
349+
if [ -n "$latest_version" ]; then
350+
print_color_message ${YELLOW} "Could not be found - copying manifests from latest known version ($latest_version) and applying them to this version."
351+
352+
# Copy manifests from latest version
353+
copy_manifests_from_latest "$provider_name" "$requested_version" "$latest_version"
354+
355+
print_color_message ${GREEN} "Manifests copied successfully. Continuing with upgrade test."
356+
else
357+
print_color_message ${RED} "Error: No known versions found for provider $provider_name that are lower than $requested_version to copy manifests from."
358+
exit 1
359+
fi
360+
else
361+
print_color_message ${RED} "Error: Docker image $SOURCE_REGISTRY does not exist in registry."
362+
print_color_message ${RED} "Error: Cannot proceed without valid source version."
363+
exit 1
364+
fi
258365
fi
259366
}
260367

@@ -278,13 +385,18 @@ print_help ()
278385
printf '\t%s\n' "--source: source version provider docker registry with tag (required)"
279386
printf '\t%s\n' "--target: target version provider docker registry with tag (required)"
280387
printf '\t%s\n' "--source-dir: source provider CR test directory relative to providers (required)"
388+
printf '\t%s\n' " Note: If the specified source-dir doesn't exist, but the Docker image"
389+
printf '\t%s\n' " exists in the registry, manifests will be automatically copied from"
390+
printf '\t%s\n' " the latest known version to enable testing of new versions."
281391
printf '\t%s\n' "--provider: which provider to test (default: provider-btp)"
282392
printf '\t%s\n' "--use-cluster-context: do not create k8s cluster, instead use existing cluster context"
283393
printf '\t%s\n' "--wait-user-input: prompt for user input within test steps"
284394
printf '\t%s\n' "--skip-crossplane-install: skip installing crossplane in k8s cluster"
285395
printf '\t%s\n' "-h,--help: Prints help"
286396
printf '\n%s\n' "Example:"
287397
printf '\t%s\n' "./provider-test.sh upgrade-test --source crossplane/provider-btp:v1.0.3 --target crossplane/provider-btp:v1.1.0 --source-dir provider-btp/v1.0.3"
398+
printf '\n%s\n' "Auto-copy example (if v1.0.5 manifests don't exist but Docker image does):"
399+
printf '\t%s\n' "./provider-test.sh upgrade-test --source crossplane/provider-btp:v1.0.5 --target crossplane/provider-btp:v1.1.0 --source-dir provider-btp/v1.0.5"
288400
}
289401

290402
print_test_steps_summary() {

providers/provider-btp/v1.1.0/chainsaw-test.yaml

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ spec:
99
cleanup: 120s
1010
steps:
1111
- timeouts:
12-
assert: 180s
12+
assert: 300s
1313
try:
1414
- apply:
15-
file: ../v1.0.3/crs/subaccount.yaml
15+
file: crs/subaccount.yaml
1616
- assert:
1717
resource:
1818
apiVersion: account.btp.sap.crossplane.io/v1alpha1
@@ -28,7 +28,7 @@ spec:
2828
assert: 120s
2929
try:
3030
- apply:
31-
file: ../v1.0.3/crs/cis-entitlement.yaml
31+
file: crs/cis-entitlement.yaml
3232
- assert:
3333
resource:
3434
apiVersion: account.btp.sap.crossplane.io/v1alpha1
@@ -44,7 +44,7 @@ spec:
4444
assert: 120s
4545
try:
4646
- apply:
47-
file: ../v1.0.3/crs/kyma-entitlement.yaml
47+
file: crs/kyma-entitlement.yaml
4848
- assert:
4949
resource:
5050
apiVersion: account.btp.sap.crossplane.io/v1alpha1
@@ -57,10 +57,10 @@ spec:
5757
(conditions[?type == 'Synced']):
5858
- status: 'True'
5959
- timeouts:
60-
assert: 480s
60+
assert: 120s
6161
try:
6262
- apply:
63-
file: ../v1.0.3/crs/service-manager.yaml
63+
file: crs/service-manager.yaml
6464
- assert:
6565
resource:
6666
apiVersion: account.btp.sap.crossplane.io/v1beta1
@@ -76,7 +76,7 @@ spec:
7676
assert: 480s
7777
try:
7878
- apply:
79-
file: ../v1.0.3/crs/cis-local.yaml
79+
file: crs/cis-local.yaml
8080
- assert:
8181
resource:
8282
apiVersion: account.btp.sap.crossplane.io/v1alpha1
@@ -92,7 +92,7 @@ spec:
9292
assert: 180s
9393
try:
9494
- apply:
95-
file: ../v1.0.3/crs/cloudfoundry-env.yaml
95+
file: crs/cloudfoundry-env.yaml
9696
- assert:
9797
resource:
9898
apiVersion: environment.btp.sap.crossplane.io/v1alpha1
@@ -108,7 +108,7 @@ spec:
108108
assert: 180s
109109
try:
110110
- apply:
111-
file: ../v1.0.3/crs/subscription.yaml
111+
file: crs/subscription.yaml
112112
- assert:
113113
resource:
114114
apiVersion: account.btp.sap.crossplane.io/v1alpha1
@@ -124,7 +124,7 @@ spec:
124124
assert: 1800s
125125
try:
126126
- apply:
127-
file: ../v1.0.3/crs/kyma-env.yaml
127+
file: crs/kyma-env.yaml
128128
- assert:
129129
resource:
130130
apiVersion: environment.btp.sap.crossplane.io/v1alpha1
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
apiVersion: account.btp.sap.crossplane.io/v1alpha1
2+
kind: Entitlement
3+
metadata:
4+
name: cis-entitlement
5+
spec:
6+
forProvider:
7+
serviceName: cis
8+
servicePlanName: local
9+
enable: true
10+
subaccountRef:
11+
name: upgrade-test-subaccount
12+
providerConfigRef:
13+
name: account-provider-config
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
apiVersion: account.btp.sap.crossplane.io/v1alpha1
2+
kind: CloudManagement
3+
metadata:
4+
name: my-cis
5+
spec:
6+
writeConnectionSecretToRef:
7+
name: my-cis
8+
namespace: default
9+
forProvider:
10+
serviceManagerRef:
11+
name: upgrade-test-subaccount-service-manager
12+
subaccountRef:
13+
name: upgrade-test-subaccount
14+
providerConfigRef:
15+
name: account-provider-config

providers/provider-btp/v1.1.0/crs/cloudfoundry-env.yaml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,11 @@ metadata:
55
spec:
66
forProvider:
77
initialOrgManagers:
8-
- $TECHNICAL_USER_EMAIL
9-
landscape: cf-eu10
10-
orgName: dummy-org
8+
- INJECT_ENV.TECHNICAL_USER_EMAIL
9+
landscape: cf-eu20
1110
cloudManagementRef:
1211
name: my-cis
1312
subaccountRef:
1413
name: upgrade-test-subaccount
1514
providerConfigRef:
1615
name: account-provider-config
17-
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
apiVersion: account.btp.sap.crossplane.io/v1alpha1
2+
kind: Directory
3+
metadata:
4+
name: my-directory
5+
spec:
6+
forProvider:
7+
description: test dir
8+
directoryAdmins:
9+
- INJECT_ENV.TECHNICAL_USER_EMAIL
10+
- INJECT_ENV.SECOND_DIRECTORY_ADMIN_EMAIL
11+
displayName: upgrade test directory
12+
providerConfigRef:
13+
name: account-provider-config
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
apiVersion: account.btp.sap.crossplane.io/v1alpha1
2+
kind: Entitlement
3+
metadata:
4+
name: kyma-entitlement
5+
spec:
6+
forProvider:
7+
serviceName: kymaruntime
8+
servicePlanName: azure
9+
amount: 1
10+
subaccountRef:
11+
name: upgrade-test-subaccount
12+
providerConfigRef:
13+
name: account-provider-config
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
apiVersion: environment.btp.sap.crossplane.io/v1alpha1
2+
kind: KymaEnvironment
3+
metadata:
4+
name: my-kyma-env
5+
spec:
6+
cloudManagementRef:
7+
name: my-cis
8+
forProvider:
9+
parameters:
10+
region: westeurope
11+
planName: azure
12+
providerConfigRef:
13+
name: account-provider-config
14+
subaccountRef:
15+
name: upgrade-test-subaccount
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
apiVersion: account.btp.sap.crossplane.io/v1beta1
2+
kind: ServiceManager
3+
metadata:
4+
name: upgrade-test-subaccount-service-manager
5+
namespace: default
6+
spec:
7+
writeConnectionSecretToRef:
8+
name: upgrade-test-subaccount-service-manager
9+
namespace: default
10+
forProvider:
11+
subaccountRef:
12+
name: upgrade-test-subaccount
13+
providerConfigRef:
14+
name: account-provider-config

0 commit comments

Comments
 (0)