func waitForSecretUpdateOrFail(clientset *kubeclientset.Clientset, namespace string, secret *v1.Secret, timeout time.Duration) { By(fmt.Sprintf("Fetching a federated secret shard of secret %q in namespace %q from cluster", secret.Name, namespace)) err := wait.PollImmediate(framework.Poll, timeout, func() (bool, error) { clusterSecret, err := clientset.Core().Secrets(namespace).Get(secret.Name) if err == nil { // We want it present, and the Get succeeded, so we're all good. if util.SecretEquivalent(*clusterSecret, *secret) { By(fmt.Sprintf("Success: shard of federated secret %q in namespace %q in cluster is updated", secret.Name, namespace)) return true, nil } else { By(fmt.Sprintf("Expected equal secrets. expected: %+v\nactual: %+v", *secret, *clusterSecret)) } By(fmt.Sprintf("Secret %q in namespace %q in cluster, waiting for secret being updated, trying again in %s (err=%v)", secret.Name, namespace, framework.Poll, err)) return false, nil } By(fmt.Sprintf("Secret %q in namespace %q in cluster, waiting for being updated, trying again in %s (err=%v)", secret.Name, namespace, framework.Poll, err)) return false, nil }) framework.ExpectNoError(err, "Failed to verify secret %q in namespace %q in cluster", secret.Name, namespace) }
func waitForSecretOrFail(clientset *kubeclientset.Clientset, namespace string, secret *v1.Secret, present bool, timeout time.Duration) { By(fmt.Sprintf("Fetching a federated secret shard of secret %q in namespace %q from cluster", secret.Name, namespace)) var clusterSecret *v1.Secret err := wait.PollImmediate(framework.Poll, timeout, func() (bool, error) { clusterSecret, err := clientset.Core().Secrets(namespace).Get(secret.Name) if (!present) && errors.IsNotFound(err) { // We want it gone, and it's gone. By(fmt.Sprintf("Success: shard of federated secret %q in namespace %q in cluster is absent", secret.Name, namespace)) return true, nil // Success } if present && err == nil { // We want it present, and the Get succeeded, so we're all good. By(fmt.Sprintf("Success: shard of federated secret %q in namespace %q in cluster is present", secret.Name, namespace)) return true, nil // Success } By(fmt.Sprintf("Secret %q in namespace %q in cluster. Found: %v, waiting for Found: %v, trying again in %s (err=%v)", secret.Name, namespace, clusterSecret != nil && err == nil, present, framework.Poll, err)) return false, nil }) framework.ExpectNoError(err, "Failed to verify secret %q in namespace %q in cluster: Present=%v", secret.Name, namespace, present) if present && clusterSecret != nil { Expect(util.SecretEquivalent(*clusterSecret, *secret)) } }
func (secretcontroller *SecretController) reconcileSecret(namespace string, secretName string) { if !secretcontroller.isSynced() { secretcontroller.deliverSecret(namespace, secretName, secretcontroller.clusterAvailableDelay, false) return } key := getSecretKey(namespace, secretName) baseSecretObj, exist, err := secretcontroller.secretInformerStore.GetByKey(key) if err != nil { glog.Errorf("Failed to query main secret store for %v: %v", key, err) secretcontroller.deliverSecret(namespace, secretName, 0, true) return } if !exist { // Not federated secret, ignoring. return } baseSecret := baseSecretObj.(*api_v1.Secret) clusters, err := secretcontroller.secretFederatedInformer.GetReadyClusters() if err != nil { glog.Errorf("Failed to get cluster list: %v", err) secretcontroller.deliverSecret(namespace, secretName, secretcontroller.clusterAvailableDelay, false) return } operations := make([]util.FederatedOperation, 0) for _, cluster := range clusters { clusterSecretObj, found, err := secretcontroller.secretFederatedInformer.GetTargetStore().GetByKey(cluster.Name, key) if err != nil { glog.Errorf("Failed to get %s from %s: %v", key, cluster.Name, err) secretcontroller.deliverSecret(namespace, secretName, 0, true) return } desiredSecret := &api_v1.Secret{ ObjectMeta: util.CopyObjectMeta(baseSecret.ObjectMeta), Data: baseSecret.Data, Type: baseSecret.Type, } if !found { secretcontroller.eventRecorder.Eventf(baseSecret, api.EventTypeNormal, "CreateInCluster", "Creating secret in cluster %s", cluster.Name) operations = append(operations, util.FederatedOperation{ Type: util.OperationTypeAdd, Obj: desiredSecret, ClusterName: cluster.Name, }) } else { clusterSecret := clusterSecretObj.(*api_v1.Secret) // Update existing secret, if needed. if !util.SecretEquivalent(*desiredSecret, *clusterSecret) { secretcontroller.eventRecorder.Eventf(baseSecret, api.EventTypeNormal, "UpdateInCluster", "Updating secret in cluster %s", cluster.Name) operations = append(operations, util.FederatedOperation{ Type: util.OperationTypeUpdate, Obj: desiredSecret, ClusterName: cluster.Name, }) } } } if len(operations) == 0 { // Everything is in order return } err = secretcontroller.federatedUpdater.UpdateWithOnError(operations, secretcontroller.updateTimeout, func(op util.FederatedOperation, operror error) { secretcontroller.eventRecorder.Eventf(baseSecret, api.EventTypeNormal, "UpdateInClusterFailed", "Secret update in cluster %s failed: %v", op.ClusterName, operror) }) if err != nil { glog.Errorf("Failed to execute updates for %s: %v", key, err) secretcontroller.deliverSecret(namespace, secretName, 0, true) return } // Evertyhing is in order but lets be double sure secretcontroller.deliverSecret(namespace, secretName, secretcontroller.secretReviewDelay, false) }
func (secretcontroller *SecretController) reconcileSecret(secret types.NamespacedName) { if !secretcontroller.isSynced() { secretcontroller.deliverSecret(secret, secretcontroller.clusterAvailableDelay, false) return } key := secret.String() baseSecretObjFromStore, exist, err := secretcontroller.secretInformerStore.GetByKey(key) if err != nil { glog.Errorf("Failed to query main secret store for %v: %v", key, err) secretcontroller.deliverSecret(secret, 0, true) return } if !exist { // Not federated secret, ignoring. return } // Create a copy before modifying the obj to prevent race condition with // other readers of obj from store. baseSecretObj, err := api.Scheme.DeepCopy(baseSecretObjFromStore) baseSecret, ok := baseSecretObj.(*apiv1.Secret) if err != nil || !ok { glog.Errorf("Error in retrieving obj from store: %v, %v", ok, err) secretcontroller.deliverSecret(secret, 0, true) return } if baseSecret.DeletionTimestamp != nil { if err := secretcontroller.delete(baseSecret); err != nil { glog.Errorf("Failed to delete %s: %v", secret, err) secretcontroller.eventRecorder.Eventf(baseSecret, api.EventTypeNormal, "DeleteFailed", "Secret delete failed: %v", err) secretcontroller.deliverSecret(secret, 0, true) } return } glog.V(3).Infof("Ensuring delete object from underlying clusters finalizer for secret: %s", baseSecret.Name) // Add the required finalizers before creating a secret in underlying clusters. updatedSecretObj, err := secretcontroller.deletionHelper.EnsureFinalizers(baseSecret) if err != nil { glog.Errorf("Failed to ensure delete object from underlying clusters finalizer in secret %s: %v", baseSecret.Name, err) secretcontroller.deliverSecret(secret, 0, false) return } baseSecret = updatedSecretObj.(*apiv1.Secret) glog.V(3).Infof("Syncing secret %s in underlying clusters", baseSecret.Name) clusters, err := secretcontroller.secretFederatedInformer.GetReadyClusters() if err != nil { glog.Errorf("Failed to get cluster list: %v", err) secretcontroller.deliverSecret(secret, secretcontroller.clusterAvailableDelay, false) return } operations := make([]util.FederatedOperation, 0) for _, cluster := range clusters { clusterSecretObj, found, err := secretcontroller.secretFederatedInformer.GetTargetStore().GetByKey(cluster.Name, key) if err != nil { glog.Errorf("Failed to get %s from %s: %v", key, cluster.Name, err) secretcontroller.deliverSecret(secret, 0, true) return } // The data should not be modified. desiredSecret := &apiv1.Secret{ ObjectMeta: util.DeepCopyRelevantObjectMeta(baseSecret.ObjectMeta), Data: baseSecret.Data, Type: baseSecret.Type, } if !found { secretcontroller.eventRecorder.Eventf(baseSecret, api.EventTypeNormal, "CreateInCluster", "Creating secret in cluster %s", cluster.Name) operations = append(operations, util.FederatedOperation{ Type: util.OperationTypeAdd, Obj: desiredSecret, ClusterName: cluster.Name, }) } else { clusterSecret := clusterSecretObj.(*apiv1.Secret) // Update existing secret, if needed. if !util.SecretEquivalent(*desiredSecret, *clusterSecret) { secretcontroller.eventRecorder.Eventf(baseSecret, api.EventTypeNormal, "UpdateInCluster", "Updating secret in cluster %s", cluster.Name) operations = append(operations, util.FederatedOperation{ Type: util.OperationTypeUpdate, Obj: desiredSecret, ClusterName: cluster.Name, }) } } } if len(operations) == 0 { // Everything is in order return } err = secretcontroller.federatedUpdater.UpdateWithOnError(operations, secretcontroller.updateTimeout, func(op util.FederatedOperation, operror error) { secretcontroller.eventRecorder.Eventf(baseSecret, api.EventTypeNormal, "UpdateInClusterFailed", "Secret update in cluster %s failed: %v", op.ClusterName, operror) }) if err != nil { glog.Errorf("Failed to execute updates for %s: %v", key, err) secretcontroller.deliverSecret(secret, 0, true) return } // Evertyhing is in order but lets be double sure secretcontroller.deliverSecret(secret, secretcontroller.secretReviewDelay, false) }