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 }
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 }
// 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 }
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 }
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 }
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 }
// 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 }
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 }
// 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 }) }