Merge pull request #3 from ysoftdevs/feature/token-requestor

Feature/token requestor
This commit is contained in:
salatamartin
2022-11-03 14:35:39 +01:00
committed by GitHub
48 changed files with 651 additions and 169 deletions

View File

@@ -2,11 +2,7 @@ version: 2
jobs:
build:
docker: # run the steps with Docker
- image: circleci/golang:1.15
auth:
username: javamachr
password: $DOCKERHUB_PASSWORD
- image: circleci/golang:1.17
steps:
- checkout # check out source code to working directory
@@ -18,14 +14,6 @@ jobs:
keys:
- go-mod-v4-{{ checksum "go.sum" }}
- run:
name: Install requirements
command: make install-requirements
- run:
name: Generate sources
command: make generate
- run:
name: Docker login
command: make docker-login
@@ -34,10 +22,6 @@ jobs:
name: Build docker images
command: make docker-images
- run:
name: Build docker images
command: make docker-images
- run:
name: Push docker images
command: make docker-push

View File

@@ -14,7 +14,7 @@
EXTENSION_PREFIX := gardener-extension
NAME := shoot-fleet-agent
REGISTRY := javamachr
REGISTRY := ysoftglobal.azurecr.io
IMAGE_PREFIX := $(REGISTRY)/gardener-extension
REPO_ROOT := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
HACK_DIR := $(REPO_ROOT)/hack
@@ -49,7 +49,7 @@ install:
.PHONY: docker-login
docker-login:
echo ${DOCKER_PASS} | docker login -u ${DOCKER_USER} --password-stdin
@echo "$$DOCKER_PASSWORD" | docker login -u "${DOCKER_USER}" --password-stdin "${REGISTRY}"
.PHONY: docker-images
docker-images:
@@ -65,7 +65,7 @@ docker-push:
.PHONY: containerd-login
containerd-login:
@echo "$(DOCKER_PASS)" | nerdctl login -u "$(DOCKER_USER)" --password-stdin
@echo "$$DOCKER_PASSWORD" | nerdctl login -u "${DOCKER_USER}" --password-stdin "${REGISTRY}"
.PHONY: containerd-images
containerd-images:
@@ -100,7 +100,7 @@ revendor:
@GO111MODULE=on go mod vendor
@GO111MODULE=on go mod tidy
@chmod +x $(REPO_ROOT)/vendor/github.com/gardener/gardener/hack/*
@chmod +x $(REPO_ROOT)/vendor/github. com/gardener/gardener/hack/.ci/*
@chmod +x $(REPO_ROOT)/vendor/github.com/gardener/gardener/hack/.ci/*
@$(REPO_ROOT)/hack/update-github-templates.sh
.PHONY: clean
@@ -121,6 +121,11 @@ check:
generate:
@$(REPO_ROOT)/vendor/github.com/gardener/gardener/hack/generate.sh ./charts/... ./cmd/... ./pkg/... ./test/...
@rm -rf ./pkg/client/fleet/clientset/internalversion;
.PHONY: generate-charts
generate-charts:
@$(REPO_ROOT)/vendor/github.com/gardener/gardener/hack/generate.sh ./charts/...
.PHONY: format
format:
@$(REPO_ROOT)/vendor/github.com/gardener/gardener/hack/format.sh ./cmd ./pkg ./test

View File

@@ -3,7 +3,7 @@
[![CircleCI](https://circleci.com/gh/javamachr/gardener-extension-shoot-fleet-agent.svg?style=shield)](https://circleci.com/gh/javamachr/gardener-extension-shoot-fleet-agent)
[![Go Report Card](https://goreportcard.com/badge/github.com/javamachr/gardener-extension-shoot-fleet-agent)](https://goreportcard.com/report/github.com/javamachr/gardener-extension-shoot-fleet-agent)
[![Go Report Card](https://goreportcard.com/badge/github.com/ysoftdevs/gardener-extension-shoot-fleet-agent)](https://goreportcard.com/report/github.com/ysoftdevs/gardener-extension-shoot-fleet-agent)
Project Gardener implements the automated management and operation of [Kubernetes](https://kubernetes.io/) clusters as a service. Its main principle is to leverage Kubernetes concepts for all of its tasks.
@@ -76,7 +76,7 @@ Static code checks and tests can be executed by running `VERIFY=true make all`.
## Feedback and Support
Feedback and contributions are always welcome. Please report bugs or suggestions as [GitHub issues](https://github.com/javamachr/gardener-extension-shoot-fleet-agent/issues) or join our [Slack channel #gardener](https://kubernetes.slack.com/messages/gardener) (please invite yourself to the Kubernetes workspace [here](http://slack.k8s.io)).
Feedback and contributions are always welcome. Please report bugs or suggestions as [GitHub issues](https://github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/issues) or join our [Slack channel #gardener](https://kubernetes.slack.com/messages/gardener) (please invite yourself to the Kubernetes workspace [here](http://slack.k8s.io)).
## Learn more!

View File

@@ -1 +1 @@
v1.0.1-DEV
v1.0.6-DEV

View File

@@ -2,4 +2,4 @@ apiVersion: v1
appVersion: "1.0"
description: A Helm chart for the Gardener Shoot Fleet Agent extension.
name: gardener-extension-shoot-fleet-agent
version: 0.1.0
version: 0.3.5

View File

@@ -12,10 +12,17 @@ rules:
- extensions.gardener.cloud
resources:
- clusters
- dnsrecords
verbs:
- get
- list
- watch
- apiGroups:
- resources.gardener.cloud
resources:
- managedresources
verbs:
- "*"
- apiGroups:
- extensions.gardener.cloud
resources:

View File

@@ -1,5 +1,5 @@
image:
repository: javamachr/gardener-extension-shoot-fleet-agent
repository: ysoftglobal.azurecr.io/gardener-extension-shoot-fleet-agent
tag: latest
pullPolicy: Always

View File

@@ -0,0 +1,4 @@
apiVersion: v1
description: A Helm chart for shoot-fleet-agent-shoot
name: shoot-fleet-agent-shoot
version: 0.1.0

View File

@@ -0,0 +1,35 @@
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: extensions.gardener.cloud:extension-shoot-fleet-agent:shoot
labels:
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
rules:
- apiGroups:
- '*'
resources:
- '*'
verbs:
- '*'
- nonResourceURLs:
- '*'
verbs:
- '*'
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: extensions.gardener.cloud:extension-shoot-fleet-agent:shoot
labels:
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: extensions.gardener.cloud:extension-shoot-fleet-agent:shoot
subjects:
- kind: ServiceAccount
name: {{ .Values.shootAccessServiceAccountName }}
namespace: {{ .Values.shootAccessServiceAccountNamespace }}

View File

@@ -0,0 +1,2 @@
shootAccessServiceAccountName: ""
shootAccessServiceAccountNamespace: kube-system

View File

@@ -18,8 +18,8 @@ import (
"context"
"fmt"
"github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/controller"
"github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/controller/healthcheck"
"github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/controller"
"github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/controller/healthcheck"
extensionscontroller "github.com/gardener/gardener/extensions/pkg/controller"
"github.com/gardener/gardener/extensions/pkg/util"

View File

@@ -17,7 +17,7 @@ package app
import (
"os"
fleetagentservicecmd "github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/cmd"
fleetagentservicecmd "github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/cmd"
controllercmd "github.com/gardener/gardener/extensions/pkg/controller/cmd"
)

View File

@@ -15,7 +15,7 @@
package main
import (
"github.com/javamachr/gardener-extension-shoot-fleet-agent/cmd/gardener-extension-shoot-fleet-agent/app"
"github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/cmd/gardener-extension-shoot-fleet-agent/app"
"os"
"github.com/gardener/gardener/pkg/logger"

View File

@@ -12,7 +12,7 @@ To let the `shoot-fleet-agent` operate properly, you need to have:
- have kubeconfig with read/write access to cluster.fleet.cattle.io and secret resrouces in some namespace
### ControllerRegistration
An example of a `ControllerRegistration` for the `shoot-fleet-agent` can be found here: https://github.com/javamachr/gardener-extension-shoot-fleet-agent/blob/master/example/controller-registration.yaml
An example of a `ControllerRegistration` for the `shoot-fleet-agent` can be found here: https://github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/blob/master/example/controller-registration.yaml
### Configuration
The `ControllerRegistration` contains a Helm chart which eventually deploy the `shoot-fleet-agent` to seed clusters.

View File

@@ -1,20 +1,28 @@
---
apiVersion: core.gardener.cloud/v1beta1
kind: ControllerDeployment
metadata:
name: extension-shoot-fleet-agent
type: helm
providerConfig:
chart: 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
values:
image:
tag: v1.0.6-DEV
fleetManager:
kubeconfig: #base64 encoded kubeconfig of Fleet manager cluster with user that has write access to Cluster and Secret
namespace: clusters
---
apiVersion: core.gardener.cloud/v1beta1
kind: ControllerRegistration
metadata:
name: extension-shoot-fleet-agent
spec:
deployment:
deploymentRefs:
- name: extension-shoot-fleet-agent
resources:
- kind: Extension
type: shoot-fleet-agent
globallyEnabled: true
deployment:
type: helm
providerConfig:
chart: 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
values:
image:
tag: v1.0.1-DEV
fleetManager:
kubeconfig: #base64 encoded kubeconfig of Fleet manager cluster with user that has write access to Cluster and Secret
namespace: clusters
primary: true

6
go.mod
View File

@@ -1,4 +1,4 @@
module github.com/javamachr/gardener-extension-shoot-fleet-agent
module github.com/ysoftdevs/gardener-extension-shoot-fleet-agent
go 1.17
@@ -9,6 +9,7 @@ require (
github.com/gobuffalo/packr/v2 v2.8.3
github.com/golang/mock v1.6.0
github.com/onsi/ginkgo v1.16.5
github.com/pkg/errors v0.9.1
github.com/rancher/fleet/pkg/apis v0.0.0-20220601092642-d45a36738d27
github.com/spf13/cobra v1.4.0
github.com/spf13/pflag v1.0.5
@@ -18,6 +19,7 @@ require (
k8s.io/code-generator v0.24.0
k8s.io/component-base v0.24.0
sigs.k8s.io/controller-runtime v0.11.2
sigs.k8s.io/yaml v1.3.0
)
require (
@@ -80,7 +82,6 @@ require (
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/nxadm/tail v1.4.8 // indirect
github.com/onsi/ginkgo/v2 v2.1.4 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/prometheus/client_golang v1.12.1 // indirect
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.32.1 // indirect
@@ -130,7 +131,6 @@ require (
sigs.k8s.io/controller-tools v0.8.0 // indirect
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect
sigs.k8s.io/yaml v1.3.0 // indirect
)
replace (

View File

@@ -60,7 +60,7 @@ ProjectConfig
<code>projectConfig</code></br>
<em>
<a href="#shoot-fleet-agent-service.extensions.config.gardener.cloud/v1alpha1.ProjectConfig">
map[string]github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/apis/config/v1alpha1.ProjectConfig
map[string]github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/apis/config/v1alpha1.ProjectConfig
</a>
</em>
</td>

View File

@@ -37,7 +37,9 @@ EOM
if [ "$1" == "--optional" ]; then
shift
MODE=$'\n globallyEnabled: false'
GLOBALLY_ENABLED='false'
else
GLOBALLY_ENABLED='true'
fi
NAME="$1"
CHART_DIR="$2"
@@ -67,7 +69,7 @@ trap cleanup EXIT ERR INT TERM
export HELM_HOME="$temp_helm_home"
[ "$(helm version --client --template "{{.Version}}" | head -c2 | tail -c1)" = "3" ] || helm init --client-only > /dev/null 2>&1
helm package "$CHART_DIR" --version "$VERSION" --app-version "$VERSION" --destination "$temp_dir" > /dev/null
helm package "$CHART_DIR" --app-version "$VERSION" --destination "$temp_dir" > /dev/null
tar -xzm -C "$temp_extract_dir" -f "$temp_dir"/*
chart="$(tar --sort=name -c --owner=root:0 --group=root:0 --mtime='UTC 2019-01-01' -C "$temp_extract_dir" "$(basename "$temp_extract_dir"/*)" | gzip -n | base64 | tr -d '\n')"
@@ -76,10 +78,27 @@ mkdir -p "$(dirname "$DEST")"
cat <<EOM > "$DEST"
---
apiVersion: core.gardener.cloud/v1beta1
kind: ControllerDeployment
metadata:
name: $NAME
type: helm
providerConfig:
chart: $chart
values:
image:
tag: $VERSION
fleetManager:
kubeconfig: #base64 encoded kubeconfig of Fleet manager cluster with user that has write access to Cluster and Secret
namespace: clusters
---
apiVersion: core.gardener.cloud/v1beta1
kind: ControllerRegistration
metadata:
name: $NAME
spec:
deployment:
deploymentRefs:
- name: $NAME
resources:
EOM
@@ -88,22 +107,11 @@ for kind_and_type in "${KINDS_AND_TYPES[@]}"; do
TYPE="$(echo "$kind_and_type" | cut -d ':' -f 2)"
cat <<EOM >> "$DEST"
- kind: $KIND
type: $TYPE$MODE
globallyEnabled: true
type: $TYPE
globallyEnabled: $GLOBALLY_ENABLED
primary: true
EOM
done
cat <<EOM >> "$DEST"
deployment:
type: helm
providerConfig:
chart: $chart
values:
image:
tag: $VERSION
fleetManager:
kubeconfig: #base64 encoded kubeconfig of Fleet manager cluster with user that has write access to Cluster and Secret
namespace: clusters
EOM
echo "Successfully generated controller registration at $DEST"

View File

@@ -24,24 +24,24 @@ PROJECT_ROOT=$(dirname $0)/..
bash "${PROJECT_ROOT}"/vendor/k8s.io/code-generator/generate-internal-groups.sh \
deepcopy,defaulter \
github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/client/componentconfig \
github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/apis \
github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/apis \
github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/client/componentconfig \
github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/apis \
github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/apis \
"config:v1alpha1" \
--go-header-file "${PROJECT_ROOT}/vendor/github.com/gardener/gardener/hack/LICENSE_BOILERPLATE.txt"
bash "${PROJECT_ROOT}"/vendor/k8s.io/code-generator/generate-internal-groups.sh \
conversion \
github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/client/componentconfig \
github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/apis \
github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/apis \
github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/client/componentconfig \
github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/apis \
github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/apis \
"config:v1alpha1" \
--extra-peer-dirs=github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/apis/config,github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/apis/config/v1alpha1,k8s.io/apimachinery/pkg/apis/meta/v1,k8s.io/apimachinery/pkg/conversion,k8s.io/apimachinery/pkg/runtime, github.com/gardener/gardener/extensions/pkg/controller/healthcheck/config/v1alpha1 \
--extra-peer-dirs=github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/apis/config,github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/apis/config/v1alpha1,k8s.io/apimachinery/pkg/apis/meta/v1,k8s.io/apimachinery/pkg/conversion,k8s.io/apimachinery/pkg/runtime, github.com/gardener/gardener/extensions/pkg/controller/healthcheck/config/v1alpha1 \
--go-header-file "${PROJECT_ROOT}/vendor/github.com/gardener/gardener/hack/LICENSE_BOILERPLATE.txt"
bash "${PROJECT_ROOT}"/vendor/k8s.io/code-generator/generate-internal-groups.sh \
conversion,client \
github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/client/fleet \
github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/client/fleet \
github.com/rancher/fleet/pkg/apis \
github.com/rancher/fleet/pkg/apis \
"fleet.cattle.io:v1alpha1" \

View File

@@ -1,9 +1,9 @@
package install
import (
"github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/apis/config"
v1alpha1 "github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/apis/config/v1alpha1"
v1alpha1fleet "github.com/rancher/fleet/pkg/apis/fleet.cattle.io/v1alpha1"
"github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/apis/config"
v1alpha1 "github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/apis/config/v1alpha1"
"k8s.io/apimachinery/pkg/runtime"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"

View File

@@ -3,8 +3,8 @@ package loader
import (
"io/ioutil"
"github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/apis/config"
"github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/apis/config/install"
"github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/apis/config"
"github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/apis/config/install"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"

View File

@@ -1,5 +1,5 @@
// +k8s:deepcopy-gen=package
// +k8s:conversion-gen=github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/apis/config
// +k8s:conversion-gen=github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/apis/config
// +k8s:openapi-gen=true
// +k8s:defaulter-gen=TypeMeta

View File

@@ -1,3 +1,4 @@
//go:build !ignore_autogenerated
// +build !ignore_autogenerated
/*
@@ -24,7 +25,7 @@ import (
unsafe "unsafe"
healthcheckconfig "github.com/gardener/gardener/extensions/pkg/controller/healthcheck/config"
config "github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/apis/config"
config "github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/apis/config"
conversion "k8s.io/apimachinery/pkg/conversion"
runtime "k8s.io/apimachinery/pkg/runtime"
)

View File

@@ -1,7 +1,8 @@
//go:build !ignore_autogenerated
// +build !ignore_autogenerated
/*
Copyright (c) 2021 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
Copyright (c) SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1,7 +1,8 @@
//go:build !ignore_autogenerated
// +build !ignore_autogenerated
/*
Copyright (c) 2021 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
Copyright (c) SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -21,7 +21,7 @@ package versioned
import (
"fmt"
fleetv1alpha1 "github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/client/fleet/clientset/versioned/typed/fleet.cattle.io/v1alpha1"
fleetv1alpha1 "github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/client/fleet/clientset/versioned/typed/fleet.cattle.io/v1alpha1"
discovery "k8s.io/client-go/discovery"
rest "k8s.io/client-go/rest"
flowcontrol "k8s.io/client-go/util/flowcontrol"

View File

@@ -19,9 +19,9 @@ limitations under the License.
package fake
import (
clientset "github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/client/fleet/clientset/versioned"
fleetv1alpha1 "github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/client/fleet/clientset/versioned/typed/fleet.cattle.io/v1alpha1"
fakefleetv1alpha1 "github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/client/fleet/clientset/versioned/typed/fleet.cattle.io/v1alpha1/fake"
clientset "github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/client/fleet/clientset/versioned"
fleetv1alpha1 "github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/client/fleet/clientset/versioned/typed/fleet.cattle.io/v1alpha1"
fakefleetv1alpha1 "github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/client/fleet/clientset/versioned/typed/fleet.cattle.io/v1alpha1/fake"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/discovery"

View File

@@ -22,8 +22,8 @@ import (
"context"
"time"
scheme "github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/client/fleet/clientset/versioned/scheme"
v1alpha1 "github.com/rancher/fleet/pkg/apis/fleet.cattle.io/v1alpha1"
scheme "github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/client/fleet/clientset/versioned/scheme"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"

View File

@@ -22,8 +22,8 @@ import (
"context"
"time"
scheme "github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/client/fleet/clientset/versioned/scheme"
v1alpha1 "github.com/rancher/fleet/pkg/apis/fleet.cattle.io/v1alpha1"
scheme "github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/client/fleet/clientset/versioned/scheme"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"

View File

@@ -22,8 +22,8 @@ import (
"context"
"time"
scheme "github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/client/fleet/clientset/versioned/scheme"
v1alpha1 "github.com/rancher/fleet/pkg/apis/fleet.cattle.io/v1alpha1"
scheme "github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/client/fleet/clientset/versioned/scheme"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"

View File

@@ -22,8 +22,8 @@ import (
"context"
"time"
scheme "github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/client/fleet/clientset/versioned/scheme"
v1alpha1 "github.com/rancher/fleet/pkg/apis/fleet.cattle.io/v1alpha1"
scheme "github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/client/fleet/clientset/versioned/scheme"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"

View File

@@ -22,8 +22,8 @@ import (
"context"
"time"
scheme "github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/client/fleet/clientset/versioned/scheme"
v1alpha1 "github.com/rancher/fleet/pkg/apis/fleet.cattle.io/v1alpha1"
scheme "github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/client/fleet/clientset/versioned/scheme"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"

View File

@@ -22,8 +22,8 @@ import (
"context"
"time"
scheme "github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/client/fleet/clientset/versioned/scheme"
v1alpha1 "github.com/rancher/fleet/pkg/apis/fleet.cattle.io/v1alpha1"
scheme "github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/client/fleet/clientset/versioned/scheme"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"

View File

@@ -22,8 +22,8 @@ import (
"context"
"time"
scheme "github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/client/fleet/clientset/versioned/scheme"
v1alpha1 "github.com/rancher/fleet/pkg/apis/fleet.cattle.io/v1alpha1"
scheme "github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/client/fleet/clientset/versioned/scheme"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"

View File

@@ -22,8 +22,8 @@ import (
"context"
"time"
scheme "github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/client/fleet/clientset/versioned/scheme"
v1alpha1 "github.com/rancher/fleet/pkg/apis/fleet.cattle.io/v1alpha1"
scheme "github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/client/fleet/clientset/versioned/scheme"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"

View File

@@ -19,7 +19,7 @@ limitations under the License.
package fake
import (
v1alpha1 "github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/client/fleet/clientset/versioned/typed/fleet.cattle.io/v1alpha1"
v1alpha1 "github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/client/fleet/clientset/versioned/typed/fleet.cattle.io/v1alpha1"
rest "k8s.io/client-go/rest"
testing "k8s.io/client-go/testing"
)

View File

@@ -19,8 +19,8 @@ limitations under the License.
package v1alpha1
import (
"github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/client/fleet/clientset/versioned/scheme"
v1alpha1 "github.com/rancher/fleet/pkg/apis/fleet.cattle.io/v1alpha1"
"github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/client/fleet/clientset/versioned/scheme"
rest "k8s.io/client-go/rest"
)

View File

@@ -22,8 +22,8 @@ import (
"context"
"time"
scheme "github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/client/fleet/clientset/versioned/scheme"
v1alpha1 "github.com/rancher/fleet/pkg/apis/fleet.cattle.io/v1alpha1"
scheme "github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/client/fleet/clientset/versioned/scheme"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"

View File

@@ -22,8 +22,8 @@ import (
"context"
"time"
scheme "github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/client/fleet/clientset/versioned/scheme"
v1alpha1 "github.com/rancher/fleet/pkg/apis/fleet.cattle.io/v1alpha1"
scheme "github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/client/fleet/clientset/versioned/scheme"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"

View File

@@ -19,12 +19,12 @@ import (
"github.com/gardener/gardener/extensions/pkg/controller/cmd"
extensionshealthcheckcontroller "github.com/gardener/gardener/extensions/pkg/controller/healthcheck"
healthcheckconfig "github.com/gardener/gardener/extensions/pkg/controller/healthcheck/config"
apisconfig "github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/apis/config"
"github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/apis/config/v1alpha1"
"github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/controller"
controllerconfig "github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/controller/config"
healthcheckcontroller "github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/controller/healthcheck"
"github.com/spf13/pflag"
apisconfig "github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/apis/config"
"github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/apis/config/v1alpha1"
"github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/controller"
controllerconfig "github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/controller/config"
healthcheckcontroller "github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/controller/healthcheck"
"io/ioutil"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/serializer"

View File

@@ -15,12 +15,17 @@
package controller
import (
"bytes"
"context"
"fmt"
managed_resource_handler "github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/controller/managed-resource-handler"
token_requestor_handler "github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/controller/token-requestor-handler"
"github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/utils"
"k8s.io/apimachinery/pkg/api/errors"
"reflect"
"strings"
projConfig "github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/apis/config"
projConfig "github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/apis/config"
"github.com/gardener/gardener/pkg/apis/core/v1beta1"
"github.com/gardener/gardener/pkg/extensions"
@@ -38,7 +43,7 @@ import (
"github.com/gardener/gardener/extensions/pkg/controller"
"github.com/gardener/gardener/extensions/pkg/controller/extension"
"github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/controller/config"
"github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/controller/config"
extensionsv1alpha1 "github.com/gardener/gardener/pkg/apis/extensions/v1alpha1"
kutil "github.com/gardener/gardener/pkg/utils/kubernetes"
@@ -48,14 +53,17 @@ import (
const ActuatorName = "shoot-fleet-agent-actuator"
// KubeconfigSecretName name of secret that holds kubeconfig for Shoot
const KubeconfigSecretName = "kubecfg"
const KubeconfigSecretName = token_requestor_handler.TokenRequestorSecretName
// KubeconfigKey key in KubeconfigSecretName secret that holds kubeconfig for Shoot
const KubeconfigKey = "kubeconfig"
const KubeconfigKey = token_requestor_handler.TokenRequestorSecretKey
// DefaultConfigKey is the name of default config key.
const DefaultConfigKey = "default"
// FleetClusterSecretDataKey is the key of the data item that holds the kubeconfig for the cluster in fleet
const FleetClusterSecretDataKey = "value"
// NewActuator returns an actuator responsible for Extension resources.
func NewActuator(config config.Config) extension.Actuator {
logger := log.Log.WithName(ActuatorName)
@@ -89,6 +97,26 @@ func initializeFleetManagers(config config.Config, logger logr.Logger) map[strin
return fleetManagers
}
func (a *actuator) ensureDependencies(ctx context.Context, cluster *extensions.Cluster) error {
// Initialize token requestor handler
tokenRequestor := token_requestor_handler.NewTokenRequestorHandler(ctx, a.client, cluster)
// Initialize the managed resoruce handler
managedResourceHandler := managed_resource_handler.NewManagedResourceHandler(ctx, a.client, cluster)
dependencyFunctions := []func() error{
tokenRequestor.EnsureKubeconfig,
managedResourceHandler.EnsureManagedResoruces,
}
return utils.RunParallelFunctions(dependencyFunctions)
}
// isShootedSeed looks into the Cluster object to determine whether we are in a Shooted Seed cluster
func isShootHibernated(cluster *extensions.Cluster) bool {
return cluster.Shoot.Status.IsHibernated
}
// Reconcile the Extension resource.
func (a *actuator) Reconcile(ctx context.Context, ex *extensionsv1alpha1.Extension) error {
namespace := ex.GetNamespace()
@@ -100,13 +128,27 @@ func (a *actuator) Reconcile(ctx context.Context, ex *extensionsv1alpha1.Extensi
if isShootedSeedCluster(cluster) {
return a.updateStatus(ctx, ex)
}
if isShootHibernated(cluster) {
return a.updateStatus(ctx, ex)
}
shootsConfigOverride := &config.Config{}
if ex.Spec.ProviderConfig != nil { //parse providerConfig defaults override for this Shoot
if _, _, err := a.decoder.Decode(ex.Spec.ProviderConfig.Raw, nil, shootsConfigOverride); err != nil {
return fmt.Errorf("failed to decode provider config: %+v", err)
}
}
a.ReconcileClusterInFleetManager(ctx, namespace, cluster, shootsConfigOverride)
if err := a.ensureDependencies(ctx, cluster); err != nil {
a.logger.Error(err, "Could not ensure dependencies")
return err
}
if err = a.ReconcileClusterInFleetManager(ctx, namespace, cluster, shootsConfigOverride); err != nil {
a.logger.Error(err, "Could not reconcile cluster in fleet")
return err
}
return a.updateStatus(ctx, ex)
}
@@ -163,71 +205,117 @@ func (a *actuator) InjectScheme(scheme *runtime.Scheme) error {
}
// ReconcileClusterInFleetManager reconciles cluster registration in remote fleet manager
func (a *actuator) ReconcileClusterInFleetManager(ctx context.Context, namespace string, cluster *extensions.Cluster, override *config.Config) {
a.logger.Info("Starting with already registered check")
func (a *actuator) ReconcileClusterInFleetManager(ctx context.Context, namespace string, cluster *extensions.Cluster, override *config.Config) error {
labels := prepareLabels(cluster, getProjectConfig(cluster, &a.serviceConfig), getProjectConfig(cluster, override))
registered, err := a.getFleetManager(cluster).GetCluster(ctx, cluster.Shoot.Name)
if err != nil {
a.logger.Error(err, "Failed to get cluster registration for Shoot", "shoot", cluster.Shoot.Name)
}
if err == nil && registered != nil {
if reflect.DeepEqual(registered.Labels, labels) {
a.logger.Info("Cluster already registered - skipping registration", "clientId", registered.Spec.ClientID)
} else {
a.logger.Info("Updating labels of already registered cluster.", "clientId", registered.Spec.ClientID)
a.updateClusterLabelsInFleet(ctx, registered, cluster, labels)
}
return
}
a.registerNewClusterInFleet(ctx, namespace, cluster, labels)
}
func (a *actuator) updateClusterLabelsInFleet(ctx context.Context, clusterRegistration *fleetv1alpha1.Cluster, cluster *extensions.Cluster, labels map[string]string) {
clusterRegistration.Labels = labels
_, err := a.getFleetManager(cluster).UpdateCluster(ctx, clusterRegistration)
if err != nil {
a.logger.Error(err, "Failed to update cluster labels in Fleet registration.", "clusterName", clusterRegistration.Name)
}
}
func (a *actuator) registerNewClusterInFleet(ctx context.Context, namespace string, cluster *extensions.Cluster, labels map[string]string) {
a.logger.Info("Looking up Secret with KubeConfig for given Shoot.", "namespace", namespace, "secretName", KubeconfigSecretName)
secret := &corev1.Secret{}
if err := a.client.Get(ctx, kutil.Key(namespace, KubeconfigSecretName), secret); err == nil {
secretData := make(map[string][]byte)
secretData["value"] = secret.Data[KubeconfigKey]
a.logger.Info("Loaded kubeconfig from secret", "kubeconfig", secret, "namespace", namespace)
const fleetRegisterNamespace = "clusters"
kubeconfigSecret := corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "kubecfg-" + buildCrdName(cluster),
Namespace: fleetRegisterNamespace,
},
Data: secretData,
}
clusterRegistration := fleetv1alpha1.Cluster{
TypeMeta: metav1.TypeMeta{},
ObjectMeta: metav1.ObjectMeta{
Name: buildCrdName(cluster),
Namespace: fleetRegisterNamespace,
Labels: labels,
},
Spec: fleetv1alpha1.ClusterSpec{
KubeConfigSecret: "kubecfg-" + buildCrdName(cluster),
},
}
if _, err = a.getFleetManager(cluster).CreateKubeconfigSecret(ctx, &kubeconfigSecret); err != nil {
a.logger.Error(err, "Failed to create secret with kubeconfig for Fleet registration")
}
if _, err = a.getFleetManager(cluster).CreateCluster(ctx, &clusterRegistration); err != nil {
a.logger.Error(err, "Failed to create Cluster for Fleet registration")
}
a.logger.Info("Registered shoot cluster in Fleet Manager ", "registration", clusterRegistration)
} else {
kubeconfigSecret := &corev1.Secret{}
if err := a.client.Get(ctx, kutil.Key(namespace, KubeconfigSecretName), kubeconfigSecret); err != nil {
a.logger.Error(err, "Failed to find Secret with kubeconfig for Fleet registration.")
return err
}
a.logger.Info("Checking if the fleet cluster already exists")
// Check whether we already have an existing cluster
_, err := a.getFleetManager(cluster).GetCluster(ctx, buildCrdName(cluster))
// We cannot find the cluster because of an unknown error
if err != nil && !errors.IsNotFound(err) {
a.logger.Error(err, "Failed to get cluster registration for Shoot", "shoot", cluster.Shoot.Name)
return err
}
// We cannot find the cluster because we haven't registered it yet
if errors.IsNotFound(err) {
a.logger.Info("Creating fleet cluster", "shoot", cluster.Shoot.Name)
return a.registerNewClusterInFleet(ctx, namespace, cluster, labels, kubeconfigSecret.Data[KubeconfigKey])
}
a.logger.Info("Updating existing fleet cluster")
return a.updateClusterInFleet(ctx, cluster, labels, kubeconfigSecret.Data[KubeconfigKey])
}
func (a *actuator) updateClusterInFleet(ctx context.Context, cluster *extensions.Cluster, labels map[string]string, kubeconfig []byte) error {
updated := false
clusterRegistration, err := a.getFleetManager(cluster).GetCluster(ctx, buildCrdName(cluster))
if err != nil {
a.logger.Error(err, "Could not fetch fleet cluster")
return err
}
fleetKubeconfigSecret, err := a.getFleetManager(cluster).GetKubeconfigSecret(ctx, buildKubecfgName(cluster))
if err != nil {
a.logger.Error(err, "Could not fetch fleet kubeconfig secret")
return err
}
if !reflect.DeepEqual(clusterRegistration.Labels, labels) {
a.logger.Info("Cluster labels changed, updating")
clusterRegistration.Labels = labels
_, err := a.getFleetManager(cluster).UpdateCluster(ctx, clusterRegistration)
if err != nil {
a.logger.Error(err, "Failed to update cluster labels in Fleet registration.", "clusterName", clusterRegistration.Name)
return err
}
updated = true
}
if bytes.Compare(fleetKubeconfigSecret.Data[FleetClusterSecretDataKey], kubeconfig) != 0 {
a.logger.Info("Shoot kubeconfig changed, updating")
fleetKubeconfigSecret.Data[FleetClusterSecretDataKey] = kubeconfig
_, err := a.getFleetManager(cluster).UpdateKubeconfigSecret(ctx, fleetKubeconfigSecret)
if err != nil {
a.logger.Error(err, "Failed to update kuebconfig secret in Fleet registration.", "clusterName", clusterRegistration.Name)
return err
}
updated = true
}
if updated {
a.logger.Info("Cluster successfully updated.")
} else {
a.logger.Info("Cluster is already up to date.")
}
return nil
}
func (a *actuator) registerNewClusterInFleet(ctx context.Context, namespace string, cluster *extensions.Cluster, labels map[string]string, kubeconfig []byte) error {
secretData := make(map[string][]byte)
secretData[FleetClusterSecretDataKey] = kubeconfig
const fleetRegisterNamespace = "clusters"
kubeconfigSecret := corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: buildKubecfgName(cluster),
Namespace: fleetRegisterNamespace,
},
Data: secretData,
}
clusterRegistration := fleetv1alpha1.Cluster{
TypeMeta: metav1.TypeMeta{},
ObjectMeta: metav1.ObjectMeta{
Name: buildCrdName(cluster),
Namespace: fleetRegisterNamespace,
Labels: labels,
},
Spec: fleetv1alpha1.ClusterSpec{
KubeConfigSecret: "kubecfg-" + buildCrdName(cluster),
},
}
if _, err := a.getFleetManager(cluster).CreateKubeconfigSecret(ctx, &kubeconfigSecret); err != nil {
a.logger.Error(err, "Failed to create secret with kubeconfig for Fleet registration")
return err
}
if _, err := a.getFleetManager(cluster).CreateCluster(ctx, &clusterRegistration); err != nil {
a.logger.Error(err, "Failed to create Cluster for Fleet registration")
return err
}
a.logger.Info("Registered shoot cluster in Fleet Manager ", "registration", clusterRegistration)
return nil
}
func prepareLabels(cluster *extensions.Cluster, serviceConfig projConfig.ProjectConfig, override projConfig.ProjectConfig) map[string]string {
@@ -276,9 +364,14 @@ func getProjectConfig(cluster *extensions.Cluster, serviceConfig *config.Config)
return projectConfig
}
// buildCrdName creates a unique name for cluster registration resources in Fleet manager cluster
func buildKubecfgName(cluster *extensions.Cluster) string {
return fmt.Sprintf("kubecfg-%s", buildCrdName(cluster))
}
// buildCrdName creates a unique name for cluster registration resources in Fleet manager cluster
func buildCrdName(cluster *extensions.Cluster) string {
return cluster.Seed.Name + "" + cluster.Shoot.Name
return fmt.Sprintf("%s%s", cluster.Seed.Name, cluster.Shoot.Name)
}
// isShootedSeedCluster checks if clusters purpose is Infrastructure

View File

@@ -15,7 +15,7 @@
package controller
import (
controllerconfig "github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/controller/config"
controllerconfig "github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/controller/config"
"github.com/gardener/gardener/extensions/pkg/controller/extension"
"sigs.k8s.io/controller-runtime/pkg/controller"

View File

@@ -1,6 +1,6 @@
package config
import "github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/apis/config"
import "github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/apis/config"
// Config holds controller config
type Config struct {

View File

@@ -8,9 +8,9 @@ import (
"k8s.io/client-go/tools/clientcmd"
fleetConfig "github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/apis/config"
clientset "github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/client/fleet/clientset/versioned"
"github.com/rancher/fleet/pkg/apis/fleet.cattle.io/v1alpha1"
fleetConfig "github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/apis/config"
clientset "github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/client/fleet/clientset/versioned"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
@@ -63,6 +63,16 @@ func (f *FleetManager) GetCluster(ctx context.Context, clusterName string) (*v1a
return f.fleetClient.FleetV1alpha1().Clusters(f.namespace).Get(ctx, clusterName, metav1.GetOptions{})
}
// GetKubeconfigSecret registers a clusters kubeconfig secret in remote fleet
func (f *FleetManager) GetKubeconfigSecret(ctx context.Context, secretName string) (*corev1.Secret, error) {
return f.secretClient.CoreV1().Secrets(f.namespace).Get(ctx, secretName, metav1.GetOptions{})
}
// UpdateKubeconfigSecret updates kubeconfig secret in remote fleet
func (f *FleetManager) UpdateKubeconfigSecret(ctx context.Context, secret *corev1.Secret) (*corev1.Secret, error) {
return f.secretClient.CoreV1().Secrets(f.namespace).Update(ctx, secret, metav1.UpdateOptions{})
}
// CreateKubeconfigSecret registers a clusters kubeconfig secret in remote fleet
func (f *FleetManager) CreateKubeconfigSecret(ctx context.Context, secret *corev1.Secret) (*corev1.Secret, error) {
return f.secretClient.CoreV1().Secrets(f.namespace).Create(ctx, secret, metav1.CreateOptions{})

View File

@@ -19,7 +19,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
fleetcontroller "github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/controller"
fleetcontroller "github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/controller"
"github.com/gardener/gardener/extensions/pkg/controller/healthcheck"
healthcheckconfig "github.com/gardener/gardener/extensions/pkg/controller/healthcheck/config"

View File

@@ -0,0 +1,117 @@
package managed_resource_handler
import (
"context"
"fmt"
"github.com/gardener/gardener/extensions/pkg/util"
"github.com/gardener/gardener/pkg/apis/resources/v1alpha1"
"github.com/gardener/gardener/pkg/extensions"
kutil "github.com/gardener/gardener/pkg/utils/kubernetes"
"github.com/gardener/gardener/pkg/utils/kubernetes/health"
"github.com/gardener/gardener/pkg/utils/managedresources"
"github.com/gardener/gardener/pkg/utils/retry"
"github.com/go-logr/logr"
token_requestor_handler "github.com/ysoftdevs/gardener-extension-shoot-fleet-agent/pkg/controller/token-requestor-handler"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"path/filepath"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/log"
"time"
)
var (
ChartsPath = filepath.Join("charts", "internal")
ManagedResourcesChartValues = map[string]interface{}{
"shootAccessServiceAccountName": token_requestor_handler.TargetServiceAccountName,
"shootAccessServiceAccountNamespace": token_requestor_handler.TargetServiceAccountNamespace,
}
)
const (
ManagedResourceChartName = "shoot-fleet-agent-shoot"
ManagedResourceName = "extension-shoot-fleet-agent-shoot"
)
type ManagedResourceHandler struct {
ctx context.Context
client client.Client
cluster *extensions.Cluster
logger logr.Logger
}
func NewManagedResourceHandler(ctx context.Context, client client.Client, cluster *extensions.Cluster) *ManagedResourceHandler {
return &ManagedResourceHandler{
ctx: ctx,
client: client,
cluster: cluster,
logger: log.Log.WithValues("logger", "managed-resource-handler", "cluster", cluster.ObjectMeta.Name),
}
}
// renderChart takes the helm chart at charts/internal/<ManagedResourceChartName> and renders it with the values
func (h *ManagedResourceHandler) renderChart() ([]byte, error) {
chartPath := filepath.Join(ChartsPath, ManagedResourceChartName)
renderer, err := util.NewChartRendererForShoot(h.cluster.Shoot.Spec.Kubernetes.Version)
if err != nil {
return nil, err
}
chart, err := renderer.Render(chartPath, ManagedResourceChartName, h.cluster.ObjectMeta.Name, ManagedResourcesChartValues)
if err != nil {
return nil, err
}
return chart.Manifest(), nil
}
func (h *ManagedResourceHandler) EnsureManagedResoruces() error {
h.logger.Info("Rendering chart with the managed resources")
renderedChart, err := h.renderChart()
if err != nil {
return err
}
data := map[string][]byte{ManagedResourceChartName: renderedChart}
keepObjects := false
forceOverwriteAnnotations := false
h.logger.Info("Creating the ManagedResource")
if err := managedresources.Create(h.ctx, h.client, h.cluster.ObjectMeta.Name, ManagedResourceName, false, "", data, &keepObjects, map[string]string{}, &forceOverwriteAnnotations); err != nil {
h.logger.Error(err, "ManagedResource could not be created")
return err
}
h.logger.Info("Waiting until the ManagedResource is healthy")
if err := h.waitUntilManagedResourceHealthy(); err != nil {
h.logger.Error(err, "ManagedResource has been created, but hasn't been applied")
return err
}
h.logger.Info("ManagedResource created")
return nil
}
func (h *ManagedResourceHandler) waitUntilManagedResourceHealthy() error {
name := ManagedResourceName
namespace := h.cluster.ObjectMeta.Name
obj := &v1alpha1.ManagedResource{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
},
}
return retry.UntilTimeout(h.ctx, 5*time.Second, 60*time.Second, func(ctx context.Context) (done bool, err error) {
if err := h.client.Get(ctx, kutil.Key(namespace, name), obj); err != nil {
h.logger.Info(fmt.Sprintf("Could not wait for the managed resource to be ready: %+v", err))
return retry.MinorError(err)
}
// Check whether ManagedResource has proper status
if err := health.CheckManagedResource(obj); err != nil {
h.logger.Info(fmt.Sprintf("Managed resource %s not ready (yet): %+v", name, err))
return retry.MinorError(err)
}
return retry.Ok()
})
}

View File

@@ -0,0 +1,163 @@
package token_requestor_handler
import (
"context"
"fmt"
extensionscontroller "github.com/gardener/gardener/extensions/pkg/controller"
constsv1alpha1 "github.com/gardener/gardener/pkg/apis/resources/v1alpha1"
"github.com/gardener/gardener/pkg/extensions"
kutil "github.com/gardener/gardener/pkg/utils/kubernetes"
"github.com/gardener/gardener/pkg/utils/retry"
"github.com/go-logr/logr"
v1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
clientapiv1 "k8s.io/client-go/tools/clientcmd/api/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/yaml"
"time"
)
const (
TokenRequestorSecretName = "shoot-access-extension-shoot-fleet-agent"
TokenRequestorSecretKey = constsv1alpha1.DataKeyKubeconfig
TargetServiceAccountName = "extension-shoot-fleet-agent"
TargetServiceAccountNamespace = "kube-system"
)
type TokenRequestorHandler struct {
ctx context.Context
client client.Client
cluster *extensions.Cluster
logger logr.Logger
}
func NewTokenRequestorHandler(ctx context.Context, client client.Client, cluster *extensions.Cluster) *TokenRequestorHandler {
return &TokenRequestorHandler{
ctx: ctx,
client: client,
cluster: cluster,
logger: log.Log.WithValues("logger", "token-requestor-handler", "cluster", cluster.ObjectMeta.Name),
}
}
func (t *TokenRequestorHandler) getGenericKubeconfigName() string {
return extensionscontroller.GenericTokenKubeconfigSecretNameFromCluster(t.cluster)
}
func (t *TokenRequestorHandler) getGenericKubeconfig() (*clientapiv1.Config, error) {
kubeconfigSecret := &v1.Secret{}
kubeconfigSecretName := t.getGenericKubeconfigName()
if err := t.client.Get(t.ctx, kutil.Key(t.cluster.ObjectMeta.Name, kubeconfigSecretName), kubeconfigSecret); err != nil {
return nil, err
}
kubeconfigData, ok := kubeconfigSecret.Data[TokenRequestorSecretKey]
if !ok {
return nil, fmt.Errorf("secret %s doesn't have data key %s", kubeconfigSecretName, TokenRequestorSecretKey)
}
kubeconfig := &clientapiv1.Config{}
if err := yaml.Unmarshal(kubeconfigData, kubeconfig); err != nil {
return nil, err
}
return kubeconfig, nil
}
func (t *TokenRequestorHandler) isTokenInserted() bool {
kubeconfigSecret := &v1.Secret{}
if err := t.client.Get(t.ctx, kutil.Key(t.cluster.ObjectMeta.Name, TokenRequestorSecretName), kubeconfigSecret); err != nil {
t.logger.Info(fmt.Sprintf("Couldn't fet the kubeconfig secret %s, %+v", TokenRequestorSecretName, err))
return false
}
kubeconfigData, ok := kubeconfigSecret.Data[TokenRequestorSecretKey]
if !ok {
t.logger.Info(fmt.Sprintf("Kubeconfig secret %s doesn't contain data item %s", TokenRequestorSecretName, TokenRequestorSecretKey))
return false
}
kubeconfig := &clientapiv1.Config{}
if err := yaml.Unmarshal(kubeconfigData, kubeconfig); err != nil {
t.logger.Info(fmt.Sprintf("Data item %s in kubeconfig secret %s couldn't be parsed: %+v", TokenRequestorSecretKey, TokenRequestorSecretName, err))
return false
}
if len(kubeconfig.AuthInfos) == 0 || kubeconfig.AuthInfos[0].AuthInfo.Token == "" {
t.logger.Info(fmt.Sprintf("Kubeconfig in secret %s doesn't contain token (yet?)", TokenRequestorSecretName))
return false
}
t.logger.Info(fmt.Sprintf("Kubeconfig in secret %s contains a proper token", TokenRequestorSecretName))
return true
}
func (t *TokenRequestorHandler) createKubeconfigSecretFromGeneric() error {
kubeconfig, err := t.getGenericKubeconfig()
s := false
for _, value := range t.cluster.Shoot.Status.AdvertisedAddresses {
// check for external URL server
if value.Name == "external" {
kubeconfig.Clusters[0].Cluster.Server = value.URL
s = true
break
}
}
if s != true {
t.logger.Info(fmt.Sprintf("Shoot status doesn't contain external URL address."))
return err
}
if err != nil {
return err
}
kubeconfigYaml, err := yaml.Marshal(kubeconfig)
if err != nil {
return err
}
existingSecret := &v1.Secret{}
err = t.client.Get(t.ctx, kutil.Key(t.cluster.ObjectMeta.Name, TokenRequestorSecretName), existingSecret)
if err == nil || !apierrors.IsNotFound(err) {
return err
}
secretObject := &v1.Secret{
ObjectMeta: metav1.ObjectMeta{
Namespace: t.cluster.ObjectMeta.Name,
Name: TokenRequestorSecretName,
Labels: map[string]string{
constsv1alpha1.ResourceManagerPurpose: constsv1alpha1.LabelPurposeTokenRequest,
},
Annotations: map[string]string{
constsv1alpha1.ServiceAccountName: TargetServiceAccountName,
constsv1alpha1.ServiceAccountNamespace: TargetServiceAccountNamespace,
},
},
StringData: map[string]string{
TokenRequestorSecretKey: string(kubeconfigYaml),
},
}
return t.client.Create(t.ctx, secretObject)
}
// EnsureKubeconfig creates the secret with a token-requestor label and waits until gardener fills in
// the token into the kubeconfig
func (t *TokenRequestorHandler) EnsureKubeconfig() error {
t.logger.Info(fmt.Sprintf("Trying to create the token requestor secret"))
if err := t.createKubeconfigSecretFromGeneric(); err != nil {
t.logger.Error(err, "Generic kubeconfig could not be copied")
return err
}
t.logger.Info("Waiting until the token is propagated into the token requestor secret")
if err := retry.UntilTimeout(t.ctx, 5*time.Second, 60*time.Second, func(ctx context.Context) (bool, error) {
return t.isTokenInserted(), nil
}); err != nil {
t.logger.Error(err, "Kubeconfig could not be created")
return err
}
return nil
}

43
pkg/utils/parallel.go Normal file
View File

@@ -0,0 +1,43 @@
package utils
import (
"github.com/pkg/errors"
"sync"
)
// RunParallelFunctions runs a list of functions in parallel
// returns nil if all functions return nil
// returns an error which wraps all errors that occurred within the functions
func RunParallelFunctions(functions []func() error) error {
var wg sync.WaitGroup
var mu sync.Mutex
var errorList []error
for _, function := range functions {
wg.Add(1)
// create an intermediate variable so each goroutine uses the correct function and doesn't get overwritten
function := function
go func(wg *sync.WaitGroup, mu *sync.Mutex) {
defer wg.Done()
err := function()
if err != nil {
mu.Lock()
errorList = append(errorList, err)
mu.Unlock()
}
}(&wg, &mu)
}
wg.Wait()
if len(errorList) > 0 {
err := errors.New("not all functions returned nil error")
for _, errorItem := range errorList {
err = errors.Wrap(err, errorItem.Error())
}
return err
}
return nil
}