Skip to content

Commit 16545d9

Browse files
authored
Merge branch 'main' into renovate/sigs.k8s.io-controller-runtime-0.x
2 parents b971d75 + b1499cb commit 16545d9

File tree

11 files changed

+331
-153
lines changed

11 files changed

+331
-153
lines changed

.github/workflows/ci.yaml

Lines changed: 8 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
name: ci
1+
name: CI
2+
23
on:
34
push:
45
tags:
@@ -8,33 +9,10 @@ on:
89
- main
910
pull_request:
1011

11-
jobs:
12-
build:
13-
runs-on: ubuntu-24.04
14-
15-
steps:
16-
- name: Checkout code
17-
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
18-
with:
19-
submodules: recursive
20-
21-
- name: Set up Go
22-
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5
23-
with:
24-
go-version-file: go.mod
12+
permissions:
13+
contents: read
2514

26-
- name: Install Task
27-
uses: arduino/setup-task@v2
28-
with:
29-
version: 3.42.1
30-
31-
- name: task generate
32-
run: |
33-
task generate --verbose
34-
git diff --exit-code
35-
36-
- name: task validate
37-
run: task validate --verbose
38-
39-
- name: task test
40-
run: task test --verbose
15+
jobs:
16+
build_validate_test:
17+
uses: openmcp-project/build/.github/workflows/ci.lib.yaml@main
18+
secrets: inherit

.github/workflows/release.yaml

Lines changed: 4 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -4,124 +4,12 @@ on:
44
push:
55
branches:
66
- main
7-
7+
88
permissions:
99
contents: write # we need this to be able to push tags
10+
pull-requests: read
1011

1112
jobs:
1213
release_tag:
13-
name: Release version
14-
runs-on: ubuntu-24.04
15-
steps:
16-
- name: Checkout code
17-
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
18-
with:
19-
ssh-key: ${{ secrets.PUSH_KEY }}
20-
fetch-tags: true
21-
fetch-depth: 0
22-
submodules: recursive
23-
24-
- name: Install Task
25-
uses: arduino/setup-task@v2
26-
with:
27-
version: 3.42.1
28-
29-
- name: Read and validate VERSION
30-
id: version
31-
run: |
32-
VERSION=$(task version)
33-
if [[ ! "$VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-dev(-[0-9a-f]*)?)?$ ]]; then
34-
echo "Invalid version format: $VERSION"
35-
exit 1
36-
fi
37-
echo "New version: $VERSION"
38-
echo "version=$VERSION" >> $GITHUB_ENV
39-
40-
- name: Skip release if version is a dev version
41-
if: contains(env.version, '-dev')
42-
run: |
43-
echo "Skipping development version release: ${{ env.version }}"
44-
echo "SKIP=true" >> $GITHUB_ENV
45-
exit 0
46-
47-
- name: Check if VERSION is already tagged
48-
id: check_tag
49-
run: |
50-
if git rev-parse "refs/tags/${{ env.version }}" >/dev/null 2>&1; then
51-
echo "Tag ${{ env.version }} already exists. Skipping release."
52-
echo "SKIP=true" >> $GITHUB_ENV
53-
exit 0
54-
fi
55-
echo "Tag ${{ env.version }} doesn't exists. Proceeding with release."
56-
57-
- name: Create Git tag
58-
if: ${{ env.SKIP != 'true' }}
59-
run: |
60-
AUTHOR_NAME=$(git log -1 --pretty=format:'%an')
61-
AUTHOR_EMAIL=$(git log -1 --pretty=format:'%ae')
62-
echo "Tagging as $AUTHOR_NAME <$AUTHOR_EMAIL>"
63-
64-
echo "AUTHOR_NAME=$AUTHOR_NAME" >> $GITHUB_ENV
65-
echo "AUTHOR_EMAIL=$AUTHOR_EMAIL" >> $GITHUB_ENV
66-
67-
git config user.name "$AUTHOR_NAME"
68-
git config user.email "$AUTHOR_EMAIL"
69-
70-
git tag -a "${{ env.version }}" -m "Release ${{ env.version }}"
71-
git push origin "${{ env.version }}"
72-
73-
- name: Build Changelog
74-
id: github_release
75-
uses: mikepenz/release-changelog-builder-action@e92187bd633e680ebfdd15961a7c30b2d097e7ad # v5
76-
with:
77-
mode: "PR"
78-
configurationJson: |
79-
{
80-
"template": "#{{CHANGELOG}}",
81-
"pr_template": "- #{{TITLE}}: ##{{NUMBER}}",
82-
"categories": [
83-
{
84-
"title": "## Feature",
85-
"labels": ["feat", "feature"]
86-
},
87-
{
88-
"title": "## Fix",
89-
"labels": ["fix", "bug"]
90-
},
91-
{
92-
"title": "## Other",
93-
"labels": []
94-
}
95-
],
96-
"label_extractor": [
97-
{
98-
"pattern": "^(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test){1}(\\([\\w\\-\\.]+\\))?(!)?: ([\\w ])+([\\s\\S]*)",
99-
"on_property": "title",
100-
"target": "$1"
101-
}
102-
]
103-
}
104-
env:
105-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
106-
107-
- name: Create GitHub release
108-
if: ${{ env.SKIP != 'true' }}
109-
uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631 # v2
110-
with:
111-
tag_name: ${{ env.version }}
112-
name: Release ${{ env.version }}
113-
body: "Automated release for version ${{ env.version }}"
114-
draft: false
115-
prerelease: false
116-
env:
117-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
118-
119-
- name: Push dev VERSION
120-
if: ${{ env.SKIP != 'true' }}
121-
run: |
122-
task release:set-version --verbose -- "${{ env.version }}-dev"
123-
git config user.name "${{ env.AUTHOR_NAME }}"
124-
git config user.email "${{ env.AUTHOR_EMAIL }}"
125-
git add VERSION
126-
git commit -m "Update VERSION to ${{ env.version }}-dev"
127-
git push origin main
14+
uses: openmcp-project/build/.github/workflows/release.lib.yaml@main
15+
secrets: inherit

.github/workflows/reuse.yaml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ name: REUSE Compliance Check
22

33
on: [push, pull_request]
44

5+
permissions:
6+
contents: read
7+
58
jobs:
6-
test:
7-
runs-on: ubuntu-latest
8-
steps:
9-
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
10-
- name: REUSE Compliance Check
11-
uses: fsfe/reuse-action@bb774aa972c2a89ff34781233d275075cbddf542 # v5
9+
run_reuse:
10+
uses: openmcp-project/build/.github/workflows/reuse.lib.yaml@main
11+
secrets: inherit
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
name: Validate Pull Request Content
2+
3+
on:
4+
pull_request:
5+
types:
6+
- opened
7+
- edited
8+
9+
permissions:
10+
contents: read
11+
12+
jobs:
13+
validate_pr_content:
14+
uses: openmcp-project/build/.github/workflows/validate-pr-content.lib.yaml@main
15+
secrets: inherit

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
v0.9.0-dev
1+
v0.10.0

pkg/clusteraccess/access.go

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import (
55
"fmt"
66
"time"
77

8+
"sigs.k8s.io/yaml"
9+
810
authenticationv1 "k8s.io/api/authentication/v1"
911
corev1 "k8s.io/api/core/v1"
1012
rbacv1 "k8s.io/api/rbac/v1"
@@ -341,3 +343,138 @@ func ComputeTokenRenewalTimeWithRatio(creationTime, expirationTime time.Time, ra
341343
renewalAt := creationTime.Add(renewalAfter)
342344
return renewalAt
343345
}
346+
347+
// oidcTrustConfig represents the configuration for an OIDC trust relationship.
348+
// It includes the host of the Kubernetes API server, CA data for TLS verification,
349+
// and the audience for the OIDC tokens.
350+
type oidcTrustConfig struct {
351+
// Host is the URL of the Kubernetes API server.
352+
Host string `json:"host,omitempty"`
353+
// CAData is the base64-encoded CA certificate data used to verify the server's TLS certificate.
354+
CAData []byte `json:"caData,omitempty"`
355+
}
356+
357+
// WriteOIDCConfigFromRESTConfig converts a RESTConfig to an OIDC trust configuration format.
358+
// When creating a Kubernetes deployment, this configuration is used to set up the trust relationship to
359+
// the target cluster.
360+
// Example:
361+
//
362+
// spec:
363+
//
364+
// template:
365+
// spec:
366+
// volumes:
367+
// - name: oidc-trust-config
368+
// projected:
369+
// sources:
370+
// - secret:
371+
// name: oidc-trust-config
372+
// items:
373+
// - key: host
374+
// path: cluster/host
375+
// - key: caData
376+
// path: cluster/ca.crt
377+
// - serviceAccountToken:
378+
// audience: target-cluster
379+
// path: cluster/token
380+
// expirationSeconds: 3600
381+
//
382+
// volumeMounts:
383+
// - name: oidc-trust-config
384+
// mountPath: /var/run/secrets/oidc-trust-config
385+
// readOnly: true
386+
func WriteOIDCConfigFromRESTConfig(restConfig *rest.Config) ([]byte, error) {
387+
oidcConfig := &oidcTrustConfig{
388+
Host: restConfig.Host,
389+
CAData: restConfig.CAData,
390+
}
391+
392+
configMarshaled, err := yaml.Marshal(oidcConfig)
393+
if err != nil {
394+
return nil, fmt.Errorf("failed to write OIDC trust config: %w", err)
395+
}
396+
397+
return configMarshaled, nil
398+
}
399+
400+
// WriteKubeconfigFromRESTConfig converts the RESTConfig to a kubeconfig format.
401+
// Supported authentication methods are Bearer Token, Username/Password and Client Certificate.
402+
func WriteKubeconfigFromRESTConfig(restConfig *rest.Config) ([]byte, error) {
403+
var authInfo *clientcmdapi.AuthInfo
404+
405+
id := "cluster"
406+
407+
type authType string
408+
const (
409+
authTypeBearerToken authType = "BearerToken"
410+
authTypeBasicAuth authType = "BasicAuth"
411+
authTypeClientCert authType = "ClientCert"
412+
)
413+
availableAuthTypes := make(map[authType]interface{})
414+
if restConfig.BearerToken != "" {
415+
availableAuthTypes[authTypeBearerToken] = nil
416+
}
417+
418+
if restConfig.Username != "" && restConfig.Password != "" {
419+
availableAuthTypes[authTypeBasicAuth] = nil
420+
}
421+
422+
if restConfig.CertData != nil && restConfig.KeyData != nil {
423+
availableAuthTypes[authTypeClientCert] = nil
424+
}
425+
426+
if len(availableAuthTypes) == 0 {
427+
return nil, fmt.Errorf("cannot write to kubeconfig when RESTConfig does not contain any supported authentication information")
428+
}
429+
430+
if _, ok := availableAuthTypes[authTypeBearerToken]; ok {
431+
authInfo = &clientcmdapi.AuthInfo{
432+
Token: restConfig.BearerToken,
433+
}
434+
}
435+
436+
if _, ok := availableAuthTypes[authTypeBasicAuth]; ok {
437+
authInfo = &clientcmdapi.AuthInfo{
438+
Username: restConfig.Username,
439+
Password: restConfig.Password,
440+
}
441+
}
442+
443+
if _, ok := availableAuthTypes[authTypeClientCert]; ok {
444+
authInfo = &clientcmdapi.AuthInfo{
445+
ClientCertificateData: restConfig.CertData,
446+
ClientKeyData: restConfig.KeyData,
447+
}
448+
}
449+
450+
server := restConfig.Host
451+
if restConfig.APIPath != "" {
452+
server = fmt.Sprint(server, "/", restConfig.APIPath)
453+
}
454+
455+
kubeConfig := clientcmdapi.Config{
456+
CurrentContext: id,
457+
Contexts: map[string]*clientcmdapi.Context{
458+
id: {
459+
AuthInfo: id,
460+
Cluster: id,
461+
},
462+
},
463+
Clusters: map[string]*clientcmdapi.Cluster{
464+
id: {
465+
Server: server,
466+
CertificateAuthorityData: restConfig.CAData,
467+
},
468+
},
469+
AuthInfos: map[string]*clientcmdapi.AuthInfo{
470+
id: authInfo,
471+
},
472+
}
473+
474+
configMarshaled, err := clientcmd.Write(kubeConfig)
475+
if err != nil {
476+
return nil, fmt.Errorf("failed to write RESTConfig to kubeconfig: %w", err)
477+
}
478+
479+
return configMarshaled, nil
480+
}

0 commit comments

Comments
 (0)