Skip to content

Commit 8a0e283

Browse files
committed
Make cluster-proxy work with multicluster-controlplane
Signed-off-by: Tamal Saha <tamal@appscode.com>
1 parent b72629a commit 8a0e283

9 files changed

Lines changed: 127 additions & 39 deletions

File tree

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
*.out
1313

1414
# Dependency directories (remove the comment below to include it)
15-
# vendor/
15+
vendor/
1616

1717
/apiserver.local.config
1818
/bin

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11

22
# Image URL to use all building/pushing image targets
3-
IMG ?= controller:latest
43
IMAGE_REGISTRY_NAME ?= quay.io/open-cluster-management
54
IMAGE_NAME = cluster-proxy
65
IMAGE_TAG ?= latest
6+
IMG ?= $(IMAGE_REGISTRY_NAME)/$(IMAGE_NAME):$(IMAGE_TAG)
77
E2E_TEST_CLUSTER_NAME ?= loopback
88
# Produce CRDs that work back to Kubernetes 1.11 (no version conversion)
99
CRD_OPTIONS ?= "crd:crdVersions={v1},allowDangerousTypes=true,generateEmbeddedObjectMeta=true"

charts/cluster-proxy/templates/manager-deployment.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ spec:
1717
containers:
1818
- name: manager
1919
image: {{ .Values.registry }}/{{ .Values.image }}:{{ .Values.tag | default (print "v" .Chart.Version) }}
20-
imagePullPolicy: IfNotPresent
20+
imagePullPolicy: Always
2121
command:
2222
- /manager
2323
args:

charts/cluster-proxy/values.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
# Image registry
2-
registry: quay.io/open-cluster-management
2+
registry: ghcr.io/kluster-manager
33

44
# Image of the cluster-gateway instances
55
image: cluster-proxy
66

77
# Image tag
8-
tag:
8+
tag: latest
99

1010
# Number of replicas
1111
replicas: 1
1212

1313
spokeAddonNamespace: "open-cluster-management-cluster-proxy"
1414

15-
proxyServerImage: quay.io/open-cluster-management/cluster-proxy
16-
proxyAgentImage: quay.io/open-cluster-management/cluster-proxy
15+
proxyServerImage: ghcr.io/kluster-manager/cluster-proxy
16+
proxyAgentImage: ghcr.io/kluster-manager/cluster-proxy
1717

1818
proxyServer:
1919
entrypointLoadBalancer: false

cmd/addon-manager/main.go

Lines changed: 58 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ import (
3131
"k8s.io/client-go/informers"
3232
"k8s.io/client-go/kubernetes"
3333
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
34+
"k8s.io/client-go/rest"
35+
"k8s.io/client-go/tools/clientcmd"
3436
"k8s.io/klog/v2"
3537
"k8s.io/klog/v2/textlogger"
3638
"open-cluster-management.io/addon-framework/pkg/addonmanager"
@@ -46,6 +48,8 @@ import (
4648
"open-cluster-management.io/cluster-proxy/pkg/proxyserver/controllers"
4749
"open-cluster-management.io/cluster-proxy/pkg/proxyserver/operator/authentication/selfsigned"
4850
ctrl "sigs.k8s.io/controller-runtime"
51+
"sigs.k8s.io/controller-runtime/pkg/client"
52+
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
4953
"sigs.k8s.io/controller-runtime/pkg/healthz"
5054
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
5155
//+kubebuilder:scaffold:imports
@@ -72,6 +76,7 @@ func main() {
7276
var signerSecretNamespace, signerSecretName string
7377
var agentInstallAll bool
7478
var enableKubeApiProxy bool
79+
var mcKubeconfig string
7580

7681
logger := textlogger.NewLogger(textlogger.NewConfig())
7782
klog.SetOutput(os.Stdout)
@@ -95,13 +100,30 @@ func main() {
95100
"Configure the install strategy of agent on managed clusters. "+
96101
"Enabling this will automatically install agent on all managed cluster.")
97102
flag.BoolVar(&enableKubeApiProxy, "enable-kube-api-proxy", true, "Enable proxy to agent kube-apiserver")
103+
flag.StringVar(&mcKubeconfig, "multicluster-kubeconfig", "",
104+
"The path to multicluster-controlplane kubeconfig")
98105

99106
flag.Parse()
100107

101108
// pipe controller-runtime logs to klog
102109
ctrl.SetLogger(logger)
103110

104-
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
111+
var mcConfig, hostConfig *rest.Config
112+
113+
if mcKubeconfig != "" {
114+
var err error
115+
mcConfig, err = clientcmd.BuildConfigFromFlags("", mcKubeconfig)
116+
if err != nil {
117+
setupLog.Error(err, "unable to build multicluster rest config")
118+
os.Exit(1)
119+
}
120+
hostConfig = ctrl.GetConfigOrDie()
121+
} else {
122+
hostConfig = ctrl.GetConfigOrDie()
123+
mcConfig = hostConfig
124+
}
125+
126+
mgr, err := ctrl.NewManager(mcConfig, ctrl.Options{
105127
Scheme: scheme,
106128
Metrics: metricsserver.Options{BindAddress: metricsAddr},
107129
HealthProbeBindAddress: probeAddr,
@@ -119,6 +141,12 @@ func main() {
119141
os.Exit(1)
120142
}
121143

144+
hostClient, err := kubernetes.NewForConfig(hostConfig)
145+
if err != nil {
146+
setupLog.Error(err, "unable to set up host kubernetes native client")
147+
os.Exit(1)
148+
}
149+
122150
nativeClient, err := kubernetes.NewForConfig(mgr.GetConfig())
123151
if err != nil {
124152
setupLog.Error(err, "unable to set up kubernetes native client")
@@ -147,22 +175,30 @@ func main() {
147175
}
148176

149177
informerFactory := externalversions.NewSharedInformerFactory(client, 0)
150-
nativeInformer := informers.NewSharedInformerFactoryWithOptions(nativeClient, 0)
178+
hostInformer := informers.NewSharedInformerFactoryWithOptions(hostClient, 0, informers.WithNamespace(signerSecretNamespace))
151179

152180
// loading self-signer
153181
selfSigner, err := selfsigned.NewSelfSignerFromSecretOrGenerate(
154-
nativeClient, signerSecretNamespace, signerSecretName)
182+
hostClient, signerSecretNamespace, signerSecretName)
155183
if err != nil {
156184
setupLog.Error(err, "failed loading self-signer")
157185
os.Exit(1)
158186
}
159187

188+
hostKubeClient, err := newHostClient(hostConfig)
189+
if err != nil {
190+
setupLog.Error(err, "failed create host KubeClient")
191+
os.Exit(1)
192+
}
193+
160194
if err := controllers.RegisterClusterManagementAddonReconciler(
161195
mgr,
162196
selfSigner,
163-
nativeClient,
164-
nativeInformer.Core().V1().Secrets(),
197+
hostKubeClient,
198+
hostClient,
199+
hostInformer.Core().V1().Secrets(),
165200
supportsV1CSR,
201+
mcKubeconfig != "",
166202
); err != nil {
167203
setupLog.Error(err, "unable to create controller", "controller", "ClusterManagementAddonReconciler")
168204
os.Exit(1)
@@ -195,6 +231,7 @@ func main() {
195231
supportsV1CSR,
196232
mgr.GetClient(),
197233
nativeClient,
234+
hostClient,
198235
agentInstallAll,
199236
enableKubeApiProxy,
200237
addonClient,
@@ -212,7 +249,7 @@ func main() {
212249
ctx, cancel := context.WithCancel(ctrl.SetupSignalHandler())
213250
defer cancel()
214251
go informerFactory.Start(ctx.Done())
215-
go nativeInformer.Start(ctx.Done())
252+
go hostInformer.Start(ctx.Done())
216253
go func() {
217254
if err := addonManager.Start(ctx); err != nil {
218255
setupLog.Error(err, "unable to start addon manager")
@@ -225,3 +262,18 @@ func main() {
225262
os.Exit(1)
226263
}
227264
}
265+
266+
func newHostClient(hostConfig *rest.Config) (client.Client, error) {
267+
hc, err := rest.HTTPClientFor(hostConfig)
268+
if err != nil {
269+
return nil, err
270+
}
271+
mapper, err := apiutil.NewDynamicRESTMapper(hostConfig, hc)
272+
if err != nil {
273+
return nil, err
274+
}
275+
return client.New(hostConfig, client.Options{
276+
Scheme: clientgoscheme.Scheme,
277+
Mapper: mapper,
278+
})
279+
}

pkg/proxyagent/agent/agent.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ func NewAgentAddon(
5353
v1CSRSupported bool,
5454
runtimeClient client.Client,
5555
nativeClient kubernetes.Interface,
56+
hostClient kubernetes.Interface,
5657
agentInstallAll bool,
5758
enableKubeApiProxy bool,
5859
addonClient addonclient.Interface) (agent.AgentAddon, error) {
@@ -134,7 +135,7 @@ func NewAgentAddon(
134135
utils.AddOnDeploymentConfigGVR,
135136
).
136137
WithGetValuesFuncs(
137-
GetClusterProxyValueFunc(runtimeClient, nativeClient, signerNamespace, caCertData, v1CSRSupported, enableKubeApiProxy),
138+
GetClusterProxyValueFunc(runtimeClient, hostClient, signerNamespace, caCertData, v1CSRSupported, enableKubeApiProxy),
138139
addonfactory.GetAddOnDeploymentConfigValues(
139140
utils.NewAddOnDeploymentConfigGetter(addonClient),
140141
toAgentAddOnChartValues(caCertData),

pkg/proxyagent/agent/manifests/charts/addon-agent/templates/addon-agent-deployment.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ spec:
3838
containers:
3939
- name: proxy-agent
4040
image: {{ .Values.proxyAgentImage }}
41-
imagePullPolicy: IfNotPresent
41+
imagePullPolicy: Always
4242
command:
4343
- /proxy-agent
4444
args:
@@ -90,7 +90,7 @@ spec:
9090
cpu: "300m"
9191
- name: addon-agent
9292
image: {{ .Values.registry }}/{{ .Values.image }}:{{ .Values.tag }}
93-
imagePullPolicy: IfNotPresent
93+
imagePullPolicy: Always
9494
command:
9595
- /agent
9696
args:

pkg/proxyserver/controllers/managedproxyconfiguration_controller.go

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"github.com/openshift/library-go/pkg/operator/events"
1919
"github.com/pkg/errors"
2020

21+
appsv1 "k8s.io/api/apps/v1"
2122
corev1 "k8s.io/api/core/v1"
2223
"k8s.io/apimachinery/pkg/api/equality"
2324
apierrors "k8s.io/apimachinery/pkg/api/errors"
@@ -47,12 +48,15 @@ var log = ctrl.Log.WithName("ClusterManagementAddonReconciler")
4748
func RegisterClusterManagementAddonReconciler(
4849
mgr manager.Manager,
4950
selfSigner selfsigned.SelfSigner,
51+
hostClient client.Client,
5052
nativeClient kubernetes.Interface,
5153
secretInformer informercorev1.SecretInformer,
5254
supportsV1CSR bool,
55+
mcMode bool,
5356
) error {
5457
r := &ManagedProxyConfigurationReconciler{
5558
Client: mgr.GetClient(),
59+
HostClient: hostClient,
5660
SelfSigner: selfSigner,
5761
CAPair: selfSigner.CA(),
5862
newCertRotatorFunc: func(namespace, name string, sans ...string) selfsigned.CertRotation {
@@ -72,12 +76,14 @@ func RegisterClusterManagementAddonReconciler(
7276
EventRecorder: events.NewInMemoryRecorder("ClusterManagementAddonReconciler"),
7377

7478
supportsV1CSR: supportsV1CSR,
79+
mcMode: mcMode,
7580
}
7681
return r.SetupWithManager(mgr)
7782
}
7883

7984
type ManagedProxyConfigurationReconciler struct {
80-
client.Client
85+
Client client.Client
86+
HostClient client.Client
8187
SelfSigner selfsigned.SelfSigner
8288
CAPair *crypto.CA
8389
SecretLister corev1listers.SecretLister
@@ -88,6 +94,7 @@ type ManagedProxyConfigurationReconciler struct {
8894

8995
newCertRotatorFunc func(namespace, name string, sans ...string) selfsigned.CertRotation
9096
supportsV1CSR bool
97+
mcMode bool
9198
}
9299

93100
func (c *ManagedProxyConfigurationReconciler) SetupWithManager(mgr ctrl.Manager) error {
@@ -171,12 +178,40 @@ func (c *ManagedProxyConfigurationReconciler) deployProxyServer(config *proxyv1a
171178
newProxyServerRole(config),
172179
newProxyServerRoleBinding(config),
173180
}
181+
if c.mcMode {
182+
var manager appsv1.Deployment
183+
key := client.ObjectKey{
184+
Namespace: config.Spec.ProxyServer.Namespace,
185+
Name: "cluster-proxy-addon-manager",
186+
}
187+
if err := c.HostClient.Get(context.Background(), key, &manager); err == nil {
188+
ownerRef := metav1.NewControllerRef(&manager, schema.GroupVersionKind{
189+
Group: "apps",
190+
Version: "v1",
191+
Kind: "Deployment",
192+
})
193+
for i, resource := range resources {
194+
resource.SetOwnerReferences([]metav1.OwnerReference{
195+
*ownerRef,
196+
})
197+
resources[i] = resource
198+
}
199+
}
200+
} else {
201+
for i, resource := range resources {
202+
resource.SetOwnerReferences([]metav1.OwnerReference{
203+
newOwnerReference(config),
204+
})
205+
resources[i] = resource
206+
}
207+
}
208+
174209
anyCreated := false
175210
createdKinds := sets.NewString()
176211
anyUpdated := false
177212
updatedKinds := sets.NewString()
178213
for _, resource := range resources {
179-
gvks, _, err := c.Scheme().ObjectKinds(resource)
214+
gvks, _, err := c.HostClient.Scheme().ObjectKinds(resource)
180215
if err != nil {
181216
return false, err
182217
}
@@ -224,7 +259,7 @@ func (c *ManagedProxyConfigurationReconciler) ensure(incomingGeneration int64, g
224259
// create if it doesn't exist
225260
current := &unstructured.Unstructured{}
226261
current.SetGroupVersionKind(gvk)
227-
if err := c.Client.Get(
262+
if err := c.HostClient.Get(
228263
context.TODO(),
229264
types.NamespacedName{
230265
Namespace: resource.GetNamespace(),
@@ -239,7 +274,7 @@ func (c *ManagedProxyConfigurationReconciler) ensure(incomingGeneration int64, g
239274
)
240275
}
241276
// if not found, then create
242-
if err := c.Client.Create(context.TODO(), resource); err != nil {
277+
if err := c.HostClient.Create(context.TODO(), resource); err != nil {
243278
if !apierrors.IsAlreadyExists(err) {
244279
return false, false, errors.Wrapf(err,
245280
"failed to create resource kind: %s, namespace: %s, name %s",
@@ -270,7 +305,7 @@ func (c *ManagedProxyConfigurationReconciler) ensure(incomingGeneration int64, g
270305
// update if generation bumped
271306
if !created && int(incomingGeneration) > currentGeneration {
272307
resource.SetResourceVersion(current.GetResourceVersion())
273-
if err := c.Client.Update(context.TODO(), resource); err != nil {
308+
if err := c.HostClient.Update(context.TODO(), resource); err != nil {
274309
if apierrors.IsConflict(err) {
275310
return c.ensure(incomingGeneration, gvk, resource)
276311
}
@@ -353,7 +388,7 @@ func (c *ManagedProxyConfigurationReconciler) ensureEntrypoint(config *proxyv1al
353388
},
354389
},
355390
}
356-
if err := c.Client.Create(context.TODO(), proxyService); err != nil {
391+
if err := c.HostClient.Create(context.TODO(), proxyService); err != nil {
357392
if !apierrors.IsAlreadyExists(err) {
358393
return "", errors.Wrapf(err, "failed to ensure entrypoint service for proxy-server")
359394
}
@@ -451,11 +486,11 @@ func (c *ManagedProxyConfigurationReconciler) ensureBasicResources(config *proxy
451486
}
452487

453488
func (c *ManagedProxyConfigurationReconciler) ensureNamespace(config *proxyv1alpha1.ManagedProxyConfiguration) error {
454-
if err := c.Client.Get(context.TODO(), types.NamespacedName{
489+
if err := c.HostClient.Get(context.TODO(), types.NamespacedName{
455490
Name: config.Spec.ProxyServer.Namespace,
456491
}, &corev1.Namespace{}); err != nil {
457492
if apierrors.IsNotFound(err) {
458-
if err := c.Client.Create(context.TODO(), &corev1.Namespace{
493+
if err := c.HostClient.Create(context.TODO(), &corev1.Namespace{
459494
ObjectMeta: metav1.ObjectMeta{
460495
Name: config.Spec.ProxyServer.Namespace,
461496
},

0 commit comments

Comments
 (0)