Пример #1
0
// TODO: when Secrets in kapi.ServiceAccount get changed to MountSecrets and represented by LocalObjectReferences, this can be
// refactored to reuse the addition code better
// addSecretsToServiceAccount adds secrets to the service account, either as pull secrets, mount secrets, or both.
func (o AddSecretOptions) addSecretsToServiceAccount(serviceaccount *kapi.ServiceAccount) error {
	updated := false
	newSecrets, err := o.getSecrets()
	if err != nil {
		return err
	}
	newSecretNames := getSecretNames(newSecrets)

	if o.ForMount {
		currentSecrets := getMountSecretNames(serviceaccount)
		secretsToAdd := newSecretNames.Difference(currentSecrets)
		for _, secretName := range secretsToAdd.List() {
			serviceaccount.Secrets = append(serviceaccount.Secrets, kapi.ObjectReference{Name: secretName})
			updated = true
		}
	}
	if o.ForPull {
		currentSecrets := getPullSecretNames(serviceaccount)
		secretsToAdd := newSecretNames.Difference(currentSecrets)
		for _, secretName := range secretsToAdd.List() {
			serviceaccount.ImagePullSecrets = append(serviceaccount.ImagePullSecrets, kapi.LocalObjectReference{Name: secretName})
			updated = true
		}
	}
	if updated {
		_, err = o.ClientInterface.ServiceAccounts(o.Namespace).Update(serviceaccount)
		return err
	}
	return nil
}
Пример #2
0
// removeSecretReferenceIfNeeded updates the given ServiceAccount to remove a reference to the given secretName if needed.
// Returns whether an update was performed, and any error that occurred
func (e *TokensController) removeSecretReferenceIfNeeded(serviceAccount *api.ServiceAccount, secretName string) (bool, error) {
	// See if the account even referenced the secret
	if !getSecretReferences(serviceAccount).Has(secretName) {
		return false, nil
	}

	// We don't want to update the cache's copy of the service account
	// so remove the secret from a freshly retrieved copy of the service account
	serviceAccounts := e.client.ServiceAccounts(serviceAccount.Namespace)
	serviceAccount, err := serviceAccounts.Get(serviceAccount.Name)
	if err != nil {
		return false, err
	}

	// Double-check to see if the account still references the secret
	if !getSecretReferences(serviceAccount).Has(secretName) {
		return false, nil
	}

	secrets := []api.ObjectReference{}
	for _, s := range serviceAccount.Secrets {
		if s.Name != secretName {
			secrets = append(secrets, s)
		}
	}
	serviceAccount.Secrets = secrets

	_, err = serviceAccounts.Update(serviceAccount)
	if err != nil {
		return false, err
	}

	return true, nil
}
func (o AddSecretOptions) AddSecretsToSAMountableSecrets(serviceAccount *api.ServiceAccount) (*api.ServiceAccount, error) {
	secrets, err := o.getSecrets()
	if err != nil {
		return nil, err
	}
	if len(secrets) == 0 {
		return nil, errors.New("no secrets found")
	}

	currentSecrets := util.StringSet{}
	for _, secretRef := range serviceAccount.Secrets {
		currentSecrets.Insert(secretRef.Name)
	}

	for _, secret := range secrets {
		if currentSecrets.Has(secret.Name) {
			continue
		}

		serviceAccount.Secrets = append(serviceAccount.Secrets, api.ObjectReference{Name: secret.Name})
		currentSecrets.Insert(secret.Name)
	}

	return o.ClientInterface.ServiceAccounts(o.Namespace).Update(serviceAccount)
}
Пример #4
0
// createSecret creates a secret of type ServiceAccountToken for the given ServiceAccount
func (e *TokensController) createSecret(serviceAccount *api.ServiceAccount) error {
	// Build the secret
	secret := &api.Secret{
		ObjectMeta: api.ObjectMeta{
			Name:      secret.Strategy.GenerateName(fmt.Sprintf("%s-token-", serviceAccount.Name)),
			Namespace: serviceAccount.Namespace,
			Annotations: map[string]string{
				api.ServiceAccountNameKey: serviceAccount.Name,
				api.ServiceAccountUIDKey:  string(serviceAccount.UID),
			},
		},
		Type: api.SecretTypeServiceAccountToken,
		Data: map[string][]byte{},
	}

	// Generate the token
	token, err := e.token.GenerateToken(*serviceAccount, *secret)
	if err != nil {
		return err
	}
	secret.Data[api.ServiceAccountTokenKey] = []byte(token)
	if e.rootCA != nil && len(e.rootCA) > 0 {
		secret.Data[api.ServiceAccountRootCAKey] = e.rootCA
	}

	// Save the secret
	if _, err := e.client.Secrets(serviceAccount.Namespace).Create(secret); err != nil {
		return err
	}

	// We don't want to update the cache's copy of the service account
	// so add the secret to a freshly retrieved copy of the service account
	serviceAccounts := e.client.ServiceAccounts(serviceAccount.Namespace)
	serviceAccount, err = serviceAccounts.Get(serviceAccount.Name)
	if err != nil {
		return err
	}
	serviceAccount.Secrets = append(serviceAccount.Secrets, api.ObjectReference{Name: secret.Name})

	_, err = serviceAccounts.Update(serviceAccount)
	if err != nil {
		// we weren't able to use the token, try to clean it up.
		glog.V(2).Infof("Deleting secret %s/%s because reference couldn't be added (%v)", secret.Namespace, secret.Name, err)
		if err := e.client.Secrets(secret.Namespace).Delete(secret.Name); err != nil {
			glog.Error(err) // if we fail, just log it
		}
	}
	if apierrors.IsConflict(err) {
		// nothing to do.  We got a conflict, that means that the service account was updated.  We simply need to return because we'll get an update notification later
		return nil
	}

	return err
}
func (o AddSecretOptions) AddSecretsToSAPullSecrets(serviceAccount *api.ServiceAccount) (*api.ServiceAccount, error) {
	secrets, err := o.getSecrets()
	if err != nil {
		return nil, err
	}

	currentSecrets := util.StringSet{}
	for _, secretRef := range serviceAccount.ImagePullSecrets {
		currentSecrets.Insert(secretRef.Name)
	}

	for _, secret := range secrets {
		if currentSecrets.Has(secret.Name) {
			continue
		}

		serviceAccount.ImagePullSecrets = append(serviceAccount.ImagePullSecrets, api.LocalObjectReference{Name: secret.Name})
		currentSecrets.Insert(secret.Name)
	}

	return o.ClientInterface.ServiceAccounts(o.Namespace).Update(serviceAccount)
}