-
Notifications
You must be signed in to change notification settings - Fork 150
Bug 1764704: Sync router-ca to the console namespace #328
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,138 @@ | ||
| package resourcesyncdestination | ||
|
|
||
| import ( | ||
| "fmt" | ||
| "time" | ||
|
|
||
| metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
| "k8s.io/apimachinery/pkg/util/runtime" | ||
| "k8s.io/apimachinery/pkg/util/wait" | ||
| coreinformersv1 "k8s.io/client-go/informers/core/v1" | ||
| coreclientv1 "k8s.io/client-go/kubernetes/typed/core/v1" | ||
| "k8s.io/client-go/tools/cache" | ||
| "k8s.io/client-go/util/workqueue" | ||
| "k8s.io/klog" | ||
|
|
||
| operatorsv1 "github.com/openshift/api/operator/v1" | ||
| operatorclientv1 "github.com/openshift/client-go/operator/clientset/versioned/typed/operator/v1" | ||
| operatorinformersv1 "github.com/openshift/client-go/operator/informers/externalversions/operator/v1" | ||
| "github.com/openshift/console-operator/pkg/api" | ||
| "github.com/openshift/library-go/pkg/operator/events" | ||
| ) | ||
|
|
||
| const ( | ||
| controllerWorkQueueKey = "resource-sync-destination-work-queue-key" | ||
| controllerName = "ConsoleResourceSyncDestinationController" | ||
| ) | ||
|
|
||
| type ResourceSyncDestinationController struct { | ||
| operatorConfigClient operatorclientv1.ConsoleInterface | ||
| configMapClient coreclientv1.ConfigMapsGetter | ||
| // events | ||
| cachesToSync []cache.InformerSynced | ||
| queue workqueue.RateLimitingInterface | ||
| recorder events.Recorder | ||
| } | ||
|
|
||
| func NewResourceSyncDestinationController( | ||
| // operatorconfig | ||
| operatorConfigClient operatorclientv1.ConsoleInterface, | ||
| operatorConfigInformer operatorinformersv1.ConsoleInformer, | ||
| // configmap | ||
| corev1Client coreclientv1.CoreV1Interface, | ||
| configMapInformer coreinformersv1.ConfigMapInformer, | ||
| // events | ||
| recorder events.Recorder, | ||
| ) *ResourceSyncDestinationController { | ||
| corev1Client.ConfigMaps(api.OpenShiftConsoleNamespace) | ||
|
|
||
| ctrl := &ResourceSyncDestinationController{ | ||
| operatorConfigClient: operatorConfigClient, | ||
| configMapClient: corev1Client, | ||
| // events | ||
| recorder: recorder, | ||
| cachesToSync: nil, | ||
| queue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), controllerName), | ||
| } | ||
|
|
||
| configMapInformer.Informer().AddEventHandler(ctrl.newEventHandler()) | ||
| operatorConfigInformer.Informer().AddEventHandler(ctrl.newEventHandler()) | ||
| ctrl.cachesToSync = append(ctrl.cachesToSync, | ||
| operatorConfigInformer.Informer().HasSynced, | ||
| configMapInformer.Informer().HasSynced, | ||
| ) | ||
|
|
||
| return ctrl | ||
| } | ||
|
|
||
| func (c *ResourceSyncDestinationController) sync() error { | ||
| operatorConfig, err := c.operatorConfigClient.Get(api.ConfigResourceName, metav1.GetOptions{}) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| switch operatorConfig.Spec.ManagementState { | ||
| case operatorsv1.Managed: | ||
| klog.V(4).Infoln("console is in a managed state: syncing router-ca configmap") | ||
| case operatorsv1.Unmanaged: | ||
| klog.V(4).Infoln("console is in an unmanaged state: skipping router-ca configmap sync") | ||
| return nil | ||
| case operatorsv1.Removed: | ||
| klog.V(4).Infoln("console is in an removed state: removing synced router-ca configmap") | ||
| return c.removeRouterCAConfigMap() | ||
| default: | ||
| return fmt.Errorf("unknown state: %v", operatorConfig.Spec.ManagementState) | ||
| } | ||
|
|
||
| return err | ||
| } | ||
|
|
||
| func (c *ResourceSyncDestinationController) removeRouterCAConfigMap() error { | ||
| klog.V(2).Info("deleting router-ca configmap") | ||
| defer klog.V(2).Info("finished deleting router-ca configmap") | ||
| return c.configMapClient.ConfigMaps(api.OpenShiftConsoleNamespace).Delete(api.RouterCAConfigMapName, &metav1.DeleteOptions{}) | ||
| } | ||
|
|
||
| func (c *ResourceSyncDestinationController) Run(workers int, stopCh <-chan struct{}) { | ||
| defer runtime.HandleCrash() | ||
| defer c.queue.ShutDown() | ||
| klog.Infof("starting %v", controllerName) | ||
| defer klog.Infof("shutting down %v", controllerName) | ||
| if !cache.WaitForCacheSync(stopCh, c.cachesToSync...) { | ||
| klog.Infoln("caches did not sync") | ||
| runtime.HandleError(fmt.Errorf("caches did not sync")) | ||
| return | ||
| } | ||
| // only start one worker | ||
| go wait.Until(c.runWorker, time.Second, stopCh) | ||
| <-stopCh | ||
| } | ||
|
|
||
| func (c *ResourceSyncDestinationController) runWorker() { | ||
| for c.processNextWorkItem() { | ||
| } | ||
| } | ||
|
|
||
| func (c *ResourceSyncDestinationController) processNextWorkItem() bool { | ||
| processKey, quit := c.queue.Get() | ||
| if quit { | ||
| return false | ||
| } | ||
| defer c.queue.Done(processKey) | ||
| err := c.sync() | ||
| if err == nil { | ||
| c.queue.Forget(processKey) | ||
| return true | ||
| } | ||
| runtime.HandleError(fmt.Errorf("%v failed with : %v", processKey, err)) | ||
| c.queue.AddRateLimited(processKey) | ||
| return true | ||
| } | ||
|
|
||
| func (c *ResourceSyncDestinationController) newEventHandler() cache.ResourceEventHandler { | ||
| return cache.ResourceEventHandlerFuncs{ | ||
| AddFunc: func(obj interface{}) { c.queue.Add(controllerWorkQueueKey) }, | ||
| UpdateFunc: func(old, new interface{}) { c.queue.Add(controllerWorkQueueKey) }, | ||
| DeleteFunc: func(obj interface{}) { c.queue.Add(controllerWorkQueueKey) }, | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -95,6 +95,9 @@ func (co *consoleOperator) sync_v400(updatedOperatorConfig *operatorv1.Console, | |
| // The sync loop may not settle, we are unable to honor it in current state. | ||
| status.HandleProgressingOrDegraded(updatedOperatorConfig, "CustomLogoSync", customLogoErrReason, customLogoError) | ||
|
|
||
| routerCAConfigMap, routerCAErrReason, routerCAError := co.ValidateRouterCAConfigMap() | ||
| status.HandleProgressingOrDegraded(updatedOperatorConfig, "RouterCAValidation", routerCAErrReason, routerCAError) | ||
|
|
||
| sec, secChanged, secErr := co.SyncSecret(set.Operator) | ||
| toUpdate = toUpdate || secChanged | ||
| status.HandleProgressingOrDegraded(updatedOperatorConfig, "OAuthClientSecretSync", "FailedApply", secErr) | ||
|
|
@@ -109,7 +112,7 @@ func (co *consoleOperator) sync_v400(updatedOperatorConfig *operatorv1.Console, | |
| return oauthErr | ||
| } | ||
|
|
||
| actualDeployment, depChanged, depErrReason, depErr := co.SyncDeployment(set.Operator, cm, serviceCAConfigMap, trustedCAConfigMap, sec, rt, set.Proxy, customLogoCanMount) | ||
| actualDeployment, depChanged, depErrReason, depErr := co.SyncDeployment(set.Operator, cm, serviceCAConfigMap, routerCAConfigMap, trustedCAConfigMap, sec, rt, set.Proxy, customLogoCanMount) | ||
| toUpdate = toUpdate || depChanged | ||
| status.HandleProgressingOrDegraded(updatedOperatorConfig, "DeploymentSync", depErrReason, depErr) | ||
| if depErr != nil { | ||
|
|
@@ -231,13 +234,14 @@ func (co *consoleOperator) SyncDeployment( | |
| operatorConfig *operatorv1.Console, | ||
| cm *corev1.ConfigMap, | ||
| serviceCAConfigMap *corev1.ConfigMap, | ||
| routerCAConfigMap *corev1.ConfigMap, | ||
| trustedCAConfigMap *corev1.ConfigMap, | ||
| sec *corev1.Secret, | ||
| rt *routev1.Route, | ||
| proxyConfig *configv1.Proxy, | ||
| canMountCustomLogo bool) (consoleDeployment *appsv1.Deployment, changed bool, reason string, err error) { | ||
|
|
||
| requiredDeployment := deploymentsub.DefaultDeployment(operatorConfig, cm, serviceCAConfigMap, trustedCAConfigMap, sec, rt, proxyConfig, canMountCustomLogo) | ||
| requiredDeployment := deploymentsub.DefaultDeployment(operatorConfig, cm, serviceCAConfigMap, routerCAConfigMap, trustedCAConfigMap, sec, rt, proxyConfig, canMountCustomLogo) | ||
| expectedGeneration := getDeploymentGeneration(co) | ||
| genChanged := operatorConfig.ObjectMeta.Generation != operatorConfig.Status.ObservedGeneration | ||
|
|
||
|
|
@@ -307,7 +311,18 @@ func (co *consoleOperator) SyncConfigMap( | |
| return nil, false, "FailedManagedConfig", mcErr | ||
| } | ||
|
|
||
| defaultConfigmap, _, err := configmapsub.DefaultConfigMap(operatorConfig, consoleConfig, managedConfig, infrastructureConfig, consoleRoute) | ||
| useDefaultCAFile := true | ||
| // We are syncing the `router-ca` configmap from `openshift-config-managed` to `openshift-console`. | ||
| // `router-ca` is only published in `openshift-config-managed` if an operator-generated default certificate is used. | ||
| // It will not exist if all ingresscontrollers user admin-provided default certificates. | ||
| // If the `router-ca` configmap in `openshift-console` exist we should mount that to the console container, | ||
| // otherwise default to `/var/run/secrets/kubernetes.io/serviceaccount/ca.crt` | ||
| _, rcaErr := co.configMapClient.ConfigMaps(api.OpenShiftConsoleNamespace).Get(api.RouterCAConfigMapName, metav1.GetOptions{}) | ||
| if rcaErr != nil && apierrors.IsNotFound(rcaErr) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what about other errors? this only covers 404.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is there anything else that would matter?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. was thinking about it and wasn't really sure if any other errors should matter in this context... saying that not really sure what should be the
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe we should just add a log and call it good: if rcaErr != nil {
klog.V(4).Infof("router-ca GET error: %s",rcaErr)
}Agree with you, probably doesn't matter, unless there is some funny state we aren't thinking about. But a |
||
| useDefaultCAFile = false | ||
| } | ||
|
|
||
| defaultConfigmap, _, err := configmapsub.DefaultConfigMap(operatorConfig, consoleConfig, managedConfig, infrastructureConfig, consoleRoute, useDefaultCAFile) | ||
| if err != nil { | ||
| return nil, false, "FailedConsoleConfigBuilder", err | ||
| } | ||
|
|
@@ -430,6 +445,20 @@ func (c *consoleOperator) SyncCustomLogoConfigMap(operatorConfig *operatorsv1.Co | |
| return okToMount, reason, err | ||
| } | ||
|
|
||
| func (c *consoleOperator) ValidateRouterCAConfigMap() (routerCA *corev1.ConfigMap, reason string, err error) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Pondering if this can live in the new controller instead of adding it here.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, probably not now yet, as the |
||
| routerCAConfigMap, err := c.configMapClient.ConfigMaps(api.OpenShiftConsoleNamespace).Get(api.RouterCAConfigMapName, metav1.GetOptions{}) | ||
| if err != nil { | ||
| klog.V(4).Infoln("router-ca configmap not found") | ||
| return nil, "FailedGet", fmt.Errorf("router-ca configmap not found") | ||
| } | ||
|
|
||
| _, caBundle := routerCAConfigMap.Data["ca-bundle.crt"] | ||
| if !caBundle { | ||
| return nil, "MissingRouterCABundle", fmt.Errorf("router-ca configmap is missing ca-bundle.crt data") | ||
| } | ||
| return routerCAConfigMap, "", nil | ||
| } | ||
|
|
||
| // on each pass of the operator sync loop, we need to check the | ||
| // operator config for a custom logo. If this has been set, then | ||
| // we notify the resourceSyncer that it needs to start watching this | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It appears we have been missing this pkg in our unit tests
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not ideal to have to manually add these eh? Prob should update this script to loop the directory instead, but looks good for now.