func getReferencedServiceAccountToken(c *client.Client, ns string, name string, shouldWait bool) (string, string, error) {
	tokenName := ""
	token := ""

	findToken := func() (bool, error) {
		user, err := c.ServiceAccounts(ns).Get(name)
		if errors.IsNotFound(err) {
			return false, nil
		}
		if err != nil {
			return false, err
		}

		for _, ref := range user.Secrets {
			secret, err := c.Secrets(ns).Get(ref.Name)
			if errors.IsNotFound(err) {
				continue
			}
			if err != nil {
				return false, err
			}
			if secret.Type != api.SecretTypeServiceAccountToken {
				continue
			}
			name := secret.Annotations[api.ServiceAccountNameKey]
			uid := secret.Annotations[api.ServiceAccountUIDKey]
			tokenData := secret.Data[api.ServiceAccountTokenKey]
			if name == user.Name && uid == string(user.UID) && len(tokenData) > 0 {
				tokenName = secret.Name
				token = string(tokenData)
				return true, nil
			}
		}

		return false, nil
	}

	if shouldWait {
		err := wait.Poll(time.Second, 10*time.Second, findToken)
		if err != nil {
			return "", "", err
		}
	} else {
		ok, err := findToken()
		if err != nil {
			return "", "", err
		}
		if !ok {
			return "", "", fmt.Errorf("No token found for %s/%s", ns, name)
		}
	}
	return tokenName, token, nil
}
Example #2
1
func addServiceAccount(c *k8sclient.Client, f *cmdutil.Factory, name string) (Result, error) {
	ns, _, e := f.DefaultNamespace()
	if e != nil {
		util.Fatal("No default namespace")
		return Failure, e
	}
	sas := c.ServiceAccounts(ns)
	_, err := sas.Get(name)
	if err != nil {
		sa := kapi.ServiceAccount{
			ObjectMeta: kapi.ObjectMeta{
				Name: name,
				Labels: map[string]string{
					"provider": "fabric8.io",
				},
			},
		}
		_, err = sas.Create(&sa)
	}
	r := Success
	if err != nil {
		r = Failure
	}
	return r, err
}
Example #3
0
// generateSecretsConfig generates any Secret and Volume objects, such
// as SSH private keys, that are necessary for the router container.
func generateSecretsConfig(cfg *RouterConfig, kClient *kclient.Client,
	namespace string) ([]*kapi.Secret, []kapi.Volume, []kapi.VolumeMount,
	error) {
	secrets := []*kapi.Secret{}
	volumes := []kapi.Volume{}
	mounts := []kapi.VolumeMount{}

	if len(cfg.ExternalHostPrivateKey) != 0 {
		privkeyData, err := loadKey(cfg.ExternalHostPrivateKey)
		if err != nil {
			return secrets, volumes, mounts, fmt.Errorf("error reading private key"+
				" for external host: %v", err)
		}

		serviceAccount, err := kClient.ServiceAccounts(namespace).Get(cfg.ServiceAccount)
		if err != nil {
			return secrets, volumes, mounts, fmt.Errorf("error looking up"+
				" service account %s: %v", cfg.ServiceAccount, err)
		}

		privkeySecret := &kapi.Secret{
			ObjectMeta: kapi.ObjectMeta{
				Name: privkeySecretName,
				Annotations: map[string]string{
					kapi.ServiceAccountNameKey: serviceAccount.Name,
					kapi.ServiceAccountUIDKey:  string(serviceAccount.UID),
				},
			},
			Data: map[string][]byte{privkeyName: privkeyData},
		}

		secrets = append(secrets, privkeySecret)
	}

	// We need a secrets volume and mount iff we have secrets.
	if len(secrets) != 0 {
		secretsVolume := kapi.Volume{
			Name: secretsVolumeName,
			VolumeSource: kapi.VolumeSource{
				Secret: &kapi.SecretVolumeSource{
					SecretName: privkeySecretName,
				},
			},
		}

		secretsMount := kapi.VolumeMount{
			Name:      secretsVolumeName,
			ReadOnly:  true,
			MountPath: secretsPath,
		}

		volumes = []kapi.Volume{secretsVolume}
		mounts = []kapi.VolumeMount{secretsMount}
	}

	return secrets, volumes, mounts, nil
}
Example #4
0
func validateServiceAccount(c *k8sclient.Client, f *cmdutil.Factory) (Result, error) {
	ns, _, err := f.DefaultNamespace()
	if err != nil {
		return Failure, err
	}
	sa, err := c.ServiceAccounts(ns).Get("fabric8")
	if sa != nil {
		return Success, err
	}
	return Failure, err
}
Example #5
0
func deleteServiceAccounts(c *k8sclient.Client, ns string, selector labels.Selector) error {
	sas, err := c.ServiceAccounts(ns).List(api.ListOptions{LabelSelector: selector})
	if err != nil {
		return err
	}
	for _, s := range sas.Items {
		err := c.ServiceAccounts(ns).Delete(s.Name)
		if err != nil {
			return errors.Wrap(err, fmt.Sprintf("failed to delete ServiceAccount %s", s.Name))
		}
	}
	return nil
}
Example #6
0
func GetClientForServiceAccount(adminClient *kclient.Client, clientConfig kclient.Config, namespace, name string) (*client.Client, *kclient.Client, *kclient.Config, error) {
	_, err := adminClient.Namespaces().Create(&kapi.Namespace{ObjectMeta: kapi.ObjectMeta{Name: namespace}})
	if err != nil && !kerrs.IsAlreadyExists(err) {
		return nil, nil, nil, err
	}

	sa, err := adminClient.ServiceAccounts(namespace).Create(&kapi.ServiceAccount{ObjectMeta: kapi.ObjectMeta{Name: name}})
	if kerrs.IsAlreadyExists(err) {
		sa, err = adminClient.ServiceAccounts(namespace).Get(name)
	}
	if err != nil {
		return nil, nil, nil, err
	}

	token := ""
	err = wait.Poll(time.Second, 30*time.Second, func() (bool, error) {
		selector := fields.OneTermEqualSelector(kclient.SecretType, string(kapi.SecretTypeServiceAccountToken))
		secrets, err := adminClient.Secrets(namespace).List(kapi.ListOptions{FieldSelector: selector})
		if err != nil {
			return false, err
		}
		for _, secret := range secrets.Items {
			if serviceaccounts.IsValidServiceAccountToken(sa, &secret) {
				token = string(secret.Data[kapi.ServiceAccountTokenKey])
				return true, nil
			}
		}
		return false, nil
	})
	if err != nil {
		return nil, nil, nil, err
	}

	saClientConfig := clientcmd.AnonymousClientConfig(clientConfig)
	saClientConfig.BearerToken = token

	kubeClient, err := kclient.New(&saClientConfig)
	if err != nil {
		return nil, nil, nil, err
	}

	osClient, err := client.New(&saClientConfig)
	if err != nil {
		return nil, nil, nil, err
	}

	return osClient, kubeClient, &saClientConfig, nil
}
func getServiceAccount(c *client.Client, ns string, name string, shouldWait bool) (*api.ServiceAccount, error) {
	if !shouldWait {
		return c.ServiceAccounts(ns).Get(name)
	}

	var user *api.ServiceAccount
	var err error
	err = wait.Poll(time.Second, 10*time.Second, func() (bool, error) {
		user, err = c.ServiceAccounts(ns).Get(name)
		if errors.IsNotFound(err) {
			return false, nil
		}
		if err != nil {
			return false, err
		}
		return true, nil
	})
	return user, err
}
Example #8
0
// EnsureServiceAccountExists ensures that there is a service account created for the given name
func EnsureServiceAccountExists(c *client.Client, ns string, serviceAccountName string) (bool, error) {
	saClient := c.ServiceAccounts(ns)
	sa, err := saClient.Get(serviceAccountName)
	created := false
	if err != nil || sa == nil {
		// lets try create the SA
		sa = &api.ServiceAccount{
			ObjectMeta: api.ObjectMeta{
				Name: serviceAccountName,
			},
		}
		log.Info("Creating ServiceAccount %s", serviceAccountName)
		_, err = saClient.Create(sa)
		if err == nil {
			created = true
		}
	}
	return created, err
}
Example #9
0
func getServiceAccountToken(client *kclient.Client, ns, name string) (string, error) {
	secrets, err := client.Secrets(ns).List(labels.Everything(), fields.Everything())
	if err != nil {
		return "", err
	}
	for _, secret := range secrets.Items {
		if secret.Type == api.SecretTypeServiceAccountToken && secret.Annotations[api.ServiceAccountNameKey] == name {
			sa, err := client.ServiceAccounts(ns).Get(name)
			if err != nil {
				return "", err
			}

			for _, ref := range sa.Secrets {
				if ref.Name == secret.Name {
					return string(secret.Data[api.ServiceAccountTokenKey]), nil
				}
			}

		}
	}

	return "", nil
}
Example #10
0
// WaitForServiceAccounts ensures the service accounts needed by build pods exist in the namespace
// The extra controllers tend to starve the service account controller
func WaitForServiceAccounts(client *kclient.Client, namespace string, accounts []string) error {
	serviceAccounts := client.ServiceAccounts(namespace)
	return wait.Poll(time.Second, ServiceAccountWaitTimeout, func() (bool, error) {
		for _, account := range accounts {
			if sa, err := serviceAccounts.Get(account); err != nil {
				if !serviceAccountSecretsExist(client, namespace, sa) {
					continue
				}
				return false, nil
			}
		}
		return true, nil
	})
}