Skip to content

Commit

Permalink
WIP error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
mrkisaolamb committed Jan 10, 2025
1 parent e5a56f9 commit 9fb1cee
Show file tree
Hide file tree
Showing 13 changed files with 52 additions and 36 deletions.
3 changes: 3 additions & 0 deletions .golangci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,8 @@ linters:
- ginkgolinter
- gofmt
- govet
- gosec
- errname
- err113
run:
timeout: 5m
6 changes: 6 additions & 0 deletions api/v1beta1/conditions.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ const (

// Common Messages used by API objects.
const (
//NovaNetworkAttachmentsReadyInitMessage
NovaNetworkAttachmentsReadyErrorMessage = "NetworkAttachments error occurred not all pods have interfaces with ips as configured in NetworkAttachments: %s"

// NovaAPIReadyInitMessage
NovaAPIReadyInitMessage = "NovaAPI not started"

Expand Down Expand Up @@ -172,4 +175,7 @@ const (

//CellHostDiscoverErrorMessage
CellHostDiscoverErrorMessage = "CellHostDiscover error occurred %s"

//InputReadyErrorMessage
InputReadyErrorMessage = "Input data error occurred %s"
)
15 changes: 8 additions & 7 deletions controllers/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ const (

// fields to index to reconcile when change
passwordSecretField = ".spec.secret"
caBundleSecretNameField = ".spec.tls.caBundleSecretName"
caBundleSecretNameField = ".spec.tls.caBundleSecretName" // #nosec G101
tlsAPIInternalField = ".spec.tls.api.internal.secretName"
tlsAPIPublicField = ".spec.tls.api.public.secretName"
tlsMetadataField = ".spec.tls.secretName"
Expand Down Expand Up @@ -186,8 +186,6 @@ type conditionUpdater interface {
MarkTrue(t condition.Type, messageFormat string, messageArgs ...interface{})
}

// ensureSecret - ensures that the Secret object exists and the expected fields
// are in the Secret. It returns a hash of the values of the expected fields.
func ensureSecret(
ctx context.Context,
secretName types.NamespacedName,
Expand Down Expand Up @@ -225,7 +223,10 @@ func ensureSecret(
for _, field := range expectedFields {
val, ok := secret.Data[field]
if !ok {
err := fmt.Errorf("field '%s' not found in secret/%s", field, secretName.Name)
// Usage in the code
err := k8s_errors.NewBadRequest(fmt.Sprintf("field '%s' not found in secret/%s", field, secretName.Name))
// ensureSecret - ensures that the Secret object exists and the expected fields
// are in the Secret. It returns a hash of the values of the expected fields.
conditionUpdater.Set(condition.FalseCondition(
condition.InputReadyCondition,
condition.ErrorReason,
Expand Down Expand Up @@ -579,7 +580,7 @@ func getNovaClient(
return nil, err
}
if (ctrlResult != ctrl.Result{}) {
return nil, fmt.Errorf("the CABundleSecret %s not found", auth.GetCABundleSecretName())
return nil, fmt.Errorf("the CABundleSecret %s not found: %w", auth.GetCABundleSecretName(), err)
}

tlsConfig = &openstack.TLSConfig{
Expand Down Expand Up @@ -641,7 +642,7 @@ func ensureMemcached(
condition.RequestedReason,
condition.SeverityInfo,
condition.MemcachedReadyWaitingMessage))
return nil, fmt.Errorf("memcached %s not found", memcachedName)
return nil, fmt.Errorf("%w: memcached %s not found", err, memcachedName)
}
conditionUpdater.Set(condition.FalseCondition(
condition.MemcachedReadyCondition,
Expand All @@ -658,7 +659,7 @@ func ensureMemcached(
condition.RequestedReason,
condition.SeverityInfo,
condition.MemcachedReadyWaitingMessage))
return nil, fmt.Errorf("memcached %s is not ready", memcachedName)
return nil, fmt.Errorf("%w: memcached %s is not ready", ErrResourceIsNotReady, memcachedName)
}
conditionUpdater.MarkTrue(condition.MemcachedReadyCondition, condition.MemcachedReadyMessage)

Expand Down
12 changes: 12 additions & 0 deletions controllers/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package controllers

import (
"errors"
)

var (
ErrResourceIsNotReady = errors.New("Resource is not ready")
ErrInvalidStatus = errors.New("invalid status")
ErrCannotUpdateObject = errors.New("cannot update object")
ErrFieldNotFound = errors.New("field not found in Secret")
)
14 changes: 7 additions & 7 deletions controllers/nova_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ func (r *NovaReconciler) Reconcile(ctx context.Context, req ctrl.Request) (resul
case nova.DBCompleted:
instance.Status.Conditions.MarkTrue(novav1.NovaAPIDBReadyCondition, condition.DBReadyMessage)
default:
return ctrl.Result{}, fmt.Errorf("invalid DatabaseStatus from ensureAPIDB: %d", apiDBStatus)
return ctrl.Result{}, fmt.Errorf("%w from ensureAPIDB: %d", ErrInvalidStatus, apiDBStatus)
}

// We need to create a list of cellNames to iterate on and as the map
Expand Down Expand Up @@ -332,7 +332,7 @@ func (r *NovaReconciler) Reconcile(ctx context.Context, req ctrl.Request) (resul
creatingDBs = append(creatingDBs, cellName)
case nova.DBCompleted:
default:
return ctrl.Result{}, fmt.Errorf("invalid DatabaseStatus from ensureCellDB: %d for cell %s", status, cellName)
return ctrl.Result{}, fmt.Errorf("%w from ensureCellDB: %d for cell %s", ErrInvalidStatus, status, cellName)
}
cellDBs[cellName] = &nova.Database{Database: cellDB, Status: status}
}
Expand Down Expand Up @@ -380,7 +380,7 @@ func (r *NovaReconciler) Reconcile(ctx context.Context, req ctrl.Request) (resul
instance.Status.Conditions.MarkTrue(
novav1.NovaAPIMQReadyCondition, novav1.NovaAPIMQReadyMessage)
default:
return ctrl.Result{}, fmt.Errorf("invalid MessageBusStatus from for the API MQ: %d", apiMQStatus)
return ctrl.Result{}, fmt.Errorf("%w from for the API MQ: %d", ErrInvalidStatus, apiMQStatus)
}

cellMQs := map[string]*nova.MessageBus{}
Expand Down Expand Up @@ -408,7 +408,7 @@ func (r *NovaReconciler) Reconcile(ctx context.Context, req ctrl.Request) (resul
creatingMQs = append(creatingMQs, cellName)
case nova.MQCompleted:
default:
return ctrl.Result{}, fmt.Errorf("invalid MessageBusStatus from ensureMQ: %d for cell %s", status, cellName)
return ctrl.Result{}, fmt.Errorf("%w from ensureMQ: %d for cell %s", ErrInvalidStatus, status, cellName)
}
cellMQs[cellName] = &nova.MessageBus{TransportURL: cellTransportURL, Status: status}
}
Expand Down Expand Up @@ -1631,8 +1631,8 @@ func (r *NovaReconciler) ensureMQ(

url, ok := secret.Data[TransportURLSelector]
if !ok {
return "", nova.MQFailed, fmt.Errorf(
"the TransportURL secret %s does not have 'transport_url' field", transportURL.Status.SecretName)
return "", nova.MQFailed, k8s_errors.NewBadRequest(fmt.Sprintf(
"the TransportURL secret %s does not have 'transport_url' field", transportURL.Status.SecretName))
}

return string(url), nova.MQCompleted, nil
Expand Down Expand Up @@ -1673,7 +1673,7 @@ func (r *NovaReconciler) ensureMetadata(
// If it is not created by us, we don't touch it
if !k8s_errors.IsNotFound(err) && !OwnedBy(metadata, instance) {
err := fmt.Errorf(
"cannot update NovaMetadata/%s as the cell is not owning it", metadata.Name)
"%w NovaMetadata/%s as the cell is not owning it", ErrCannotUpdateObject, metadata.Name)
Log.Error(err,
"NovaMetadata is enabled, but there is a "+
"NovaMetadata CR not owned by us. We cannot update it. "+
Expand Down
5 changes: 2 additions & 3 deletions controllers/novaapi_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -588,13 +588,12 @@ func (r *NovaAPIReconciler) ensureDeployment(
if networkReady {
instance.Status.Conditions.MarkTrue(condition.NetworkAttachmentsReadyCondition, condition.NetworkAttachmentsReadyMessage)
} else {
err := fmt.Errorf("not all pods have interfaces with ips as configured in NetworkAttachments: %s", instance.Spec.NetworkAttachments)
instance.Status.Conditions.Set(condition.FalseCondition(
condition.NetworkAttachmentsReadyCondition,
condition.ErrorReason,
condition.SeverityWarning,
condition.NetworkAttachmentsReadyErrorMessage,
err.Error()))
novav1.NovaNetworkAttachmentsReadyErrorMessage,
instance.Spec.NetworkAttachments))

return ctrl.Result{}, err
}
Expand Down
6 changes: 3 additions & 3 deletions controllers/novacell_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,7 @@ func (r *NovaCellReconciler) ensureNoVNCProxy(
// If it is not created by us, we don't touch it
if !k8s_errors.IsNotFound(err) && !OwnedBy(novncproxy, instance) {
err := fmt.Errorf(
"cannot update NovaNoVNCProxy/%s as the cell is not owning it", novncproxyName.Name)
"%w NovaNoVNCProxy/%s as the cell is not owning it", ErrCannotUpdateObject, novncproxyName.Name)
Log.Error(err,
"NovaNoVNCProxy is enabled in this cell, but there is a "+
"NovaNoVNCProxy CR not owned by the cell. We cannot update it. "+
Expand Down Expand Up @@ -548,7 +548,7 @@ func (r *NovaCellReconciler) ensureMetadata(
// If it is not created by us, we don't touch it
if !k8s_errors.IsNotFound(err) && !OwnedBy(metadata, instance) {
err := fmt.Errorf(
"cannot update NovaMetadata/%s as the cell is not owning it", metadata.Name)
"%w NovaMetadata/%s as the cell is not owning it", ErrCannotUpdateObject, metadata.Name)
Log.Error(err,
"NovaMetadata is enabled, but there is a "+
"NovaMetadata CR not owned by us. We cannot update it. "+
Expand Down Expand Up @@ -708,7 +708,7 @@ func (r *NovaCellReconciler) ensureNovaCompute(
// If it is not created by us, we don't touch it
if !k8s_errors.IsNotFound(err) && !OwnedBy(novacompute, instance) {
err := fmt.Errorf(
"cannot update NovaCompute/%s as the cell is not owning it", novacompute.Name)
"%w NovaCompute/%s as the cell is not owning it", ErrCannotUpdateObject, novacompute.Name)
Log.Error(err,
"NovaCompute is defined in the cell, but there is a "+
"NovaCompute CR not owned by us. We cannot update it. "+
Expand Down
5 changes: 2 additions & 3 deletions controllers/novacompute_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -403,13 +403,12 @@ func (r *NovaComputeReconciler) ensureDeployment(
if networkReady {
instance.Status.Conditions.MarkTrue(condition.NetworkAttachmentsReadyCondition, condition.NetworkAttachmentsReadyMessage)
} else {
err := fmt.Errorf("not all pods have interfaces with ips as configured in NetworkAttachments: %s", instance.Spec.NetworkAttachments)
instance.Status.Conditions.Set(condition.FalseCondition(
condition.NetworkAttachmentsReadyCondition,
condition.ErrorReason,
condition.SeverityWarning,
condition.NetworkAttachmentsReadyErrorMessage,
err.Error()))
novav1.NovaNetworkAttachmentsReadyErrorMessage,
instance.Spec.NetworkAttachments))

return ctrl.Result{}, err
}
Expand Down
5 changes: 2 additions & 3 deletions controllers/novaconductor_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -560,13 +560,12 @@ func (r *NovaConductorReconciler) ensureDeployment(
if networkReady {
instance.Status.Conditions.MarkTrue(condition.NetworkAttachmentsReadyCondition, condition.NetworkAttachmentsReadyMessage)
} else {
err := fmt.Errorf("not all pods have interfaces with ips as configured in NetworkAttachments: %s", instance.Spec.NetworkAttachments)
instance.Status.Conditions.Set(condition.FalseCondition(
condition.NetworkAttachmentsReadyCondition,
condition.ErrorReason,
condition.SeverityWarning,
condition.NetworkAttachmentsReadyErrorMessage,
err.Error()))
novav1.NovaNetworkAttachmentsReadyErrorMessage,
instance.Spec.NetworkAttachments))

return ctrl.Result{}, err
}
Expand Down
5 changes: 2 additions & 3 deletions controllers/novametadata_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -598,13 +598,12 @@ func (r *NovaMetadataReconciler) ensureDeployment(
if networkReady {
instance.Status.Conditions.MarkTrue(condition.NetworkAttachmentsReadyCondition, condition.NetworkAttachmentsReadyMessage)
} else {
err := fmt.Errorf("not all pods have interfaces with ips as configured in NetworkAttachments: %s", instance.Spec.NetworkAttachments)
instance.Status.Conditions.Set(condition.FalseCondition(
condition.NetworkAttachmentsReadyCondition,
condition.ErrorReason,
condition.SeverityWarning,
condition.NetworkAttachmentsReadyErrorMessage,
err.Error()))
novav1.NovaNetworkAttachmentsReadyErrorMessage,
instance.Spec.NetworkAttachments))

return ctrl.Result{}, err
}
Expand Down
5 changes: 2 additions & 3 deletions controllers/novanovncproxy_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -546,13 +546,12 @@ func (r *NovaNoVNCProxyReconciler) ensureDeployment(
if networkReady {
instance.Status.Conditions.MarkTrue(condition.NetworkAttachmentsReadyCondition, condition.NetworkAttachmentsReadyMessage)
} else {
err := fmt.Errorf("not all pods have interfaces with ips as configured in NetworkAttachments: %s", instance.Spec.NetworkAttachments)
instance.Status.Conditions.Set(condition.FalseCondition(
condition.NetworkAttachmentsReadyCondition,
condition.ErrorReason,
condition.SeverityWarning,
condition.NetworkAttachmentsReadyErrorMessage,
err.Error()))
novav1.NovaNetworkAttachmentsReadyErrorMessage,
instance.Spec.NetworkAttachments))

return ctrl.Result{}, err
}
Expand Down
5 changes: 2 additions & 3 deletions controllers/novascheduler_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -613,13 +613,12 @@ func (r *NovaSchedulerReconciler) ensureDeployment(
if networkReady {
instance.Status.Conditions.MarkTrue(condition.NetworkAttachmentsReadyCondition, condition.NetworkAttachmentsReadyMessage)
} else {
err := fmt.Errorf("not all pods have interfaces with ips as configured in NetworkAttachments: %s", instance.Spec.NetworkAttachments)
instance.Status.Conditions.Set(condition.FalseCondition(
condition.NetworkAttachmentsReadyCondition,
condition.ErrorReason,
condition.SeverityWarning,
condition.NetworkAttachmentsReadyErrorMessage,
err.Error()))
novav1.NovaNetworkAttachmentsReadyErrorMessage,
instance.Spec.NetworkAttachments))

return ctrl.Result{}, err
}
Expand Down
2 changes: 1 addition & 1 deletion test/functional/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ var _ = BeforeSuite(func() {
dialer := &net.Dialer{Timeout: time.Duration(10) * time.Second}
addrPort := fmt.Sprintf("%s:%d", webhookInstallOptions.LocalServingHost, webhookInstallOptions.LocalServingPort)
Eventually(func() error {
conn, err := tls.DialWithDialer(dialer, "tcp", addrPort, &tls.Config{InsecureSkipVerify: true})
conn, err := tls.DialWithDialer(dialer, "tcp", addrPort, &tls.Config{InsecureSkipVerify: true}) // #nosec G402
if err != nil {
return err
}
Expand Down

0 comments on commit 9fb1cee

Please sign in to comment.