-
Notifications
You must be signed in to change notification settings - Fork 170
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
ARO-3258: propagate errors of ARO PullSecret controller to ARO operator #3947
base: master
Are you sure you want to change the base?
Changes from 3 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 |
---|---|---|
|
@@ -30,6 +30,7 @@ import ( | |
|
||
"github.com/Azure/ARO-RP/pkg/operator" | ||
arov1alpha1 "github.com/Azure/ARO-RP/pkg/operator/apis/aro.openshift.io/v1alpha1" | ||
"github.com/Azure/ARO-RP/pkg/operator/controllers/base" | ||
"github.com/Azure/ARO-RP/pkg/operator/predicates" | ||
"github.com/Azure/ARO-RP/pkg/util/pullsecret" | ||
) | ||
|
@@ -43,15 +44,16 @@ var rhKeys = []string{"registry.redhat.io", "cloud.openshift.com", "registry.con | |
|
||
// Reconciler reconciles a Cluster object | ||
type Reconciler struct { | ||
log *logrus.Entry | ||
|
||
client client.Client | ||
base.AROController | ||
} | ||
|
||
func NewReconciler(log *logrus.Entry, client client.Client) *Reconciler { | ||
return &Reconciler{ | ||
log: log, | ||
client: client, | ||
AROController: base.AROController{ | ||
Log: log, | ||
Client: client, | ||
Name: ControllerName, | ||
}, | ||
} | ||
} | ||
|
||
|
@@ -65,36 +67,39 @@ func NewReconciler(log *logrus.Entry, client client.Client) *Reconciler { | |
// - If the pull Secret object (which is not owned by the Cluster object) | ||
// changes, we'll see the pull Secret object requested. | ||
func (r *Reconciler) Reconcile(ctx context.Context, request ctrl.Request) (ctrl.Result, error) { | ||
instance := &arov1alpha1.Cluster{} | ||
err := r.client.Get(ctx, types.NamespacedName{Name: arov1alpha1.SingletonClusterName}, instance) | ||
instance, err := r.GetCluster(ctx) | ||
if err != nil { | ||
r.Log.Error(err) | ||
return reconcile.Result{}, err | ||
} | ||
|
||
if !instance.Spec.OperatorFlags.GetSimpleBoolean(operator.PullSecretEnabled) { | ||
r.log.Debug("controller is disabled") | ||
r.Log.Debug("controller is disabled") | ||
return reconcile.Result{}, nil | ||
} | ||
|
||
r.log.Debug("running") | ||
r.Log.Debug("running") | ||
userSecret := &corev1.Secret{} | ||
err = r.client.Get(ctx, pullSecretName, userSecret) | ||
err = r.Client.Get(ctx, pullSecretName, userSecret) | ||
if err != nil && !kerrors.IsNotFound(err) { | ||
r.Log.Error(err) | ||
return reconcile.Result{}, err | ||
} | ||
|
||
// reconcile global pull secret | ||
// detects if the global pull secret is broken and fixes it by using backup managed by ARO operator | ||
if instance.Spec.OperatorFlags.GetSimpleBoolean(operator.PullSecretManaged) { | ||
operatorSecret := &corev1.Secret{} | ||
err = r.client.Get(ctx, types.NamespacedName{Namespace: operator.Namespace, Name: operator.SecretName}, operatorSecret) | ||
err = r.Client.Get(ctx, types.NamespacedName{Namespace: operator.Namespace, Name: operator.SecretName}, operatorSecret) | ||
if err != nil { | ||
r.Log.Error(err) | ||
return reconcile.Result{}, err | ||
} | ||
|
||
// fix pull secret if its broken to have at least the ARO pull secret | ||
userSecret, err = r.ensureGlobalPullSecret(ctx, operatorSecret, userSecret) | ||
if err != nil { | ||
r.Log.Error(err) | ||
return reconcile.Result{}, err | ||
} | ||
} | ||
|
@@ -104,10 +109,11 @@ func (r *Reconciler) Reconcile(ctx context.Context, request ctrl.Request) (ctrl. | |
// - list of Red Hat pull-secret keys in status. | ||
instance.Status.RedHatKeysPresent, err = r.parseRedHatKeys(userSecret) | ||
if err != nil { | ||
r.Log.Error(err) | ||
return reconcile.Result{}, err | ||
} | ||
|
||
err = r.client.Update(ctx, instance) | ||
err = r.Client.Update(ctx, instance) | ||
return reconcile.Result{}, err | ||
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. We should validate if err is nil or not here, and:
|
||
} | ||
|
||
|
@@ -175,22 +181,23 @@ func (r *Reconciler) ensureGlobalPullSecret(ctx context.Context, operatorSecret, | |
// delete possible existing userSecret, calling deletion every time and ignoring when secret not found | ||
// allows for simpler logic flow, when delete and create are not handled separately | ||
// this call happens only when there is a need to change, it has no significant impact on performance | ||
err := r.client.Delete(ctx, secret) | ||
r.log.Info("Global Pull secret Not Found, Creating Again") | ||
err := r.Client.Delete(ctx, secret) | ||
r.Log.Info("Global Pull secret Not Found, Creating Again") | ||
if err != nil && !kerrors.IsNotFound(err) { | ||
r.Log.Error(err) | ||
return nil, err | ||
} | ||
|
||
err = r.client.Create(ctx, secret) | ||
err = r.Client.Create(ctx, secret) | ||
if err == nil { | ||
r.log.Info("Global Pull secret Created") | ||
r.Log.Info("Global Pull secret Created") | ||
} | ||
return secret, err | ||
} | ||
|
||
err = r.client.Update(ctx, secret) | ||
err = r.Client.Update(ctx, secret) | ||
if err == nil { | ||
r.log.Info("Updated Existing Global Pull secret") | ||
r.Log.Info("Updated Existing Global Pull secret") | ||
} | ||
return secret, err | ||
} | ||
|
@@ -205,7 +212,7 @@ func (r *Reconciler) parseRedHatKeys(secret *corev1.Secret) (foundKeys []string, | |
// parse keys and validate JSON | ||
parsedKeys, err := pullsecret.UnmarshalSecretData(secret) | ||
if err != nil { | ||
r.log.Info("pull secret is not valid json - recreating") | ||
r.Log.Info("pull secret is not valid json - recreating") | ||
return foundKeys, err | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,6 +10,7 @@ import ( | |
"testing" | ||
|
||
"github.com/sirupsen/logrus" | ||
"github.com/stretchr/testify/assert" | ||
corev1 "k8s.io/api/core/v1" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
"k8s.io/apimachinery/pkg/types" | ||
|
@@ -285,11 +286,11 @@ func TestPullSecretReconciler(t *testing.T) { | |
ctx := context.Background() | ||
|
||
clientFake := ctrlfake.NewClientBuilder().WithObjects(tt.instance).WithObjects(tt.secrets...).Build() | ||
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. We should also add validation in these tests to ensure that the conditions on the controller are what we expect (e.g. Degraded:True when an error occurs). You can see an example of this in the dnsmasq machine config controller tests: https://github.com/Azure/ARO-RP/blob/master/pkg/operator/controllers/dnsmasq/machineconfig_controller_test.go#L36 |
||
assert.NotNil(t, clientFake) | ||
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. Do we need to add these extra assert calls here? The test works as-is without them added. 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. It should be helpful to manifest nil object occurrence whenever that object is supposed to be not nil and thus to render test case failure early on. |
||
|
||
r := NewReconciler(logrus.NewEntry(logrus.StandardLogger()), clientFake) | ||
assert.NotNil(t, r) | ||
|
||
r := &Reconciler{ | ||
log: logrus.NewEntry(logrus.StandardLogger()), | ||
client: clientFake, | ||
} | ||
if tt.request.Name == "" { | ||
tt.request.NamespacedName = pullSecretName | ||
} | ||
|
@@ -301,7 +302,8 @@ func TestPullSecretReconciler(t *testing.T) { | |
} | ||
|
||
s := &corev1.Secret{} | ||
err = r.client.Get(ctx, types.NamespacedName{Namespace: "openshift-config", Name: "pull-secret"}, s) | ||
assert.NotNil(t, s) | ||
err = r.Client.Get(ctx, types.NamespacedName{Namespace: "openshift-config", Name: "pull-secret"}, s) | ||
if err != nil { | ||
t.Error(err) | ||
} | ||
|
@@ -315,6 +317,7 @@ func TestPullSecretReconciler(t *testing.T) { | |
} | ||
|
||
cluster := &arov1alpha1.Cluster{} | ||
assert.NotNil(t, cluster) | ||
err = clientFake.Get(ctx, types.NamespacedName{Name: arov1alpha1.SingletonClusterName}, cluster) | ||
if err != nil { | ||
t.Fatal("Error found") | ||
|
@@ -363,9 +366,8 @@ func TestParseRedHatKeys(t *testing.T) { | |
|
||
for _, tt := range test { | ||
t.Run(tt.name, func(t *testing.T) { | ||
r := &Reconciler{ | ||
log: logrus.NewEntry(logrus.StandardLogger()), | ||
} | ||
r := NewReconciler(logrus.NewEntry(logrus.StandardLogger()), nil) | ||
assert.NotNil(t, r) | ||
|
||
out, err := r.parseRedHatKeys(tt.ps) | ||
utilerror.AssertErrorMessage(t, err, tt.wantErr) | ||
|
@@ -760,16 +762,15 @@ func TestEnsureGlobalPullSecret(t *testing.T) { | |
for _, tt := range test { | ||
t.Run(tt.name, func(t *testing.T) { | ||
ctx := context.Background() | ||
assert.NotNil(t, ctx) | ||
|
||
clientBuilder := ctrlfake.NewClientBuilder() | ||
if tt.initialSecret != nil { | ||
clientBuilder = clientBuilder.WithObjects(tt.initialSecret) | ||
} | ||
|
||
r := &Reconciler{ | ||
client: clientBuilder.Build(), | ||
log: logrus.NewEntry(logrus.StandardLogger()), | ||
} | ||
r := NewReconciler(logrus.NewEntry(logrus.StandardLogger()), clientBuilder.Build()) | ||
assert.NotNil(t, r) | ||
|
||
s, err := r.ensureGlobalPullSecret(ctx, tt.operatorPullSecret, tt.pullSecret) | ||
utilerror.AssertErrorMessage(t, err, tt.wantError) | ||
|
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.
We probably want to
SetDegraded
here if we can't ensure the global pull secret. Here's an example: https://github.com/Azure/ARO-RP/pull/3177/files#diff-17756e345e334809c4f7ea3663119196d4de8e8085aca1b0da6a96e708d5d251R84There 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.
Resolving as we've agreed in the JIRA to not set degraded as part of this PR as it could impact user's ability to rotate their pull secret.
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.
We can safely SetDegraded here without impacting any functionality. The controller will still continue to execute as it would normally, and the controller Degraded status will (as of right now) not be cascaded to the ARO Cluster Operator itself, so this controller being degraded will not e.g. block cluster upgrades.