Skip to content

Commit f4726dd

Browse files
committed
Rename sync_v400 to sync and break down into smaller files
1 parent ca5f378 commit f4726dd

14 files changed

+901
-746
lines changed

pkg/console/operator/operator.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ func (c *consoleOperator) handleSync(ctx context.Context, controllerContext fact
378378
return fmt.Errorf("console is in an unknown state: %v", updatedStatus.Spec.ManagementState)
379379
}
380380

381-
return c.sync_v400(ctx, controllerContext, updatedStatus, configs)
381+
return c.sync(ctx, controllerContext, updatedStatus, configs)
382382
}
383383

384384
// this may need to move to sync_v400 if versions ever have custom delete logic

pkg/console/operator/sync.go

+251
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
package operator
2+
3+
import (
4+
"context"
5+
"errors"
6+
"fmt"
7+
"net/url"
8+
"os"
9+
10+
// kube
11+
corev1 "k8s.io/api/core/v1"
12+
apierrors "k8s.io/apimachinery/pkg/api/errors"
13+
"k8s.io/klog/v2"
14+
15+
// openshift
16+
configv1 "github.com/openshift/api/config/v1"
17+
operatorv1 "github.com/openshift/api/operator/v1"
18+
routev1 "github.com/openshift/api/route/v1"
19+
"github.com/openshift/library-go/pkg/controller/factory"
20+
21+
// operator
22+
"github.com/openshift/console-operator/pkg/api"
23+
"github.com/openshift/console-operator/pkg/console/status"
24+
deploymentsub "github.com/openshift/console-operator/pkg/console/subresource/deployment"
25+
routesub "github.com/openshift/console-operator/pkg/console/subresource/route"
26+
secretsub "github.com/openshift/console-operator/pkg/console/subresource/secret"
27+
)
28+
29+
// The sync loop starts from zero and works its way through the requirements for a running console.
30+
// If at any point something is missing, it creates/updates that piece and immediately dies.
31+
// The next loop will pick up where they previous left off and move the process forward one step.
32+
// This ensures the logic is simpler as we do not have to handle coordination between objects within
33+
// the loop.
34+
func (co *consoleOperator) sync(ctx context.Context, controllerContext factory.SyncContext, updatedOperatorConfig *operatorv1.Console, set configSet) error {
35+
klog.V(4).Infoln("running sync loop 4.0.0")
36+
37+
var (
38+
statusHandler = status.NewStatusHandler(co.operatorClient)
39+
// track changes, may trigger ripples & update operator config or console config status
40+
toUpdate = false
41+
consoleRoute *routev1.Route
42+
consoleURL *url.URL
43+
)
44+
45+
if len(set.Operator.Spec.Ingress.ConsoleURL) == 0 {
46+
routeName := api.OpenShiftConsoleRouteName
47+
routeConfig := routesub.NewRouteConfig(updatedOperatorConfig, set.Ingress, routeName)
48+
if routeConfig.IsCustomHostnameSet() {
49+
routeName = api.OpenshiftConsoleCustomRouteName
50+
}
51+
52+
route, url, routeReasonErr, routeErr := routesub.GetActiveRouteInfo(co.routeLister, routeName)
53+
// TODO: this controller is no longer responsible for syncing the route.
54+
// however, the route is essential for several of the components below.
55+
// - the loop should exit early and wait until the RouteSyncController creates the route.
56+
// there is nothing new in this flow, other than 2 controllers now look
57+
// at the same resource.
58+
// - RouteSyncController is responsible for updates
59+
// - ConsoleOperatorController (future ConsoleDeploymentController) is responsible for reads only.
60+
statusHandler.AddConditions(status.HandleProgressingOrDegraded("SyncLoopRefresh", routeReasonErr, routeErr))
61+
if routeErr != nil {
62+
return statusHandler.FlushAndReturn(routeErr)
63+
}
64+
consoleRoute = route
65+
consoleURL = url
66+
} else {
67+
url, err := url.Parse(set.Operator.Spec.Ingress.ConsoleURL)
68+
if err != nil {
69+
return statusHandler.FlushAndReturn(fmt.Errorf("failed to get console url: %w", err))
70+
}
71+
consoleURL = url
72+
}
73+
74+
authnConfig, err := co.authnConfigLister.Get(api.ConfigResourceName)
75+
if err != nil {
76+
return statusHandler.FlushAndReturn(err)
77+
}
78+
79+
var (
80+
authServerCAConfig *corev1.ConfigMap
81+
sessionSecret *corev1.Secret
82+
)
83+
switch authnConfig.Spec.Type {
84+
case configv1.AuthenticationTypeOIDC:
85+
if len(authnConfig.Spec.OIDCProviders) > 0 {
86+
oidcProvider := authnConfig.Spec.OIDCProviders[0]
87+
authServerCAConfig, err = co.configNSConfigMapLister.ConfigMaps(api.OpenShiftConfigNamespace).Get(oidcProvider.Issuer.CertificateAuthority.Name)
88+
if err != nil && !apierrors.IsNotFound(err) {
89+
return statusHandler.FlushAndReturn(err)
90+
}
91+
}
92+
93+
sessionSecret, err = co.syncSessionSecret(ctx, updatedOperatorConfig, controllerContext.Recorder())
94+
if err != nil {
95+
return statusHandler.FlushAndReturn(err)
96+
}
97+
}
98+
99+
// TODO remove deprecated CustomLogoFile API
100+
// TODO: why is this missing a toUpdate change?
101+
customLogoError, customLogoErrReason := co.SyncCustomLogoConfigMap(updatedOperatorConfig)
102+
// If the custom logo sync fails for any reason, we are degraded, not progressing.
103+
// The sync loop may not settle, we are unable to honor it in current state.
104+
statusHandler.AddConditions(status.HandleProgressingOrDegraded("CustomLogoSync", customLogoErrReason, customLogoError))
105+
if customLogoError != nil {
106+
return statusHandler.FlushAndReturn(customLogoError)
107+
}
108+
109+
customLogosErr, customLogosErrReason := co.SyncCustomLogos(updatedOperatorConfig)
110+
statusHandler.AddConditions(status.HandleProgressingOrDegraded("CustomLogosSync", customLogosErrReason, customLogosErr))
111+
if customLogosErr != nil {
112+
return statusHandler.FlushAndReturn(customLogosErr)
113+
}
114+
115+
cm, cmChanged, cmErrReason, cmErr := co.SyncConfigMap(
116+
ctx,
117+
set.Operator,
118+
set.Console,
119+
set.Infrastructure,
120+
set.OAuth,
121+
authServerCAConfig,
122+
authnConfig,
123+
consoleRoute,
124+
controllerContext.Recorder(),
125+
consoleURL.Hostname(),
126+
)
127+
toUpdate = toUpdate || cmChanged
128+
statusHandler.AddConditions(status.HandleProgressingOrDegraded("ConfigMapSync", cmErrReason, cmErr))
129+
if cmErr != nil {
130+
return statusHandler.FlushAndReturn(cmErr)
131+
}
132+
133+
serviceCAConfigMap, serviceCAChanged, serviceCAErrReason, serviceCAErr := co.SyncServiceCAConfigMap(ctx, set.Operator)
134+
toUpdate = toUpdate || serviceCAChanged
135+
statusHandler.AddConditions(status.HandleProgressingOrDegraded("ServiceCASync", serviceCAErrReason, serviceCAErr))
136+
if serviceCAErr != nil {
137+
return statusHandler.FlushAndReturn(serviceCAErr)
138+
}
139+
140+
trustedCAConfigMap, trustedCAConfigMapChanged, trustedCAErrReason, trustedCAErr := co.SyncTrustedCAConfigMap(ctx, set.Operator)
141+
toUpdate = toUpdate || trustedCAConfigMapChanged
142+
statusHandler.AddConditions(status.HandleProgressingOrDegraded("TrustedCASync", trustedCAErrReason, trustedCAErr))
143+
if trustedCAErr != nil {
144+
return statusHandler.FlushAndReturn(trustedCAErr)
145+
}
146+
147+
var oauthServingCertConfigMap *corev1.ConfigMap
148+
switch authnConfig.Spec.Type {
149+
// We don't disable auth since the internal OAuth server is not disabled even with auth type 'None'.
150+
case "", configv1.AuthenticationTypeIntegratedOAuth, configv1.AuthenticationTypeNone:
151+
var oauthServingCertErrReason string
152+
var oauthServingCertErr error
153+
154+
oauthServingCertConfigMap, oauthServingCertErrReason, oauthServingCertErr = co.ValidateOAuthServingCertConfigMap(ctx)
155+
statusHandler.AddConditions(status.HandleProgressingOrDegraded("OAuthServingCertValidation", oauthServingCertErrReason, oauthServingCertErr))
156+
if oauthServingCertErr != nil {
157+
return statusHandler.FlushAndReturn(oauthServingCertErr)
158+
}
159+
}
160+
161+
clientSecret, secErr := co.secretsLister.Secrets(api.TargetNamespace).Get(secretsub.Stub().Name)
162+
statusHandler.AddConditions(status.HandleProgressingOrDegraded("OAuthClientSecretGet", "FailedGet", secErr))
163+
if secErr != nil {
164+
return statusHandler.FlushAndReturn(secErr)
165+
}
166+
167+
actualDeployment, depChanged, depErrReason, depErr := co.SyncDeployment(
168+
ctx,
169+
set.Operator,
170+
cm,
171+
serviceCAConfigMap,
172+
oauthServingCertConfigMap,
173+
authServerCAConfig,
174+
trustedCAConfigMap,
175+
clientSecret,
176+
sessionSecret,
177+
set.Proxy,
178+
set.Infrastructure,
179+
controllerContext.Recorder(),
180+
)
181+
toUpdate = toUpdate || depChanged
182+
statusHandler.AddConditions(status.HandleProgressingOrDegraded("DeploymentSync", depErrReason, depErr))
183+
if depErr != nil {
184+
return statusHandler.FlushAndReturn(depErr)
185+
}
186+
187+
statusHandler.UpdateDeploymentGeneration(actualDeployment)
188+
statusHandler.UpdateReadyReplicas(actualDeployment.Status.ReadyReplicas)
189+
statusHandler.UpdateObservedGeneration(set.Operator.ObjectMeta.Generation)
190+
191+
klog.V(4).Infoln("-----------------------")
192+
klog.V(4).Infof("sync loop 4.0.0 resources updated: %v", toUpdate)
193+
klog.V(4).Infoln("-----------------------")
194+
195+
statusHandler.AddCondition(status.HandleProgressing("SyncLoopRefresh", "InProgress", func() error {
196+
if toUpdate {
197+
return errors.New("changes made during sync updates, additional sync expected")
198+
}
199+
version := os.Getenv("OPERATOR_IMAGE_VERSION")
200+
if !deploymentsub.IsAvailableAndUpdated(actualDeployment) {
201+
return fmt.Errorf("working toward version %s, %v replicas available", version, actualDeployment.Status.AvailableReplicas)
202+
}
203+
204+
if co.versionGetter.GetVersions()["operator"] != version {
205+
co.versionGetter.SetVersion("operator", version)
206+
}
207+
return nil
208+
}()))
209+
210+
statusHandler.AddCondition(status.HandleAvailable(func() (prefix string, reason string, err error) {
211+
prefix = "Deployment"
212+
if !deploymentsub.IsAvailable(actualDeployment) {
213+
return prefix, "InsufficientReplicas", fmt.Errorf("%v replicas available for console deployment", actualDeployment.Status.ReadyReplicas)
214+
}
215+
return prefix, "", nil
216+
}()))
217+
218+
// if we survive the gauntlet, we need to update the console config with the
219+
// public hostname so that the world can know the console is ready to roll
220+
klog.V(4).Infoln("sync_v400: updating console status")
221+
222+
_, consoleConfigErr := co.SyncConsoleConfig(ctx, set.Console, consoleURL.String())
223+
statusHandler.AddCondition(status.HandleDegraded("ConsoleConfig", "FailedUpdate", consoleConfigErr))
224+
if consoleConfigErr != nil {
225+
klog.Errorf("could not update console config status: %v", consoleConfigErr)
226+
return statusHandler.FlushAndReturn(consoleConfigErr)
227+
}
228+
229+
_, _, consolePublicConfigErr := co.SyncConsolePublicConfig(ctx, consoleURL.String(), controllerContext.Recorder())
230+
statusHandler.AddCondition(status.HandleDegraded("ConsolePublicConfigMap", "FailedApply", consolePublicConfigErr))
231+
if consolePublicConfigErr != nil {
232+
klog.Errorf("could not update public console config status: %v", consolePublicConfigErr)
233+
return statusHandler.FlushAndReturn(consolePublicConfigErr)
234+
}
235+
236+
defer func() {
237+
klog.V(4).Infof("sync loop 4.0.0 complete")
238+
239+
if cmChanged {
240+
klog.V(4).Infof("\t configmap changed: %v", cm.GetResourceVersion())
241+
}
242+
if serviceCAChanged {
243+
klog.V(4).Infof("\t service-ca configmap changed: %v", serviceCAConfigMap.GetResourceVersion())
244+
}
245+
if depChanged {
246+
klog.V(4).Infof("\t deployment changed: %v", actualDeployment.GetResourceVersion())
247+
}
248+
}()
249+
250+
return statusHandler.FlushAndReturn(nil)
251+
}

0 commit comments

Comments
 (0)