mirror of
https://github.com/ysoftdevs/gardener-extension-shoot-fleet-agent.git
synced 2026-03-21 16:49:49 +01:00
Added support for configuration per project
Shoots with type==Infrastructure will not be considered to be added to Fleet
This commit is contained in:
2
Makefile
2
Makefile
@@ -76,7 +76,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
|
||||
|
||||
37
README.md
37
README.md
@@ -11,17 +11,30 @@ Recently, most of the vendor specific logic has been developed [in-tree](https:/
|
||||
|
||||
## Configuration
|
||||
|
||||
Example configuration for this extension controller:
|
||||
Example configuration for this extension controller with default config and 2 project specific configs:
|
||||
|
||||
```yaml
|
||||
apiVersion: shoot-fleet-agent-service.extensions.config.gardener.cloud/v1alpha1
|
||||
kind: Configuration
|
||||
clientConnection:
|
||||
defaultConfig:
|
||||
kubeconfig: #base64encoded kubeconfig of cluster running Fleet manager
|
||||
labels: #extra labels to apply to Cluster registration
|
||||
env: dev
|
||||
env: dev
|
||||
projectConfig:
|
||||
myproject:
|
||||
kubeconfig: #base64encoded kubeconfig of cluster running Fleet manager
|
||||
labels:
|
||||
project: myproject
|
||||
somelabel: samevalue
|
||||
namespace: clusters
|
||||
myotherproject:
|
||||
kubeconfig: #base64encoded kubeconfig of cluster running Fleet manager
|
||||
labels:
|
||||
project: mypotherproject
|
||||
namespace: fleetclusters
|
||||
```
|
||||
|
||||
Unless the shoot is in one of the myproject or myother project it will get defaultConfiguration.
|
||||
Configuration supplied in ControllerRegistration will be applied as default however it can be overriden via configuration in Extension for given Shoot.
|
||||
## Extension-Resources
|
||||
|
||||
Example extension resource:
|
||||
@@ -39,6 +52,22 @@ spec:
|
||||
When an extension resource is reconciled, the extension controller will register Shoot cluster in Fleet management cluster(configured in kubeconfig in Configuration object above.
|
||||
|
||||
Please note, this extension controller relies on existing properly configured [Fleet multi-cluster deployment](https://fleet.rancher.io/multi-cluster-install/) configured above.
|
||||
By default configuration from ControllerRegistration is used but if Extension specifies different config for particular Shoot that configuration overrides the default settings.
|
||||
|
||||
## Shooted seeds registration in Fleet
|
||||
All shooted seeds will be ignored and not registered in Fleet. If you need to register shooted seeds please do so manually.
|
||||
|
||||
## Fleet CRD cluster default labels
|
||||
By default all clusters registered in fleet will have following labels:
|
||||
|
||||
|label|value|
|
||||
|---|---|
|
||||
|corebundle|true|
|
||||
|region| region of shoot |
|
||||
|cluster| name of shoot|
|
||||
|seed|name of shoots seed|
|
||||
|
||||
Any labels defined in configuration are added to those default labels.
|
||||
|
||||
## How to start using or developing this extension controller locally
|
||||
|
||||
|
||||
@@ -6,13 +6,16 @@ gardener-extension-shoot-fleet-agent
|
||||
---
|
||||
apiVersion: shoot-fleet-agent-service.extensions.config.gardener.cloud/v1alpha1
|
||||
kind: FleetAgentConfig
|
||||
clientConnection:
|
||||
defaultConfig:
|
||||
kubeconfig: {{ .Values.fleetManager.kubeconfig }}
|
||||
{{- if .Values.fleetManager.labels }}
|
||||
labels: {{ .Values.fleetManager.labels | toYaml | nindent 6 }}
|
||||
labels: {{ .Values.fleetManager.labels | toYaml | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- if .Values.fleetManager.namespace }}
|
||||
namespace: {{ .Values.fleetManager.namespace }}
|
||||
namespace: {{ .Values.fleetManager.namespace }}
|
||||
{{- end }}
|
||||
{{- if .Values.fleetManager.projectConfig }}
|
||||
projectConfig: {{ .Values.fleetManager.projectConfig | toYaml | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
|
||||
@@ -27,9 +27,20 @@ controllers:
|
||||
concurrentSyncs: 1
|
||||
|
||||
fleetManager:
|
||||
#default config values
|
||||
kubeconfig: #base64encoded kubeconfig of fleet manager cluster comes here
|
||||
labels: # optional fleet Cluster crd labels
|
||||
namespace: clusters # namespace where Fleet clusters stores Cluster CRD objects
|
||||
#project specific values
|
||||
# projectConfig:
|
||||
# myproject:
|
||||
# kubeconfig: #base64encoded kubeconfig of fleet manager cluster for myproject comes here
|
||||
# labels: # optional fleet Cluster crd labels for myproject
|
||||
# namespace: clusters # namespace where Fleet clusters stores Cluster CRD objects for myproject
|
||||
# myotherproject:
|
||||
# kubeconfig: #base64encoded kubeconfig of fleet manager cluster for myotherproject comes here
|
||||
# labels: # optional fleet Cluster crd labels for myotherproject
|
||||
# namespace: clusters # namespace where Fleet clusters stores Cluster CRD objects for myotherproject
|
||||
|
||||
disableControllers: []
|
||||
|
||||
|
||||
@@ -22,9 +22,10 @@ apiVersion: core.gardener.cloud/v1beta1
|
||||
kind: ControllerRegistration
|
||||
...
|
||||
values:
|
||||
clientConnection:
|
||||
kubeconfig: abcd
|
||||
labels:
|
||||
defaultConfig:
|
||||
clientConnection:
|
||||
kubeconfig: abcd
|
||||
labels:
|
||||
```
|
||||
|
||||
If the `shoot-fleet-agent` should be enabled for every shoot cluster in your Gardener managed environment, you need to globally enable it in the `ControllerRegistration`:
|
||||
|
||||
@@ -15,10 +15,11 @@ spec:
|
||||
providerConfig:
|
||||
apiVersion: service.fleet-agent.extensions.gardener.cloud/v1alpha1
|
||||
kind:
|
||||
clientConnection:
|
||||
kubeconfig: base64 encoded kubeconfig
|
||||
labels:
|
||||
env: test
|
||||
defaultConfig:
|
||||
clientConnection:
|
||||
kubeconfig: base64 encoded kubeconfig
|
||||
labels:
|
||||
env: test
|
||||
```
|
||||
|
||||
<style>
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
apiVersion: shoot-fleet-agent-service.extensions.config.gardener.cloud/v1alpha1
|
||||
kind: FleetAgentConfig
|
||||
clientConnection:
|
||||
defaultConfig:
|
||||
kubeconfig: #base64 encoded kubeconfig of fleet cluster
|
||||
namespace: clusters #namespace to register clusters in fleet manager cluster
|
||||
namespace: clusters #namespace to register clusters in fleet manager cluster
|
||||
labels:
|
||||
allshootswillhavethislabel: somevalue
|
||||
# example of project specific config:
|
||||
#projectConfig:
|
||||
# projectABC:
|
||||
# kubeconfig: #base64 encoded kubeconfig of ABC fleet cluster
|
||||
# namespace: nsABC #namespace to register clusters in fleet manager cluster
|
||||
# labels:
|
||||
# myProjectABClabel1: myvalue
|
||||
# myProjectABClabel2: myvalue2
|
||||
# projectDEF:
|
||||
# kubeconfig: #base64 encoded kubeconfig of DEF fleet cluster
|
||||
# namespace: nsDEF #namespace to register clusters in fleet manager cluster
|
||||
# labels:
|
||||
# myProjectDEFlabel1: myvalue
|
||||
# myProjectDEFlabel2: myvalue2
|
||||
|
||||
@@ -11,7 +11,7 @@ spec:
|
||||
deployment:
|
||||
type: helm
|
||||
providerConfig:
|
||||
chart: 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
|
||||
chart: H4sIAAAAAAAAA+0ca3PbNjKf+StwynWadELqYVludZObU2U39TSxPVbqTufmJgORkMSGJFiAlKMmvd9+iwcpkKKedu30yp1MLIHAYneBfQFLTTHzSESYTT4kJOI+jWw+ozSxJwEhiY2nJEqaT+4GLYCT42P5F6D8V35uH3XbneNOryfa273eyckTdHzHeXeClCeYIfSEAdOb+m17/ieF6S7r78xIEPrTiDJyyBxigXvd7tr1h2Uvrn+n3TrqPkGt+2a2Cv7i6/8UXeEkISziKKFIrTG6nZEIjVM/8PxoimLsvod9wB3rKXo78zniaRxTlsAH2BcBmgZ0jEKcuDPo/QIxEuDEnxMYl8yMdhx5gCAiU3hKI/QsZmTifyAeuvWh39+eO+gyChaIRnKkIAnFhKHAj4hjOaejd6MEaAMUQxqGgOBmOEKez7jlTP2kKf9X5FvO+DfWlP9nDbNpU/yXfeXzqLlENAb+0hhN/IBw6yuH38bw/xi/h/+TED7/F7reYObTlKPz0zOYMGb0F+ImluN7BDdVP2iynDl3qUea1mOv6u6wk/4PZ5glzgKHwUFzbNP/DviGov63emASav1/AMCxf0OYWPc+mrctHMfGV6fltGyPzC2PcJf5cSLbB+h7cAfIFZsCTShDyYygV3ofoZHYPeg7sXvQQOwelO8sx4pwSPpolz1nzSvIeGxh/R/CTvrvUdeZ0oPn2KL/nVb7qBT/nZz0Tmr9fwhoNsENxgvwlLMEPXOfI1iNb9BocIVGZwh0G0fyC56Ae/RxQpBLwxhHCwcNwPXLYRxcPidsTjxHxQfCkyL4G/gubCnw8GnkEWUmBhBMwJ8RnSS3GCKN16rLCzR3UAcshUviBGGOIprAOApD2K3PAVskh78+H55dAGFiBqvZhH8ZhopJctzaoqGO00LPRIeGftR4/g+BYkFTiFMWYlKUwmRJzoQmCGYXbIMAIpeoeCVZTuAIHD9rHHScYOiOYUAM3yZmR4QTTbSEWZLE/Wbz9vbWwZJih7JpUwuNNzWvNlCtR/0YQYQipP1r6jPgeLxAYK9hAB4DrQG+lQs2ZQSeiWAuQrcMgiIRfHEtcIHG83nC/HGaFISW0Qismx1AbLAFGoMROh810LeD0fnohUDy0/nb7y9/fIt+GlxfDy7enp+N0OU1Gl5enJ6/Pb+8gG/focHFz+iH84vTF4j4YiVBnBD0AQdApi/ECTtG4BoRUiAh8yk8Jq4/8V1gLZqmYIrQlIJbiGRQSljoc7GsXEaWgCbwQz+RwSVf5cuxoMuU9qfC2Il97DhN+DeD2K+ZtdkujRJGgwDMISNTIQWJzuEztME8Ikcjuzm7HgHv+hv5gIFH0lyHVIRT6CxD21/1gIKnKxV7a2dLIrHSHJl86GBcCk03CvkI1l3KGISpaEkBKlBgxSb22rv+FWEn/58Q2Mmw2fhhJ0F7n/9A/H9yXJ//PATsuf7vIOMH08udJN49F9wW/x2dlOK/zlGnU5//PAh8/Ggjj0z8CKIikZ01kP3779ZOGZoYSiJPDrBMPPIxOJ2JP1XobNu2zERzBZct4kdw1E4+H3cUAicjxXEDmnrNeRsH8Qy3rfd+5PVVninTzKHsDpnqBKeB/ta3EHqfjolC1UcfPyLnBgcp4Y6c/A2OYHrmLPsgoFaw4k+qewZ4TAIueiGkPq/Hqvt+gljsZ+HrPyGIXDwRMHSzaYT4tswoFoWDoyZq0vzr+nkLI3acRZ9oDXMhFBrWz1UcV8Fqp4II/VF+zjeNHwJCtV0Q0qTOML+Sp4SowWe4c9zrN3IyZH8nwVOUj4iZHyUT1PiC/+sLXu7JSEy5n1C22IQCFoxUIewfjLCa7YxrmIFCjL5wA8y5PvJQQtAi4CSE5qFIuiBdavzzJWo77a7dAmqGkDWMIStLfJj6B9jCWr+cV36SpTwCE4fUwksDiAqd918DkRSUyMqZXTdH+85zjEmCjYnWddP6bFqTtZYlIBjiehLAloOZfU+JaoORstUIOxtion5s0/tZwJ7+X1nJEMe23OtzkCpltsjKRKpJqs+It97/9Ernv0fQv137/4eAklOQq3ojV/UyW1RhtErHxMr5Kqv/BsdWCKru4QT3tYeSDsOP3CD18rjCATzVu2bVrV2DvmJI2i+Kzk97XEucnuA4ln6bRSQh0pRsmnjNED+C1Y+qZhVjMo4k0fxdcZf30SfL8IqVgvuEqh3+Yy+6AXvqv0figC5CaNzjOmiL/h8fr8b/J8dHtf4/BJRDc9AR3sw1/DRf7goV3ylJuE/V3nFChES5gsNnTXmutce4fQ2EOKAUJDMy9wXa730u4sHX4iCyj1ryiTyfLWYJunFIUzANknsu4xPKFP/yzvy1IZB7EMn+zCGUqb2mytgAEl8UUX3cmjUhBPGd+56nYZMTl5GMDJ3d2UYeltvoQrLogMlUkT7gyMy2gB3d1AoZy3hlKaBKH1Qg6pkM/NHfnbdaAs63IJkrUc/Q2CkEajzfzIpOBVRDUFjpe1nrQ1YboWw7C8gSk6FITC72nV8v+MB1xR7fe7g4sMYQ8LNcKvZ+NkeBXJ/ibtNZpmMuiGy7SoPgioJaLgqqqjK6OH9Y2GQ0DDFYybzBRs296LORrVXiZZMkbrOgLHqfye1UGBHiD2KUmzImEhwmTi5cUbvy0qB7eeQvP+vOo0XkcpMFgW9GcJDMpMbsj9sYvG0ez+fi9sK4ZClg1Y+Hy6egQL9QP0KNF40yLlXIY9OYqKsMe2mM1lGqhlxmIwb5gDLuUsZo+95LcwetpqCFzUSiubkh1K59fTY4Pbt+d/b6bCgux95dDN6cja4Gw7O8J0JzQfJ3jIZ9oxGhiU8C75pMiq26XVikfm6Ylwc/h5rNjN7zN4NXZzdA7OX1u8ubs+ufrs/frtDaR8q/GoFxszJSXm/5VghkhNOUuaSwefLGvgi49QnT6ohPKGF+uIy5262NVhe4oEEakjfCQvHVNavyXIYIQjFMyX9Vd41+DLaLqGvrA3XpnRdmixNbQ9/KMu1GX0FcSlgr9nijlFQMYO5c1XJR4mX9cXAB4V4y21dibpbLmuSuzSg3ZLIZ6IPoN9QDFN1Oy2BCC/axQ38Je+Z/qtVwTbvMse3856jVLuV/3Xb7uM7/HgIqD3ZGUk0rUr69dHaXxC9Db+yoLenBuNclkZtZ+8/qLOXPCHvqf+G+YlcDsFX/e+X7/263rv97GDD139S76ospGeoqG3FlJoiHng7pQLKd14FY4mUCHJwq56mDkkL1cSObGEnSVguQ8/kq7pmdxmPL+3ODPfWfjbGrO7iELY3+RkuwTf97rfL7P71O7f8fBsrnv2KBHZwmM9Cx31SZ4PLSWF/7BCAzwq5pQDaFCLxUutHffCRyrwfAh5x+rY4JZZGDZ48XxVEjtenFQJYGIimyYbT/itE0lhzYqNGwComrbFPZDxePwKKOs+avGo+YChyg/3u/CLRF/49OVvS/0z2p3/95ELh3/d9RR/+U9z3rtH2tzVs1Aq4SHi/agClJ5N/A5+rDrbgCutNEy66lr03gMEl3I0B8ivNPaQxLTXYzdnnydyCn8NVgVm3BCmmCMGmYNcoqIT/RPFdMCuYXy0OanJclgysUrNWEtYvKaEB4uWEMOuNHU9W+7FF6tCex4pMHm3PX1Wjkl1bS+xR9EXwjc1CJ5SPp3rKvMfVKT7C61qlyZKvUiAvlKoqWlQRlPHcVgEspA7luXjKp2CXJ6wnviDBrl+cc6tlO9wcGIQa7mTC0mtzJWn+r9ttfzWgD5/oCJVvXDYKDXqtebi8x8XQsSmKln8iO08zb0H2Fvssx2uH+f8/4r2gBdowEt+V/3ZNu+fyn16rrfx4EyhbFOAMubNq6/GfVsjz22t0H7Kn/8xjv/zsQW/S/3T0q1/91jo5btf4/BJQuVcX6qrdMvVLVbwO8JeUuXq3x7zS0yYC+iQ89rqg30J0JO9By2EDJjtYjK1uqYCWLxczinWKbMjl5wZFs9M177vyRurX+8qsv80ve0I8GQUBviVEDBLjiVBKbv6bdWE+Rs0ThwDjx8nU2rLGBkfIwo1JA1OmFlC0OIkENPYQKPbL82gtCoFwQwuYFLFWlpqJ9pdx0ef2+o/lWMbO5qKpFXcAbRUGCEbOzs+z32VZp/3Gwk/2fK8kd+gNA287/wN6v/P7XcX3/9yCgaiSlWcxeZ+ujX/Ach9idsV3rGRM87SMZIYhvsVFLOQhu8YJbViFbFtYFuiorK+1l47gVimOA3Ho1et03vmiRv+qwsWe787XoaoFii27afeUFTU8rLP7TFev9dGm7261WmLdks8hJtpqZhvB7QIpReKirG8zKSMAGjWsLEvtoggMuSDeqK3M/VUZkme9jSk505ZGuqVDFeuJgwnwT9ukY3KispAC6PeOR+MkSiRGp2w+WnWWJclfCgSRGlvE6CInKe1kc6FHDrDfzdKeiF8/OP2Hk8j3VW4FV/2ZU3kGU0sOEGcLh9SmiKrMWTOoXT5e/EaLZfCpKl81XVy25juFCt+rvd5aGuHbOkZqy0ej3EFARV4bgnmVWNUm4kD+w84dIxsR8L+IxEf6xMirMZK3WJffRv/9jAQlVBYjirTBBnCqEVSIt1koqcckYR3GhbNO1YX6nfjJLxw5ILbe/zTWDTatNUmfqMhGX51Zbc7Es28t+iUYvmsYizXej5XScbx7zLrKGGmqooYYaaqihhhpqqKGGGmqooYYaaqihhhpqqKGGGmqooYYaaqihhv3hfw+TpaoAeAAA
|
||||
values:
|
||||
image:
|
||||
tag: v1.0.0-dev
|
||||
|
||||
@@ -44,15 +44,70 @@ string
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>clientConnection</code></br>
|
||||
<code>defaultConfig</code></br>
|
||||
<em>
|
||||
k8s.io/component-base/config/v1alpha1.ClientConnectionConfiguration
|
||||
<a href="#shoot-fleet-agent-service.extensions.config.gardener.cloud/v1alpha1.ProjectConfig">
|
||||
ProjectConfig
|
||||
</a>
|
||||
</em>
|
||||
</td>
|
||||
<td>
|
||||
<em>(Optional)</em>
|
||||
<p>ClientConnection specifies the kubeconfig file and client connection
|
||||
settings for the proxy server to use when communicating with the apiserver.</p>
|
||||
<p>DefaultConfiguration holds default config applied if no project config found</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<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
|
||||
</a>
|
||||
</em>
|
||||
</td>
|
||||
<td>
|
||||
<p>ProjectConfiguration holds configuration overrides for each project</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>healthCheckConfig</code></br>
|
||||
<em>
|
||||
<a href="https://github.com/gardener/gardener/extensions/pkg/controller/healthcheck/config">
|
||||
github.com/gardener/gardener/extensions/pkg/controller/healthcheck/config.HealthCheckConfig
|
||||
</a>
|
||||
</em>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h3 id="shoot-fleet-agent-service.extensions.config.gardener.cloud/v1alpha1.ProjectConfig">ProjectConfig
|
||||
</h3>
|
||||
<p>
|
||||
(<em>Appears on:</em>
|
||||
<a href="#shoot-fleet-agent-service.extensions.config.gardener.cloud/v1alpha1.FleetAgentConfig">FleetAgentConfig</a>)
|
||||
</p>
|
||||
<p>
|
||||
<p>ProjectConfig holds configuration for single project</p>
|
||||
</p>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Field</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<code>kubeconfig</code></br>
|
||||
<em>
|
||||
string
|
||||
</em>
|
||||
</td>
|
||||
<td>
|
||||
<p>Kubeconfig contains base64 encoded kubeconfig</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -77,18 +132,6 @@ string
|
||||
<p>namespace to store clusters registrations in Fleet managers cluster</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>healthCheckConfig</code></br>
|
||||
<em>
|
||||
<a href="https://github.com/gardener/gardener/extensions/pkg/controller/healthcheck/config">
|
||||
github.com/gardener/gardener/extensions/pkg/controller/healthcheck/config.HealthCheckConfig
|
||||
</a>
|
||||
</em>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<hr/>
|
||||
|
||||
@@ -3,7 +3,6 @@ package config
|
||||
import (
|
||||
healthcheckconfig "github.com/gardener/gardener/extensions/pkg/controller/healthcheck/config"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
componentbaseconfig "k8s.io/component-base/config"
|
||||
)
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
@@ -12,15 +11,23 @@ import (
|
||||
type FleetAgentConfig struct {
|
||||
metav1.TypeMeta
|
||||
|
||||
// ClientConnection specifies the kubeconfig file and client connection
|
||||
// settings for the proxy server to use when communicating with the apiserver.
|
||||
ClientConnection *componentbaseconfig.ClientConnectionConfiguration
|
||||
// DefaultConfiguration holds default config applied if no project config found
|
||||
DefaultConfiguration ProjectConfig
|
||||
|
||||
// ProjectConfiguration holds configuration overrides for each project
|
||||
ProjectConfiguration map[string]ProjectConfig
|
||||
|
||||
HealthCheckConfig *healthcheckconfig.HealthCheckConfig
|
||||
}
|
||||
|
||||
// ProjectConfig holds configuration for single project
|
||||
type ProjectConfig struct {
|
||||
// Kubeconfig contains base64 encoded kubeconfig
|
||||
Kubeconfig string
|
||||
|
||||
// labels to use in Fleet Cluster registration
|
||||
Labels map[string]string
|
||||
|
||||
//namespace to store clusters registrations in Fleet managers cluster
|
||||
Namespace string
|
||||
|
||||
HealthCheckConfig *healthcheckconfig.HealthCheckConfig
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package v1alpha1
|
||||
import (
|
||||
healthcheckconfig "github.com/gardener/gardener/extensions/pkg/controller/healthcheck/config"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
componentbaseconfigv1alpha1 "k8s.io/component-base/config/v1alpha1"
|
||||
)
|
||||
|
||||
// +genclient
|
||||
@@ -13,16 +12,23 @@ import (
|
||||
type FleetAgentConfig struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
|
||||
// ClientConnection specifies the kubeconfig file and client connection
|
||||
// settings for the proxy server to use when communicating with the apiserver.
|
||||
// +optional
|
||||
ClientConnection *componentbaseconfigv1alpha1.ClientConnectionConfiguration `json:"clientConnection,omitempty"`
|
||||
// DefaultConfiguration holds default config applied if no project config found
|
||||
DefaultConfiguration ProjectConfig `json:"defaultConfig,omitempty"`
|
||||
|
||||
// ProjectConfiguration holds configuration overrides for each project
|
||||
ProjectConfiguration map[string]ProjectConfig `json:"projectConfig,omitempty"`
|
||||
|
||||
HealthCheckConfig *healthcheckconfig.HealthCheckConfig `json:"healthCheckConfig,omitempty"`
|
||||
}
|
||||
|
||||
// ProjectConfig holds configuration for single project
|
||||
type ProjectConfig struct {
|
||||
// Kubeconfig contains base64 encoded kubeconfig
|
||||
Kubeconfig string `json:"kubeconfig,omitempty"`
|
||||
|
||||
// labels to use in Fleet Cluster registration
|
||||
Labels map[string]string `json:"labels,omitempty"`
|
||||
|
||||
//namespace to store clusters registrations in Fleet managers cluster
|
||||
Namespace string `json:"namespace,omitempty"`
|
||||
|
||||
HealthCheckConfig *healthcheckconfig.HealthCheckConfig `json:"healthCheckConfig,omitempty"`
|
||||
}
|
||||
|
||||
@@ -27,8 +27,6 @@ import (
|
||||
config "github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/apis/config"
|
||||
conversion "k8s.io/apimachinery/pkg/conversion"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
componentbaseconfig "k8s.io/component-base/config"
|
||||
configv1alpha1 "k8s.io/component-base/config/v1alpha1"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -48,13 +46,24 @@ func RegisterConversions(s *runtime.Scheme) error {
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*ProjectConfig)(nil), (*config.ProjectConfig)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1alpha1_ProjectConfig_To_config_ProjectConfig(a.(*ProjectConfig), b.(*config.ProjectConfig), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*config.ProjectConfig)(nil), (*ProjectConfig)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_config_ProjectConfig_To_v1alpha1_ProjectConfig(a.(*config.ProjectConfig), b.(*ProjectConfig), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func autoConvert_v1alpha1_FleetAgentConfig_To_config_FleetAgentConfig(in *FleetAgentConfig, out *config.FleetAgentConfig, s conversion.Scope) error {
|
||||
out.ClientConnection = (*componentbaseconfig.ClientConnectionConfiguration)(unsafe.Pointer(in.ClientConnection))
|
||||
out.Labels = *(*map[string]string)(unsafe.Pointer(&in.Labels))
|
||||
out.Namespace = in.Namespace
|
||||
if err := Convert_v1alpha1_ProjectConfig_To_config_ProjectConfig(&in.DefaultConfiguration, &out.DefaultConfiguration, s); err != nil {
|
||||
return err
|
||||
}
|
||||
out.ProjectConfiguration = *(*map[string]config.ProjectConfig)(unsafe.Pointer(&in.ProjectConfiguration))
|
||||
out.HealthCheckConfig = (*healthcheckconfig.HealthCheckConfig)(unsafe.Pointer(in.HealthCheckConfig))
|
||||
return nil
|
||||
}
|
||||
@@ -65,9 +74,10 @@ func Convert_v1alpha1_FleetAgentConfig_To_config_FleetAgentConfig(in *FleetAgent
|
||||
}
|
||||
|
||||
func autoConvert_config_FleetAgentConfig_To_v1alpha1_FleetAgentConfig(in *config.FleetAgentConfig, out *FleetAgentConfig, s conversion.Scope) error {
|
||||
out.ClientConnection = (*configv1alpha1.ClientConnectionConfiguration)(unsafe.Pointer(in.ClientConnection))
|
||||
out.Labels = *(*map[string]string)(unsafe.Pointer(&in.Labels))
|
||||
out.Namespace = in.Namespace
|
||||
if err := Convert_config_ProjectConfig_To_v1alpha1_ProjectConfig(&in.DefaultConfiguration, &out.DefaultConfiguration, s); err != nil {
|
||||
return err
|
||||
}
|
||||
out.ProjectConfiguration = *(*map[string]ProjectConfig)(unsafe.Pointer(&in.ProjectConfiguration))
|
||||
out.HealthCheckConfig = (*healthcheckconfig.HealthCheckConfig)(unsafe.Pointer(in.HealthCheckConfig))
|
||||
return nil
|
||||
}
|
||||
@@ -76,3 +86,27 @@ func autoConvert_config_FleetAgentConfig_To_v1alpha1_FleetAgentConfig(in *config
|
||||
func Convert_config_FleetAgentConfig_To_v1alpha1_FleetAgentConfig(in *config.FleetAgentConfig, out *FleetAgentConfig, s conversion.Scope) error {
|
||||
return autoConvert_config_FleetAgentConfig_To_v1alpha1_FleetAgentConfig(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1alpha1_ProjectConfig_To_config_ProjectConfig(in *ProjectConfig, out *config.ProjectConfig, s conversion.Scope) error {
|
||||
out.Kubeconfig = in.Kubeconfig
|
||||
out.Labels = *(*map[string]string)(unsafe.Pointer(&in.Labels))
|
||||
out.Namespace = in.Namespace
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1alpha1_ProjectConfig_To_config_ProjectConfig is an autogenerated conversion function.
|
||||
func Convert_v1alpha1_ProjectConfig_To_config_ProjectConfig(in *ProjectConfig, out *config.ProjectConfig, s conversion.Scope) error {
|
||||
return autoConvert_v1alpha1_ProjectConfig_To_config_ProjectConfig(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_config_ProjectConfig_To_v1alpha1_ProjectConfig(in *config.ProjectConfig, out *ProjectConfig, s conversion.Scope) error {
|
||||
out.Kubeconfig = in.Kubeconfig
|
||||
out.Labels = *(*map[string]string)(unsafe.Pointer(&in.Labels))
|
||||
out.Namespace = in.Namespace
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_config_ProjectConfig_To_v1alpha1_ProjectConfig is an autogenerated conversion function.
|
||||
func Convert_config_ProjectConfig_To_v1alpha1_ProjectConfig(in *config.ProjectConfig, out *ProjectConfig, s conversion.Scope) error {
|
||||
return autoConvert_config_ProjectConfig_To_v1alpha1_ProjectConfig(in, out, s)
|
||||
}
|
||||
|
||||
@@ -23,23 +23,18 @@ package v1alpha1
|
||||
import (
|
||||
config "github.com/gardener/gardener/extensions/pkg/controller/healthcheck/config"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
configv1alpha1 "k8s.io/component-base/config/v1alpha1"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *FleetAgentConfig) DeepCopyInto(out *FleetAgentConfig) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
if in.ClientConnection != nil {
|
||||
in, out := &in.ClientConnection, &out.ClientConnection
|
||||
*out = new(configv1alpha1.ClientConnectionConfiguration)
|
||||
**out = **in
|
||||
}
|
||||
if in.Labels != nil {
|
||||
in, out := &in.Labels, &out.Labels
|
||||
*out = make(map[string]string, len(*in))
|
||||
in.DefaultConfiguration.DeepCopyInto(&out.DefaultConfiguration)
|
||||
if in.ProjectConfiguration != nil {
|
||||
in, out := &in.ProjectConfiguration, &out.ProjectConfiguration
|
||||
*out = make(map[string]ProjectConfig, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
(*out)[key] = *val.DeepCopy()
|
||||
}
|
||||
}
|
||||
if in.HealthCheckConfig != nil {
|
||||
@@ -67,3 +62,26 @@ func (in *FleetAgentConfig) DeepCopyObject() runtime.Object {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ProjectConfig) DeepCopyInto(out *ProjectConfig) {
|
||||
*out = *in
|
||||
if in.Labels != nil {
|
||||
in, out := &in.Labels, &out.Labels
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProjectConfig.
|
||||
func (in *ProjectConfig) DeepCopy() *ProjectConfig {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ProjectConfig)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
@@ -23,23 +23,18 @@ package config
|
||||
import (
|
||||
healthcheckconfig "github.com/gardener/gardener/extensions/pkg/controller/healthcheck/config"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
componentbaseconfig "k8s.io/component-base/config"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *FleetAgentConfig) DeepCopyInto(out *FleetAgentConfig) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
if in.ClientConnection != nil {
|
||||
in, out := &in.ClientConnection, &out.ClientConnection
|
||||
*out = new(componentbaseconfig.ClientConnectionConfiguration)
|
||||
**out = **in
|
||||
}
|
||||
if in.Labels != nil {
|
||||
in, out := &in.Labels, &out.Labels
|
||||
*out = make(map[string]string, len(*in))
|
||||
in.DefaultConfiguration.DeepCopyInto(&out.DefaultConfiguration)
|
||||
if in.ProjectConfiguration != nil {
|
||||
in, out := &in.ProjectConfiguration, &out.ProjectConfiguration
|
||||
*out = make(map[string]ProjectConfig, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
(*out)[key] = *val.DeepCopy()
|
||||
}
|
||||
}
|
||||
if in.HealthCheckConfig != nil {
|
||||
@@ -67,3 +62,26 @@ func (in *FleetAgentConfig) DeepCopyObject() runtime.Object {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ProjectConfig) DeepCopyInto(out *ProjectConfig) {
|
||||
*out = *in
|
||||
if in.Labels != nil {
|
||||
in, out := &in.Labels, &out.Labels
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProjectConfig.
|
||||
func (in *ProjectConfig) DeepCopy() *ProjectConfig {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ProjectConfig)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
@@ -16,20 +16,21 @@ package controller
|
||||
|
||||
import (
|
||||
"context"
|
||||
b64 "encoding/base64"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
projConfig "github.com/javamachr/gardener-extension-shoot-fleet-agent/pkg/apis/config"
|
||||
|
||||
"github.com/gardener/gardener/pkg/apis/core/v1beta1"
|
||||
"github.com/gardener/gardener/pkg/extensions"
|
||||
"github.com/go-logr/logr"
|
||||
fleetv1alpha1 "github.com/rancher/fleet/pkg/apis/fleet.cattle.io/v1alpha1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
"k8s.io/client-go/util/retry"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/log"
|
||||
@@ -51,42 +52,42 @@ const KubeconfigSecretName = "kubecfg"
|
||||
// KubeconfigKey key in KubeconfigSecretName secret that holds kubeconfig for Shoot
|
||||
const KubeconfigKey = "kubeconfig"
|
||||
|
||||
// DefaultConfigKey is the name of default config key.
|
||||
const DefaultConfigKey = "default"
|
||||
|
||||
// NewActuator returns an actuator responsible for Extension resources.
|
||||
func NewActuator(config config.Config) extension.Actuator {
|
||||
fleetKubeConfig, _ := b64.StdEncoding.DecodeString(config.FleetAgentConfig.ClientConnection.Kubeconfig)
|
||||
var kubeconfigPath string
|
||||
var err error
|
||||
if kubeconfigPath, err = writeKubeconfigToTempFile(fleetKubeConfig); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fleetClientConfig, _ := clientcmd.BuildConfigFromFlags("", kubeconfigPath)
|
||||
var fleetNamespace = "clusters"
|
||||
if len(config.Namespace) != 0 {
|
||||
fleetNamespace = config.Namespace
|
||||
}
|
||||
fleetManager, err := NewManagerForConfig(fleetClientConfig, fleetNamespace)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
logger := log.Log.WithName(ActuatorName)
|
||||
fleetManagers := initializeFleetManagers(config, logger)
|
||||
|
||||
return &actuator{
|
||||
logger: log.Log.WithName(ActuatorName),
|
||||
logger: logger,
|
||||
serviceConfig: config,
|
||||
fleetManager: fleetManager,
|
||||
fleetManagers: fleetManagers,
|
||||
}
|
||||
}
|
||||
|
||||
type actuator struct {
|
||||
client client.Client
|
||||
config *rest.Config
|
||||
decoder runtime.Decoder
|
||||
fleetManager *FleetManager
|
||||
client client.Client
|
||||
config *rest.Config
|
||||
decoder runtime.Decoder
|
||||
fleetManagers map[string]*FleetManager
|
||||
|
||||
serviceConfig config.Config
|
||||
|
||||
logger logr.Logger
|
||||
}
|
||||
|
||||
// initializeFleetManagers initializes fleet managers for given config
|
||||
func initializeFleetManagers(config config.Config, logger logr.Logger) map[string]*FleetManager {
|
||||
fleetManagers := make(map[string]*FleetManager)
|
||||
fleetManagers[DefaultConfigKey] = createFleetManager(config.DefaultConfiguration, logger)
|
||||
for name, projConfig := range config.ProjectConfiguration {
|
||||
fleetManagers[name] = createFleetManager(projConfig, logger)
|
||||
}
|
||||
return fleetManagers
|
||||
}
|
||||
|
||||
// Reconcile the Extension resource.
|
||||
func (a *actuator) Reconcile(ctx context.Context, ex *extensionsv1alpha1.Extension) error {
|
||||
namespace := ex.GetNamespace()
|
||||
@@ -95,6 +96,9 @@ func (a *actuator) Reconcile(ctx context.Context, ex *extensionsv1alpha1.Extensi
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if isShootedSeedCluster(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 {
|
||||
@@ -112,12 +116,15 @@ func (a *actuator) Delete(ctx context.Context, ex *extensionsv1alpha1.Extension)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if isShootedSeedCluster(cluster) {
|
||||
return nil
|
||||
}
|
||||
a.logger.Info("Component is being deleted", "component", "fleet-agent-management", "namespace", namespace, "cluster", buildCrdName(cluster))
|
||||
err = a.fleetManager.DeleteKubeconfigSecret(ctx, buildCrdName(cluster))
|
||||
err = a.getFleetManager(cluster).DeleteKubeconfigSecret(ctx, buildCrdName(cluster))
|
||||
if err != nil {
|
||||
a.logger.Error(err, "Failed to delete kubeconfig secret for Shoot cluster.", "cluster", buildCrdName(cluster))
|
||||
}
|
||||
err = a.fleetManager.DeleteCluster(ctx, buildCrdName(cluster))
|
||||
err = a.getFleetManager(cluster).DeleteCluster(ctx, buildCrdName(cluster))
|
||||
if err != nil {
|
||||
a.logger.Error(err, "Failed to delete Cluster registration for Shoot cluster.", "cluster", buildCrdName(cluster))
|
||||
}
|
||||
@@ -157,23 +164,26 @@ 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")
|
||||
labels := prepareLabels(cluster, a.serviceConfig, override)
|
||||
registered, err := a.fleetManager.GetCluster(ctx, cluster.Shoot.Name)
|
||||
if !errors.IsNotFound(err) {
|
||||
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, labels)
|
||||
a.updateClusterLabelsInFleet(ctx, registered, cluster, labels)
|
||||
}
|
||||
return
|
||||
}
|
||||
a.registerNewClusterInFleet(ctx, namespace, cluster, labels)
|
||||
}
|
||||
|
||||
func (a *actuator) updateClusterLabelsInFleet(ctx context.Context, clusterRegistration *fleetv1alpha1.Cluster, labels map[string]string) {
|
||||
func (a *actuator) updateClusterLabelsInFleet(ctx context.Context, clusterRegistration *fleetv1alpha1.Cluster, cluster *extensions.Cluster, labels map[string]string) {
|
||||
clusterRegistration.Labels = labels
|
||||
_, err := a.fleetManager.UpdateCluster(ctx, clusterRegistration)
|
||||
_, 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)
|
||||
}
|
||||
@@ -207,10 +217,10 @@ func (a *actuator) registerNewClusterInFleet(ctx context.Context, namespace stri
|
||||
KubeConfigSecret: "kubecfg-" + buildCrdName(cluster),
|
||||
},
|
||||
}
|
||||
if _, err = a.fleetManager.CreateKubeconfigSecret(ctx, &kubeconfigSecret); err != nil {
|
||||
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.fleetManager.CreateCluster(ctx, &clusterRegistration); err != nil {
|
||||
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)
|
||||
@@ -219,17 +229,18 @@ func (a *actuator) registerNewClusterInFleet(ctx context.Context, namespace stri
|
||||
}
|
||||
}
|
||||
|
||||
func prepareLabels(cluster *extensions.Cluster, serviceConfig config.Config, override *config.Config) map[string]string {
|
||||
func prepareLabels(cluster *extensions.Cluster, serviceConfig projConfig.ProjectConfig, override projConfig.ProjectConfig) map[string]string {
|
||||
labels := make(map[string]string)
|
||||
labels["corebundle"] = "true"
|
||||
labels["region"] = cluster.Shoot.Spec.Region
|
||||
labels["cluster"] = cluster.Shoot.Name
|
||||
labels["seed"] = cluster.Seed.Name
|
||||
if len(override.Labels) > 0 { //adds labels from Shoot configuration
|
||||
for key, value := range override.Labels {
|
||||
labels[key] = value
|
||||
}
|
||||
} else {
|
||||
if len(serviceConfig.FleetAgentConfig.Labels) > 0 { //adds labels from default configuration
|
||||
if len(serviceConfig.Labels) > 0 { //adds labels from default configuration
|
||||
for key, value := range serviceConfig.Labels {
|
||||
labels[key] = value
|
||||
}
|
||||
@@ -238,13 +249,41 @@ func prepareLabels(cluster *extensions.Cluster, serviceConfig config.Config, ove
|
||||
return labels
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
func (a *actuator) updateStatus(ctx context.Context, ex *extensionsv1alpha1.Extension) error {
|
||||
return controller.TryUpdateStatus(ctx, retry.DefaultBackoff, a.client, ex, func() error {
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (a *actuator) getFleetManager(cluster *extensions.Cluster) *FleetManager {
|
||||
manager, present := a.fleetManagers[getProjectName(cluster)]
|
||||
if !present {
|
||||
return a.fleetManagers[DefaultConfigKey]
|
||||
}
|
||||
return manager
|
||||
}
|
||||
|
||||
// getProjectConfig return project specific or default config
|
||||
func getProjectConfig(cluster *extensions.Cluster, serviceConfig *config.Config) projConfig.ProjectConfig {
|
||||
name := getProjectName(cluster)
|
||||
projectConfig, present := serviceConfig.ProjectConfiguration[name]
|
||||
if !present {
|
||||
return serviceConfig.DefaultConfiguration
|
||||
}
|
||||
return projectConfig
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// isShootedSeedCluster checks if clusters purpose is Infrastructure
|
||||
func isShootedSeedCluster(cluster *extensions.Cluster) bool {
|
||||
return *cluster.Shoot.Spec.Purpose == v1beta1.ShootPurposeInfrastructure
|
||||
}
|
||||
|
||||
// getProjectName extracts project name from Shoots namespace
|
||||
func getProjectName(cluster *extensions.Cluster) string {
|
||||
return cluster.Shoot.Namespace[strings.LastIndex(cluster.Shoot.Namespace, "-")+1:]
|
||||
}
|
||||
|
||||
@@ -2,7 +2,13 @@ package controller
|
||||
|
||||
import (
|
||||
"context"
|
||||
b64 "encoding/base64"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
|
||||
"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"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
@@ -66,3 +72,31 @@ func (f *FleetManager) CreateKubeconfigSecret(ctx context.Context, secret *corev
|
||||
func (f *FleetManager) DeleteKubeconfigSecret(ctx context.Context, secretName string) error {
|
||||
return f.secretClient.CoreV1().Secrets(f.namespace).Delete(ctx, secretName, metav1.DeleteOptions{})
|
||||
}
|
||||
|
||||
// createFleetManager creates fleet manager for given configuration
|
||||
func createFleetManager(config fleetConfig.ProjectConfig, logger logr.Logger) *FleetManager {
|
||||
logger.Info("Creating Fleet manager for config", "config", config)
|
||||
fleetKubeConfig, err := b64.StdEncoding.DecodeString(config.Kubeconfig)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
var kubeconfigPath string
|
||||
if kubeconfigPath, err = writeKubeconfigToTempFile(fleetKubeConfig); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
logger.Info("Written kubeconfig to temp", "file", kubeconfigPath)
|
||||
fleetClientConfig, err := clientcmd.BuildConfigFromFlags("", kubeconfigPath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
logger.Info("Fleet k8s client successfully built.")
|
||||
var fleetNamespace = "clusters"
|
||||
if len(config.Namespace) != 0 {
|
||||
fleetNamespace = config.Namespace
|
||||
}
|
||||
fleetManager, err := NewManagerForConfig(fleetClientConfig, fleetNamespace)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return fleetManager
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user