rbd: create token and use it for vault SA everytime possible

use TokenRequest API by default for vault SA even with K8s versions < 1.24

Signed-off-by: Prashanth Dintyala <vdintyala@nvidia.com>
This commit is contained in:
Prashanth Dintyala 2022-09-07 13:49:38 -07:00 committed by mergify[bot]
parent 76064d8e34
commit 2a6487cbf5

View File

@ -23,8 +23,6 @@ import (
"io/ioutil" "io/ioutil"
"os" "os"
"github.com/ceph/ceph-csi/internal/util/k8s"
"github.com/libopenstorage/secrets/vault" "github.com/libopenstorage/secrets/vault"
authenticationv1 "k8s.io/api/authentication/v1" authenticationv1 "k8s.io/api/authentication/v1"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
@ -39,9 +37,6 @@ const (
// should be available in the Tenants namespace. This ServiceAccount // should be available in the Tenants namespace. This ServiceAccount
// will be used to connect to Hashicorp Vault. // will be used to connect to Hashicorp Vault.
vaultTenantSAName = "ceph-csi-vault-sa" vaultTenantSAName = "ceph-csi-vault-sa"
// Kubernetes version which requires ServiceAccount token creation.
// Kubernetes 1.24 => 1 * 1000 + 24.
kubeMinVersionForCreateToken = 1024
) )
/* /*
@ -298,6 +293,15 @@ func (kms *vaultTenantSA) getToken() (string, error) {
kms.tenantSAName, err) kms.tenantSAName, err)
} }
// From Kubernetes v1.24+, secret for service account tokens are not
// automatically created. Trying to fetch tokens from service account secret references will fail
// refer: https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.24.md \
// #no-really-you-must-read-this-before-you-upgrade-1.
token, err := kms.createToken(sa, c)
if err == nil {
return token, nil
}
for _, secretRef := range sa.Secrets { for _, secretRef := range sa.Secrets {
secret, sErr := c.CoreV1().Secrets(kms.Tenant).Get(context.TODO(), secretRef.Name, metav1.GetOptions{}) secret, sErr := c.CoreV1().Secrets(kms.Tenant).Get(context.TODO(), secretRef.Name, metav1.GetOptions{})
if sErr != nil { if sErr != nil {
@ -310,7 +314,7 @@ func (kms *vaultTenantSA) getToken() (string, error) {
} }
} }
return kms.createToken(sa, c) return "", fmt.Errorf("failed to find/create ServiceAccount token %s/%s: %w", kms.Tenant, kms.tenantSAName, err)
} }
// getTokenPath creates a temporary directory structure that contains the token // getTokenPath creates a temporary directory structure that contains the token
@ -335,32 +339,18 @@ func (kms *vaultTenantSA) getTokenPath() (string, error) {
return dir + "/token", nil return dir + "/token", nil
} }
// createToken creates required service account token for kubernetes 1.24+, // createToken creates required service account token using the TokenRequest API.
// else returns error.
// From kubernetes v1.24+, secret for service account tokens are not
// automatically created. Hence, use the create token api to fetch it.
// refer: https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.24.md \
// #no-really-you-must-read-this-before-you-upgrade-1 .
func (kms *vaultTenantSA) createToken(sa *corev1.ServiceAccount, client *kubernetes.Clientset) (string, error) { func (kms *vaultTenantSA) createToken(sa *corev1.ServiceAccount, client *kubernetes.Clientset) (string, error) {
major, minor, err := k8s.GetServerVersion(client) tokenRequest := &authenticationv1.TokenRequest{}
token, err := client.CoreV1().ServiceAccounts(kms.Tenant).CreateToken(
context.TODO(),
sa.Name,
tokenRequest,
metav1.CreateOptions{},
)
if err != nil { if err != nil {
return "", fmt.Errorf("failed to get server version: %w", err) return "", fmt.Errorf("failed to create token for service account %s/%s: %w", kms.Tenant, sa.Name, err)
} }
if (major*1000 + minor) >= kubeMinVersionForCreateToken { return token.Status.Token, nil
tokenRequest := &authenticationv1.TokenRequest{}
token, err := client.CoreV1().ServiceAccounts(kms.Tenant).CreateToken(
context.TODO(),
sa.Name,
tokenRequest,
metav1.CreateOptions{},
)
if err != nil {
return "", fmt.Errorf("failed to create token for service account %s/%s: %w", kms.Tenant, sa.Name, err)
}
return token.Status.Token, nil
}
return "", fmt.Errorf("failed to find token in ServiceAccount %s/%s", kms.Tenant, kms.tenantSAName)
} }