Skip to content

Commit 67806db

Browse files
authored
Merge branch 'main' into kms-beta
2 parents 9ca8501 + 1b5d0b2 commit 67806db

File tree

10 files changed

+288
-36
lines changed

10 files changed

+288
-36
lines changed

.github/workflows/release.yaml

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,15 @@ jobs:
4141
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
4242
passphrase: ${{ secrets.GPG_PASSPHRASE }}
4343

44+
# nfpm-rpm signing needs gpg provided as filepath
45+
# https://goreleaser.com/customization/nfpm/
46+
- name: Create GPG key file
47+
run: |
48+
KEY_PATH="$RUNNER_TEMP/gpg-private-key.asc"
49+
printf '%s' "${{ secrets.GPG_PRIVATE_KEY }}" > "$KEY_PATH"
50+
chmod 600 "$KEY_PATH"
51+
echo "GPG_KEY_PATH=$KEY_PATH" >> "$GITHUB_ENV"
52+
4453
- name: Set up keychain
4554
run: |
4655
echo -n $SIGNING_CERTIFICATE_BASE64 | base64 -d -o ./ApplicationID.p12
@@ -71,15 +80,22 @@ jobs:
7180
env:
7281
GITHUB_TOKEN: ${{ secrets.CLI_RELEASE }}
7382
GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }}
83+
GPG_KEY_PATH: ${{ env.GPG_KEY_PATH }}
84+
# nfpm-rpm signing needs this env to be set.
85+
NFPM_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
7486

75-
# artifacts need to be passed to the "publish-apt" job somehow
87+
- name: Clean up GPG key file
88+
if: always()
89+
run: |
90+
rm -f "$GPG_KEY_PATH"
91+
7692
- name: Upload artifacts to workflow
7793
uses: actions/upload-artifact@v4
7894
with:
7995
name: goreleaser-dist-temp
8096
path: dist
8197
retention-days: 1
82-
98+
8399
publish-apt:
84100
name: Publish APT
85101
runs-on: macOS-latest
@@ -115,3 +131,42 @@ jobs:
115131
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
116132
GPG_PRIVATE_KEY_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }}
117133
run: ./scripts/publish-apt-packages.sh
134+
135+
publish-rpm:
136+
name: Publish RPM
137+
runs-on: ubuntu-latest
138+
needs: [goreleaser]
139+
env:
140+
# Needed to publish new packages to our S3-hosted RPM repo
141+
AWS_ACCESS_KEY_ID: ${{ secrets.OBJECT_STORAGE_ACCESS_KEY_ID }}
142+
AWS_SECRET_ACCESS_KEY: ${{ secrets.OBJECT_STORAGE_SECRET_ACCESS_KEY }}
143+
AWS_DEFAULT_REGION: eu01
144+
AWS_ENDPOINT_URL: https://object.storage.eu01.onstackit.cloud
145+
steps:
146+
- name: Checkout
147+
uses: actions/checkout@v5
148+
149+
- name: Download artifacts from workflow
150+
uses: actions/download-artifact@v5
151+
with:
152+
name: goreleaser-dist-temp
153+
path: dist
154+
155+
- name: Install RPM tools
156+
run: |
157+
sudo apt-get update
158+
sudo apt-get install -y createrepo-c
159+
160+
- name: Import GPG key
161+
uses: crazy-max/ghaction-import-gpg@v6
162+
id: import_gpg
163+
with:
164+
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
165+
passphrase: ${{ secrets.GPG_PASSPHRASE }}
166+
167+
- name: Publish RPM packages
168+
if: contains(github.ref_name, '-') == false
169+
env:
170+
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
171+
GPG_PRIVATE_KEY_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }}
172+
run: ./scripts/publish-rpm-packages.sh

.github/workflows/renovate.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ jobs:
1313
- name: Checkout
1414
uses: actions/checkout@v5
1515
- name: Self-hosted Renovate
16-
uses: renovatebot/[email protected].16
16+
uses: renovatebot/[email protected].17
1717
with:
1818
configurationFile: .github/renovate.json
1919
token: ${{ secrets.RENOVATE_TOKEN }}

.goreleaser.yaml

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -99,17 +99,10 @@ nfpms:
9999
- deb
100100
- rpm
101101

102-
signs:
103-
- artifacts: package
104-
args:
105-
[
106-
"-u",
107-
"{{ .Env.GPG_FINGERPRINT }}",
108-
"--output",
109-
"${signature}",
110-
"--detach-sign",
111-
"${artifact}",
112-
]
102+
rpm:
103+
# The package is signed if a key_file is set
104+
signature:
105+
key_file: "{{ .Env.GPG_KEY_PATH }}"
113106

114107
homebrew_casks:
115108
- name: stackit

INSTALLATION.md

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -130,16 +130,54 @@ asset_filters=["stackit-cli_", "_linux_amd64.tar.gz"]
130130
eget stackitcloud/stackit-cli
131131
```
132132

133-
#### RPM package via dnf, yum and zypper
133+
#### RHEL/Fedora/Rocky/Alma/openSUSE/... (`DNF/YUM/Zypper`)
134134

135-
The STACKIT CLI is available as [RPM Package](https://github.com/stackitcloud/stackit-cli/releases) and can be installed via dnf, yum and zypper package manager.
135+
The STACKIT CLI can be installed through the [`DNF/YUM`](https://docs.fedoraproject.org/en-US/fedora/f40/system-administrators-guide/package-management/DNF/) / [`Zypper`](https://de.opensuse.org/Zypper) package managers.
136136

137-
Just download the rpm package from the [release page](https://github.com/stackitcloud/stackit-cli/releases) and run the install command like the following:
137+
> Requires rpm version 4.15 or newer to support Ed25519 signatures.
138+
139+
> `$basearch` is supported by modern distributions. On older systems that don't expand `$basearch`, replace it in the `baseurl` with your architecture explicitly (for example, `.../rpm/cli/x86_64` or `.../rpm/cli/aarch64`).
140+
141+
##### Installation via DNF/YUM
142+
143+
1. Add the repository:
144+
145+
```shell
146+
sudo tee /etc/yum.repos.d/stackit.repo > /dev/null << 'EOF'
147+
[stackit]
148+
name=STACKIT CLI
149+
baseurl=https://packages.stackit.cloud/rpm/cli/$basearch
150+
enabled=1
151+
gpgcheck=1
152+
gpgkey=https://packages.stackit.cloud/keys/key.gpg
153+
EOF
154+
```
155+
156+
2. Install the CLI:
157+
158+
```shell
159+
sudo dnf install stackit
160+
```
161+
162+
##### Installation via Zypper
163+
164+
1. Add the repository:
165+
166+
```shell
167+
sudo tee /etc/zypp/repos.d/stackit.repo > /dev/null << 'EOF'
168+
[stackit]
169+
name=STACKIT CLI
170+
baseurl=https://packages.stackit.cloud/rpm/cli/$basearch
171+
enabled=1
172+
gpgcheck=1
173+
gpgkey=https://packages.stackit.cloud/keys/key.gpg
174+
EOF
175+
```
176+
177+
2. Install the CLI:
138178

139179
```shell
140-
dnf install stackitcli.rpm
141-
yum install stackitcli.rpm
142-
zypper install stackitcli.rpm
180+
sudo zypper install stackit
143181
```
144182

145183
#### Any distribution

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ require (
247247
github.com/stackitcloud/stackit-sdk-go/services/logme v0.25.1
248248
github.com/stackitcloud/stackit-sdk-go/services/mariadb v0.25.1
249249
github.com/stackitcloud/stackit-sdk-go/services/objectstorage v1.4.0
250-
github.com/stackitcloud/stackit-sdk-go/services/observability v0.14.0
250+
github.com/stackitcloud/stackit-sdk-go/services/observability v0.15.0
251251
github.com/stackitcloud/stackit-sdk-go/services/rabbitmq v0.25.1
252252
github.com/stackitcloud/stackit-sdk-go/services/redis v0.25.1
253253
github.com/subosito/gotenv v1.6.0 // indirect

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -585,8 +585,8 @@ github.com/stackitcloud/stackit-sdk-go/services/mongodbflex v1.5.2 h1:BQ+qAkVS/a
585585
github.com/stackitcloud/stackit-sdk-go/services/mongodbflex v1.5.2/go.mod h1:oc8Mpwl7O6EZwG0YxfhOzNCJwNQBWK5rFh764OtxoMY=
586586
github.com/stackitcloud/stackit-sdk-go/services/objectstorage v1.4.0 h1:g3yNDUc3JydAikezUrI9bQ4nuMJpVeAQ35jOFfFmq1U=
587587
github.com/stackitcloud/stackit-sdk-go/services/objectstorage v1.4.0/go.mod h1:foslkEiICdtHR3v0A/i/Rgo6EP9MMula9XNC9luNOgw=
588-
github.com/stackitcloud/stackit-sdk-go/services/observability v0.14.0 h1:oewwaYjABWbNqDkmSwIXmjDBK4a46+tnznyZSXh3Xk0=
589-
github.com/stackitcloud/stackit-sdk-go/services/observability v0.14.0/go.mod h1:tJEOi6L0le4yQZPGwalup/PZ13gqs1aCQDqlUs2cYW0=
588+
github.com/stackitcloud/stackit-sdk-go/services/observability v0.15.0 h1:MA5i1ScjXLWe5CYeFCLHeZzNS1AH4mbx1kUyiVbxKjI=
589+
github.com/stackitcloud/stackit-sdk-go/services/observability v0.15.0/go.mod h1:tJEOi6L0le4yQZPGwalup/PZ13gqs1aCQDqlUs2cYW0=
590590
github.com/stackitcloud/stackit-sdk-go/services/opensearch v0.24.1 h1:50n87uZn0EvSP9hJGLqd3Wm2hfqbyh7BMGGCk7axgqA=
591591
github.com/stackitcloud/stackit-sdk-go/services/opensearch v0.24.1/go.mod h1:jfguuSPa56Z5Bzs/Xg/CI37XzPo5Zn5lzC5LhfuT8Qc=
592592
github.com/stackitcloud/stackit-sdk-go/services/postgresflex v1.2.1 h1:K8vXele3U6b5urcSIpq21EkVblWfPDY3eMPSuQ48TkI=

internal/pkg/services/ske/utils/utils.go

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"maps"
77
"os"
88
"path/filepath"
9+
"regexp"
910
"strconv"
1011

1112
"github.com/stackitcloud/stackit-cli/internal/pkg/utils"
@@ -16,13 +17,9 @@ import (
1617
)
1718

1819
const (
19-
defaultNodepoolAvailabilityZone = "eu01-3"
2020
defaultNodepoolCRI = ske.CRINAME_CONTAINERD
21-
defaultNodepoolMachineType = "b1.2"
2221
defaultNodepoolMachineImageName = "flatcar"
23-
defaultNodepoolMaxSurge = 1
2422
defaultNodepoolMaxUnavailable = 0
25-
defaultNodepoolMaximum = 2
2623
defaultNodepoolMinimum = 1
2724
defaultNodepoolName = "pool-default"
2825
defaultNodepoolVolumeType = "storage_premium_perf2"
@@ -110,22 +107,38 @@ func getDefaultPayloadKubernetes(resp *ske.ProviderOptions) (*ske.Kubernetes, er
110107
}
111108

112109
func getDefaultPayloadNodepool(resp *ske.ProviderOptions) (*ske.Nodepool, error) {
110+
if resp.AvailabilityZones == nil || len(*resp.AvailabilityZones) == 0 {
111+
return nil, fmt.Errorf("no availability zones found")
112+
}
113+
var availabilityZones []string
114+
for i := range *resp.AvailabilityZones {
115+
azName := (*resp.AvailabilityZones)[i].GetName()
116+
// don't include availability zones like eu01-m, eu02-m, not all flavors are available there
117+
if !regexp.MustCompile(`\w{2}\d{2}-m`).MatchString(azName) {
118+
availabilityZones = append(availabilityZones, azName)
119+
}
120+
}
121+
122+
if resp.MachineTypes == nil || len(*resp.MachineTypes) == 0 {
123+
return nil, fmt.Errorf("no machine types found")
124+
}
125+
machineType := (*resp.MachineTypes)[0].GetName()
126+
113127
output := &ske.Nodepool{
114-
AvailabilityZones: &[]string{
115-
defaultNodepoolAvailabilityZone,
116-
},
128+
AvailabilityZones: &availabilityZones,
117129
Cri: &ske.CRI{
118130
Name: utils.Ptr(defaultNodepoolCRI),
119131
},
120132
Machine: &ske.Machine{
121-
Type: utils.Ptr(defaultNodepoolMachineType),
133+
Type: &machineType,
122134
Image: &ske.Image{
123135
Name: utils.Ptr(defaultNodepoolMachineImageName),
124136
},
125137
},
126-
MaxSurge: utils.Ptr(int64(defaultNodepoolMaxSurge)),
138+
// there must be as many nodes as availability zones are given
139+
MaxSurge: utils.Ptr(int64(len(availabilityZones))),
127140
MaxUnavailable: utils.Ptr(int64(defaultNodepoolMaxUnavailable)),
128-
Maximum: utils.Ptr(int64(defaultNodepoolMaximum)),
141+
Maximum: utils.Ptr(int64(len(availabilityZones))),
129142
Minimum: utils.Ptr(int64(defaultNodepoolMinimum)),
130143
Name: utils.Ptr(defaultNodepoolName),
131144
Volume: &ske.Volume{

internal/pkg/services/ske/utils/utils_test.go

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,17 @@ func TestClusterExists(t *testing.T) {
146146

147147
func fixtureProviderOptions(mods ...func(*ske.ProviderOptions)) *ske.ProviderOptions {
148148
providerOptions := &ske.ProviderOptions{
149+
AvailabilityZones: &[]ske.AvailabilityZone{
150+
{Name: utils.Ptr("eu01-m")},
151+
{Name: utils.Ptr("eu01-1")},
152+
{Name: utils.Ptr("eu01-2")},
153+
{Name: utils.Ptr("eu01-3")},
154+
},
155+
MachineTypes: &[]ske.MachineType{
156+
{
157+
Name: utils.Ptr("b1.2"),
158+
},
159+
},
149160
KubernetesVersions: &[]ske.KubernetesVersion{
150161
{
151162
State: utils.Ptr("supported"),
@@ -263,6 +274,8 @@ func fixtureGetDefaultPayload(mods ...func(*ske.CreateOrUpdateClusterPayload)) *
263274
Nodepools: &[]ske.Nodepool{
264275
{
265276
AvailabilityZones: &[]string{
277+
"eu01-1",
278+
"eu01-2",
266279
"eu01-3",
267280
},
268281
Cri: &ske.CRI{
@@ -275,9 +288,9 @@ func fixtureGetDefaultPayload(mods ...func(*ske.CreateOrUpdateClusterPayload)) *
275288
Name: utils.Ptr("flatcar"),
276289
},
277290
},
278-
MaxSurge: utils.Ptr(int64(1)),
291+
MaxSurge: utils.Ptr(int64(3)),
279292
MaxUnavailable: utils.Ptr(int64(0)),
280-
Maximum: utils.Ptr(int64(2)),
293+
Maximum: utils.Ptr(int64(3)),
281294
Minimum: utils.Ptr(int64(1)),
282295
Name: utils.Ptr("pool-default"),
283296
Volume: &ske.Volume{
@@ -312,6 +325,34 @@ func TestGetDefaultPayload(t *testing.T) {
312325
listProviderOptionsFails: true,
313326
isValid: false,
314327
},
328+
{
329+
description: "availability zones nil",
330+
listProviderOptionsResp: fixtureProviderOptions(func(po *ske.ProviderOptions) {
331+
po.AvailabilityZones = nil
332+
}),
333+
isValid: false,
334+
},
335+
{
336+
description: "no availability zones",
337+
listProviderOptionsResp: fixtureProviderOptions(func(po *ske.ProviderOptions) {
338+
po.AvailabilityZones = &[]ske.AvailabilityZone{}
339+
}),
340+
isValid: false,
341+
},
342+
{
343+
description: "machine types nil",
344+
listProviderOptionsResp: fixtureProviderOptions(func(po *ske.ProviderOptions) {
345+
po.MachineTypes = nil
346+
}),
347+
isValid: false,
348+
},
349+
{
350+
description: "no machine types",
351+
listProviderOptionsResp: fixtureProviderOptions(func(po *ske.ProviderOptions) {
352+
po.MachineTypes = &[]ske.MachineType{}
353+
}),
354+
isValid: false,
355+
},
315356
{
316357
description: "no Kubernetes versions 1",
317358
listProviderOptionsResp: fixtureProviderOptions(func(po *ske.ProviderOptions) {

scripts/publish-apt-packages.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,4 @@ aptly snapshot pull -no-remove -architectures="amd64,i386,arm64" current-snapsho
4949

5050
# Publish the new snapshot to the remote repo
5151
printf "\n>>> Publishing updated snapshot \n"
52-
aptly publish snapshot -keyring="${CUSTOM_KEYRING_FILE}" -gpg-key="${GPG_PRIVATE_KEY_FINGERPRINT}" -passphrase "${GPG_PASSPHRASE}" -config "${APTLY_CONFIG_FILE_PATH}" updated-snapshot "s3:${APT_BUCKET_NAME}:${APT_REPO_PATH}"
52+
aptly publish snapshot -keyring="${CUSTOM_KEYRING_FILE}" -gpg-key="${GPG_PRIVATE_KEY_FINGERPRINT}" -passphrase "${GPG_PASSPHRASE}" -config "${APTLY_CONFIG_FILE_PATH}" updated-snapshot "s3:${APT_BUCKET_NAME}:${APT_REPO_PATH}"

0 commit comments

Comments
 (0)