func()

in cmd/gcp-controller-manager/service_account_verifier.go [344:407]


func (sav *serviceAccountVerifier) persist(key string) error {
	namespace, name, err := cache.SplitMetaNamespaceKey(key)
	if err != nil {
		klog.Errorf("Dropping invalid key %q in CM queue: %v", key, err)
		return nil
	}
	if namespace != verifiedSAConfigMapNamespace || name != verifiedSAConfigMapName {
		klog.Errorf("Dropping unknown ConfigMap object %s/%s in CM queue.", namespace, name)
		return nil
	}

	o, exists, err := sav.cmIndexer.GetByKey(key)
	if err != nil {
		return fmt.Errorf("failed to get ConfigMap %q: %v", key, err)
	}
	if !exists {
		klog.Warningf("ConfigMap %s/%s does not exist; creating.", namespace, name)
		text, err := sav.verifiedSAs.serialize()
		if err != nil {
			return fmt.Errorf("internal error during serialization: %v", err)
		}
		cm := newVerifiedSAConfigMap(text)
		klog.V(5).Infof("Creating ConfigMap: %+v", cm.Data)
		_, err = sav.c.CoreV1().ConfigMaps(verifiedSAConfigMapNamespace).Create(context.TODO(), cm, metav1.CreateOptions{})
		if err != nil {
			return fmt.Errorf("failed to create ConfigMap: %v", err)
		}
		return nil
	}

	cm, ok := o.(*core.ConfigMap)
	if !ok {
		klog.Errorf("Dropping invalid object from ConfigMap queue with key %q: %#v", key, o)
		return nil
	}
	text, err := sav.verifiedSAs.serialize()
	if err != nil {
		return fmt.Errorf("internal error during serialization: %v", err)
	}
	if cm.BinaryData == nil {
		cm.BinaryData = make(map[string][]byte)
	}
	if b, found := cm.BinaryData[verifiedSAConfigMapKey]; found && bytes.Equal(text, b) {
		klog.V(5).Infof("ConfigMap in sync; no update necessary: %+v", cm.BinaryData)
		return nil
	}
	cm.BinaryData[verifiedSAConfigMapKey] = text
	klog.V(5).Infof("Updating ConfigMap: %+v", cm.Data)
	_, err = sav.c.CoreV1().ConfigMaps(verifiedSAConfigMapNamespace).Update(context.TODO(), cm, metav1.UpdateOptions{})
	if err != nil {
		// Fail-close by deleting the ConfigMap assuming update failure was due to invalid content.
		// Retries are triggered at workqueue level (subject to verfiiedCMQueueRetryLimit), any CM
		// or SA update, and CM Informer level periodic resync.
		//
		// TODO(danielywong): catch TooLong error returned from validation.ValidateConfigMap for
		// alerting.
		rmErr := sav.c.CoreV1().ConfigMaps(verifiedSAConfigMapNamespace).Delete(context.TODO(), key, *metav1.NewDeleteOptions(0))
		if rmErr != nil {
			return fmt.Errorf("failed to update ConfigMap (%v) and reset also failed (%v)", err, rmErr)
		}
		return fmt.Errorf("reset ConfigMap due to update error: %v", err)
	}
	return nil
}