feat(k8-operator): dynamic secrets

This commit is contained in:
Daniel Hougaard
2024-12-08 21:30:28 +04:00
parent 0d35273857
commit 4552f0efa4
29 changed files with 1741 additions and 325 deletions
+84 -4
View File
@@ -63,11 +63,13 @@ var AuthStrategy = struct {
type SecretCrdType string
var SecretCrd = struct {
INFISICAL_SECRET SecretCrdType
INFISICAL_PUSH_SECRET SecretCrdType
INFISICAL_SECRET SecretCrdType
INFISICAL_PUSH_SECRET SecretCrdType
INFISICAL_DYNAMIC_SECRET SecretCrdType
}{
INFISICAL_SECRET: "INFISICAL_SECRET",
INFISICAL_PUSH_SECRET: "INFISICAL_PUSH_SECRET",
INFISICAL_SECRET: "INFISICAL_SECRET",
INFISICAL_PUSH_SECRET: "INFISICAL_PUSH_SECRET",
INFISICAL_DYNAMIC_SECRET: "INFISICAL_DYNAMIC_SECRET",
}
type SecretAuthInput struct {
@@ -107,6 +109,18 @@ func HandleUniversalAuth(ctx context.Context, reconcilerClient client.Client, se
CredentialsRef: infisicalPushSecret.Spec.Authentication.UniversalAuth.CredentialsRef,
SecretsScope: v1alpha1.MachineIdentityScopeInWorkspace{},
}
case SecretCrd.INFISICAL_DYNAMIC_SECRET:
infisicalDynamicSecret, ok := secretCrd.Secret.(v1alpha1.InfisicalDynamicSecret)
if !ok {
return AuthenticationDetails{}, errors.New("unable to cast secret to InfisicalDynamicSecret")
}
universalAuthSpec = v1alpha1.UniversalAuthDetails{
CredentialsRef: infisicalDynamicSecret.Spec.Authentication.UniversalAuth.CredentialsRef,
SecretsScope: v1alpha1.MachineIdentityScopeInWorkspace{},
}
}
universalAuthKubeSecret, err := GetInfisicalUniversalAuthFromKubeSecret(ctx, reconcilerClient, v1alpha1.KubeSecretReference{
@@ -160,6 +174,22 @@ func HandleKubernetesAuth(ctx context.Context, reconcilerClient client.Client, s
},
SecretsScope: v1alpha1.MachineIdentityScopeInWorkspace{},
}
case SecretCrd.INFISICAL_DYNAMIC_SECRET:
infisicalDynamicSecret, ok := secretCrd.Secret.(v1alpha1.InfisicalDynamicSecret)
if !ok {
return AuthenticationDetails{}, errors.New("unable to cast secret to InfisicalDynamicSecret")
}
kubernetesAuthSpec = v1alpha1.KubernetesAuthDetails{
IdentityID: infisicalDynamicSecret.Spec.Authentication.KubernetesAuth.IdentityID,
ServiceAccountRef: v1alpha1.KubernetesServiceAccountRef{
Namespace: infisicalDynamicSecret.Spec.Authentication.KubernetesAuth.ServiceAccountRef.Namespace,
Name: infisicalDynamicSecret.Spec.Authentication.KubernetesAuth.ServiceAccountRef.Name,
},
SecretsScope: v1alpha1.MachineIdentityScopeInWorkspace{},
}
}
if kubernetesAuthSpec.IdentityID == "" {
@@ -208,6 +238,18 @@ func HandleAwsIamAuth(ctx context.Context, reconcilerClient client.Client, secre
IdentityID: infisicalPushSecret.Spec.Authentication.AwsIamAuth.IdentityID,
SecretsScope: v1alpha1.MachineIdentityScopeInWorkspace{},
}
case SecretCrd.INFISICAL_DYNAMIC_SECRET:
infisicalDynamicSecret, ok := secretCrd.Secret.(v1alpha1.InfisicalDynamicSecret)
if !ok {
return AuthenticationDetails{}, errors.New("unable to cast secret to InfisicalDynamicSecret")
}
awsIamAuthSpec = v1alpha1.AWSIamAuthDetails{
IdentityID: infisicalDynamicSecret.Spec.Authentication.AwsIamAuth.IdentityID,
SecretsScope: v1alpha1.MachineIdentityScopeInWorkspace{},
}
}
if awsIamAuthSpec.IdentityID == "" {
@@ -253,6 +295,19 @@ func HandleAzureAuth(ctx context.Context, reconcilerClient client.Client, secret
Resource: infisicalPushSecret.Spec.Authentication.AzureAuth.Resource,
SecretsScope: v1alpha1.MachineIdentityScopeInWorkspace{},
}
case SecretCrd.INFISICAL_DYNAMIC_SECRET:
infisicalDynamicSecret, ok := secretCrd.Secret.(v1alpha1.InfisicalDynamicSecret)
if !ok {
return AuthenticationDetails{}, errors.New("unable to cast secret to InfisicalDynamicSecret")
}
azureAuthSpec = v1alpha1.AzureAuthDetails{
IdentityID: infisicalDynamicSecret.Spec.Authentication.AzureAuth.IdentityID,
Resource: infisicalDynamicSecret.Spec.Authentication.AzureAuth.Resource,
SecretsScope: v1alpha1.MachineIdentityScopeInWorkspace{},
}
}
if azureAuthSpec.IdentityID == "" {
@@ -296,6 +351,18 @@ func HandleGcpIdTokenAuth(ctx context.Context, reconcilerClient client.Client, s
IdentityID: infisicalPushSecret.Spec.Authentication.GcpIdTokenAuth.IdentityID,
SecretsScope: v1alpha1.MachineIdentityScopeInWorkspace{},
}
case SecretCrd.INFISICAL_DYNAMIC_SECRET:
infisicalDynamicSecret, ok := secretCrd.Secret.(v1alpha1.InfisicalDynamicSecret)
if !ok {
return AuthenticationDetails{}, errors.New("unable to cast secret to InfisicalDynamicSecret")
}
gcpIdTokenSpec = v1alpha1.GCPIdTokenAuthDetails{
IdentityID: infisicalDynamicSecret.Spec.Authentication.GcpIdTokenAuth.IdentityID,
SecretsScope: v1alpha1.MachineIdentityScopeInWorkspace{},
}
}
if gcpIdTokenSpec.IdentityID == "" {
@@ -340,6 +407,19 @@ func HandleGcpIamAuth(ctx context.Context, reconcilerClient client.Client, secre
ServiceAccountKeyFilePath: infisicalPushSecret.Spec.Authentication.GcpIamAuth.ServiceAccountKeyFilePath,
SecretsScope: v1alpha1.MachineIdentityScopeInWorkspace{},
}
case SecretCrd.INFISICAL_DYNAMIC_SECRET:
infisicalDynamicSecret, ok := secretCrd.Secret.(v1alpha1.InfisicalDynamicSecret)
if !ok {
return AuthenticationDetails{}, errors.New("unable to cast secret to InfisicalDynamicSecret")
}
gcpIamSpec = v1alpha1.GcpIamAuthDetails{
IdentityID: infisicalDynamicSecret.Spec.Authentication.GcpIamAuth.IdentityID,
ServiceAccountKeyFilePath: infisicalDynamicSecret.Spec.Authentication.GcpIamAuth.ServiceAccountKeyFilePath,
SecretsScope: v1alpha1.MachineIdentityScopeInWorkspace{},
}
}
if gcpIamSpec.IdentityID == "" && gcpIamSpec.ServiceAccountKeyFilePath == "" {
@@ -3,10 +3,11 @@ package util
import (
"fmt"
"strconv"
"strings"
"time"
)
func ConvertResyncIntervalToDuration(resyncInterval string) (time.Duration, error) {
func ConvertIntervalToDuration(resyncInterval string) (time.Duration, error) {
length := len(resyncInterval)
if length < 2 {
return 0, fmt.Errorf("invalid format")
@@ -38,3 +39,23 @@ func ConvertResyncIntervalToDuration(resyncInterval string) (time.Duration, erro
return 0, fmt.Errorf("invalid time unit")
}
}
func ConvertIntervalToTime(resyncInterval string) (time.Time, error) {
duration, err := ConvertIntervalToDuration(resyncInterval)
if err != nil {
return time.Time{}, err
}
// Add duration to current time
return time.Now().Add(duration), nil
}
func AppendAPIEndpoint(address string) string {
if strings.HasSuffix(address, "/api") {
return address
}
if address[len(address)-1] == '/' {
return address + "api"
}
return address + "/api"
}
+27
View File
@@ -0,0 +1,27 @@
package util
import (
"fmt"
"github.com/Infisical/infisical/k8-operator/packages/api"
"github.com/Infisical/infisical/k8-operator/packages/model"
"github.com/go-resty/resty/v2"
)
func GetProjectByID(accessToken string, projectId string) (model.Project, error) {
httpClient := resty.New()
httpClient.
SetAuthScheme("Bearer").
SetAuthToken(accessToken).
SetHeader("Accept", "application/json")
projectDetails, err := api.CallGetProjectByID(httpClient, api.GetProjectByIDRequest{
ProjectID: projectId,
})
if err != nil {
return model.Project{}, fmt.Errorf("unable to get project by slug. [err=%v]", err)
}
return projectDetails.Project, nil
}