mirror of
https://github.com/external-secrets/external-secrets.git
synced 2024-12-14 11:57:59 +00:00
2b51f8a8e1
* feat: increase verbosity of error message during validation Signed-off-by: Gergely Brautigam <182850+Skarlso@users.noreply.github.com> * removing Equal as we do not have the specific error message there Signed-off-by: Gergely Brautigam <182850+Skarlso@users.noreply.github.com> --------- Signed-off-by: Gergely Brautigam <182850+Skarlso@users.noreply.github.com>
122 lines
4.3 KiB
Go
122 lines
4.3 KiB
Go
/*
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package secretstore
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/go-logr/logr"
|
|
v1 "k8s.io/api/core/v1"
|
|
"k8s.io/client-go/tools/record"
|
|
ctrl "sigs.k8s.io/controller-runtime"
|
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
|
|
|
esapi "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
|
|
"github.com/external-secrets/external-secrets/pkg/controllers/secretstore/metrics"
|
|
)
|
|
|
|
const (
|
|
errStoreProvider = "could not get store provider: %w"
|
|
errStoreClient = "could not get provider client: %w"
|
|
errValidationFailed = "could not validate provider: %w"
|
|
errPatchStatus = "unable to patch status: %w"
|
|
errUnableCreateClient = "unable to create client"
|
|
errUnableValidateStore = "unable to validate store: %s"
|
|
errUnableGetProvider = "unable to get store provider"
|
|
|
|
msgStoreValidated = "store validated"
|
|
)
|
|
|
|
func reconcile(ctx context.Context, req ctrl.Request, ss esapi.GenericStore, cl client.Client, log logr.Logger,
|
|
controllerClass string, gaugeVecGetter metrics.GaugeVevGetter, recorder record.EventRecorder, requeueInterval time.Duration) (ctrl.Result, error) {
|
|
if !ShouldProcessStore(ss, controllerClass) {
|
|
log.V(1).Info("skip store")
|
|
return ctrl.Result{}, nil
|
|
}
|
|
|
|
if ss.GetSpec().RefreshInterval != 0 {
|
|
requeueInterval = time.Second * time.Duration(ss.GetSpec().RefreshInterval)
|
|
}
|
|
|
|
// patch status when done processing
|
|
p := client.MergeFrom(ss.Copy())
|
|
defer func() {
|
|
err := cl.Status().Patch(ctx, ss, p)
|
|
if err != nil {
|
|
log.Error(err, errPatchStatus)
|
|
}
|
|
}()
|
|
|
|
// validateStore modifies the store conditions
|
|
// we have to patch the status
|
|
log.V(1).Info("validating")
|
|
err := validateStore(ctx, req.Namespace, controllerClass, ss, cl, gaugeVecGetter, recorder)
|
|
if err != nil {
|
|
log.Error(err, "unable to validate store")
|
|
return ctrl.Result{}, err
|
|
}
|
|
storeProvider, err := esapi.GetProvider(ss)
|
|
if err != nil {
|
|
return ctrl.Result{}, err
|
|
}
|
|
capStatus := esapi.SecretStoreStatus{
|
|
Capabilities: storeProvider.Capabilities(),
|
|
Conditions: ss.GetStatus().Conditions,
|
|
}
|
|
ss.SetStatus(capStatus)
|
|
|
|
recorder.Event(ss, v1.EventTypeNormal, esapi.ReasonStoreValid, msgStoreValidated)
|
|
cond := NewSecretStoreCondition(esapi.SecretStoreReady, v1.ConditionTrue, esapi.ReasonStoreValid, msgStoreValidated)
|
|
SetExternalSecretCondition(ss, *cond, gaugeVecGetter)
|
|
|
|
return ctrl.Result{
|
|
RequeueAfter: requeueInterval,
|
|
}, err
|
|
}
|
|
|
|
// validateStore tries to construct a new client
|
|
// if it fails sets a condition and writes events.
|
|
func validateStore(ctx context.Context, namespace, controllerClass string, store esapi.GenericStore,
|
|
client client.Client, gaugeVecGetter metrics.GaugeVevGetter, recorder record.EventRecorder) error {
|
|
mgr := NewManager(client, controllerClass, false)
|
|
defer mgr.Close(ctx)
|
|
cl, err := mgr.GetFromStore(ctx, store, namespace)
|
|
if err != nil {
|
|
cond := NewSecretStoreCondition(esapi.SecretStoreReady, v1.ConditionFalse, esapi.ReasonInvalidProviderConfig, errUnableCreateClient)
|
|
SetExternalSecretCondition(store, *cond, gaugeVecGetter)
|
|
recorder.Event(store, v1.EventTypeWarning, esapi.ReasonInvalidProviderConfig, err.Error())
|
|
return fmt.Errorf(errStoreClient, err)
|
|
}
|
|
validationResult, err := cl.Validate()
|
|
if err != nil && validationResult != esapi.ValidationResultUnknown {
|
|
cond := NewSecretStoreCondition(esapi.SecretStoreReady, v1.ConditionFalse, esapi.ReasonValidationFailed, fmt.Sprintf(errUnableValidateStore, err))
|
|
SetExternalSecretCondition(store, *cond, gaugeVecGetter)
|
|
recorder.Event(store, v1.EventTypeWarning, esapi.ReasonValidationFailed, err.Error())
|
|
return fmt.Errorf(errValidationFailed, err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// ShouldProcessStore returns true if the store should be processed.
|
|
func ShouldProcessStore(store esapi.GenericStore, class string) bool {
|
|
if store == nil || store.GetSpec().Controller == "" || store.GetSpec().Controller == class {
|
|
return true
|
|
}
|
|
|
|
return false
|
|
}
|