mirror of
https://github.com/Infisical/infisical.git
synced 2025-03-25 14:05:03 +00:00
allow host api in spec and update spec names
This commit is contained in:
@ -26,16 +26,4 @@ jobs:
|
||||
context: k8-operator
|
||||
push: true
|
||||
platforms: linux/amd64,linux/arm64
|
||||
tags: infisical/kubernetes-operator:latest
|
||||
|
||||
- uses: actions/setup-go@v2
|
||||
|
||||
- name: Generate YAML for Kubectl
|
||||
run: make dist charts
|
||||
|
||||
- name: Upload CRD manifest
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
file: dist/install-secrets-operator.yaml
|
||||
tag: ${{ github.ref }}
|
||||
tags: infisical/kubernetes-operator:latest
|
@ -38,19 +38,11 @@ spec:
|
||||
environment:
|
||||
description: The Infisical environment such as dev, prod, testing
|
||||
type: string
|
||||
infisicalToken:
|
||||
properties:
|
||||
secretName:
|
||||
description: The name of the Kubernetes Secret
|
||||
type: string
|
||||
secretNamespace:
|
||||
description: The name space where the Kubernetes Secret is located
|
||||
type: string
|
||||
required:
|
||||
- secretName
|
||||
- secretNamespace
|
||||
type: object
|
||||
managedSecret:
|
||||
hostAPI:
|
||||
default: https://app.infisical.com/api
|
||||
description: Infisical host to pull secrets from
|
||||
type: string
|
||||
managedSecretReference:
|
||||
properties:
|
||||
secretName:
|
||||
description: The name of the Kubernetes Secret
|
||||
@ -65,6 +57,18 @@ spec:
|
||||
projectId:
|
||||
description: The Infisical project id
|
||||
type: string
|
||||
tokenSecretReference:
|
||||
properties:
|
||||
secretName:
|
||||
description: The name of the Kubernetes Secret
|
||||
type: string
|
||||
secretNamespace:
|
||||
description: The name space where the Kubernetes Secret is located
|
||||
type: string
|
||||
required:
|
||||
- secretName
|
||||
- secretNamespace
|
||||
type: object
|
||||
required:
|
||||
- environment
|
||||
- projectId
|
||||
|
@ -16,8 +16,8 @@ type KubeSecretReference struct {
|
||||
|
||||
// InfisicalSecretSpec defines the desired state of InfisicalSecret
|
||||
type InfisicalSecretSpec struct {
|
||||
InfisicalToken KubeSecretReference `json:"infisicalToken,omitempty"`
|
||||
ManagedSecret KubeSecretReference `json:"managedSecret,omitempty"`
|
||||
TokenSecretReference KubeSecretReference `json:"tokenSecretReference,omitempty"`
|
||||
ManagedSecretReference KubeSecretReference `json:"managedSecretReference,omitempty"`
|
||||
|
||||
// The Infisical project id
|
||||
// +kubebuilder:validation:Required
|
||||
@ -26,6 +26,10 @@ type InfisicalSecretSpec struct {
|
||||
// The Infisical environment such as dev, prod, testing
|
||||
// +kubebuilder:validation:Required
|
||||
Environment string `json:"environment"`
|
||||
|
||||
// Infisical host to pull secrets from
|
||||
// +kubebuilder:default="https://app.infisical.com/api"
|
||||
HostAPI string `json:"hostAPI,omitempty"`
|
||||
}
|
||||
|
||||
// InfisicalSecretStatus defines the observed state of InfisicalSecret
|
||||
|
@ -88,8 +88,8 @@ func (in *InfisicalSecretList) DeepCopyObject() runtime.Object {
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *InfisicalSecretSpec) DeepCopyInto(out *InfisicalSecretSpec) {
|
||||
*out = *in
|
||||
out.InfisicalToken = in.InfisicalToken
|
||||
out.ManagedSecret = in.ManagedSecret
|
||||
out.TokenSecretReference = in.TokenSecretReference
|
||||
out.ManagedSecretReference = in.ManagedSecretReference
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InfisicalSecretSpec.
|
||||
|
@ -38,19 +38,11 @@ spec:
|
||||
environment:
|
||||
description: The Infisical environment such as dev, prod, testing
|
||||
type: string
|
||||
infisicalToken:
|
||||
properties:
|
||||
secretName:
|
||||
description: The name of the Kubernetes Secret
|
||||
type: string
|
||||
secretNamespace:
|
||||
description: The name space where the Kubernetes Secret is located
|
||||
type: string
|
||||
required:
|
||||
- secretName
|
||||
- secretNamespace
|
||||
type: object
|
||||
managedSecret:
|
||||
hostAPI:
|
||||
default: https://app.infisical.com/api
|
||||
description: Infisical host to pull secrets from
|
||||
type: string
|
||||
managedSecretReference:
|
||||
properties:
|
||||
secretName:
|
||||
description: The name of the Kubernetes Secret
|
||||
@ -65,6 +57,18 @@ spec:
|
||||
projectId:
|
||||
description: The Infisical project id
|
||||
type: string
|
||||
tokenSecretReference:
|
||||
properties:
|
||||
secretName:
|
||||
description: The name of the Kubernetes Secret
|
||||
type: string
|
||||
secretNamespace:
|
||||
description: The name space where the Kubernetes Secret is located
|
||||
type: string
|
||||
required:
|
||||
- secretName
|
||||
- secretNamespace
|
||||
type: object
|
||||
required:
|
||||
- environment
|
||||
- projectId
|
||||
|
@ -1,12 +1,12 @@
|
||||
# Adds namespace to all resources.
|
||||
namespace: k8-operator-system
|
||||
namespace: infisical-operator-system
|
||||
|
||||
# Value of this field is prepended to the
|
||||
# names of all resources, e.g. a deployment named
|
||||
# "wordpress" becomes "alices-wordpress".
|
||||
# Note that it should also match with the prefix (text before '-') of the namespace
|
||||
# field above.
|
||||
namePrefix: k8-operator-
|
||||
namePrefix: infisical-operator-
|
||||
|
||||
# Labels to add to all resources and selectors.
|
||||
#commonLabels:
|
||||
|
14
k8-operator/config/samples/sample.yaml
Normal file
14
k8-operator/config/samples/sample.yaml
Normal file
@ -0,0 +1,14 @@
|
||||
apiVersion: secrets.infisical.com/v1alpha1
|
||||
kind: InfisicalSecret
|
||||
metadata:
|
||||
name: infisicalsecret-sample
|
||||
# namespace: first-project
|
||||
spec:
|
||||
projectId: 62faf98ae0b05e8529b5da46
|
||||
environment: dev
|
||||
tokenSecretReference:
|
||||
secretName: service-token
|
||||
secretNamespace: first-project
|
||||
managedSecretReference:
|
||||
secretName: managed-secret
|
||||
secretNamespace: first-project
|
@ -1,19 +0,0 @@
|
||||
apiVersion: secrets.infisical.com/v1alpha1
|
||||
kind: InfisicalSecret
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: infisicalsecret
|
||||
app.kubernetes.io/instance: infisicalsecret-sample
|
||||
app.kubernetes.io/part-of: k8-operator
|
||||
app.kubernetes.io/managed-by: kustomize
|
||||
app.kubernetes.io/created-by: k8-operator
|
||||
name: infisicalsecret-sample
|
||||
spec:
|
||||
projectId: 62faf98ae0b05e8529b5da46
|
||||
environment: dev
|
||||
infisicalToken:
|
||||
secretName: service-token
|
||||
secretNamespace: default
|
||||
managedSecret:
|
||||
secretName: managed-secret
|
||||
secretNamespace: default
|
@ -36,6 +36,8 @@ func (r *InfisicalSecretReconciler) Reconcile(ctx context.Context, req ctrl.Requ
|
||||
var infisicalSecretCR v1alpha1.InfisicalSecret
|
||||
err := r.Get(ctx, req.NamespacedName, &infisicalSecretCR)
|
||||
|
||||
requeueTime := time.Minute * 5
|
||||
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
log.Info("Infisical Secret not found")
|
||||
@ -43,7 +45,7 @@ func (r *InfisicalSecretReconciler) Reconcile(ctx context.Context, req ctrl.Requ
|
||||
} else {
|
||||
log.Error(err, "Unable to fetch Infisical Secret from cluster. Will retry")
|
||||
return ctrl.Result{
|
||||
RequeueAfter: time.Minute,
|
||||
RequeueAfter: requeueTime,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
@ -58,13 +60,13 @@ func (r *InfisicalSecretReconciler) Reconcile(ctx context.Context, req ctrl.Requ
|
||||
if err != nil {
|
||||
log.Error(err, "Unable to reconcile Infisical Secret and will try again")
|
||||
return ctrl.Result{
|
||||
RequeueAfter: time.Minute,
|
||||
RequeueAfter: requeueTime,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Sync again after the specified time
|
||||
return ctrl.Result{
|
||||
RequeueAfter: time.Minute,
|
||||
RequeueAfter: requeueTime,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -29,12 +29,12 @@ func (r *InfisicalSecretReconciler) GetKubeSecretByNamespacedName(ctx context.Co
|
||||
|
||||
func (r *InfisicalSecretReconciler) GetInfisicalToken(ctx context.Context, infisicalSecret v1alpha1.InfisicalSecret) (string, error) {
|
||||
tokenSecret, err := r.GetKubeSecretByNamespacedName(ctx, types.NamespacedName{
|
||||
Namespace: infisicalSecret.Spec.InfisicalToken.SecretNamespace,
|
||||
Name: infisicalSecret.Spec.InfisicalToken.SecretName,
|
||||
Namespace: infisicalSecret.Spec.TokenSecretReference.SecretNamespace,
|
||||
Name: infisicalSecret.Spec.TokenSecretReference.SecretName,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to read Infisical token secret from secret named [%s] in namespace [%s]: with error [%w]", infisicalSecret.Spec.ManagedSecret.SecretName, infisicalSecret.Spec.ManagedSecret.SecretNamespace, err)
|
||||
return "", fmt.Errorf("failed to read Infisical token secret from secret named [%s] in namespace [%s]: with error [%w]", infisicalSecret.Spec.ManagedSecretReference.SecretName, infisicalSecret.Spec.ManagedSecretReference.SecretNamespace, err)
|
||||
}
|
||||
|
||||
infisicalServiceToken := tokenSecret.Data[INFISICAL_TOKEN_SECRET_KEY_NAME]
|
||||
@ -54,8 +54,8 @@ func (r *InfisicalSecretReconciler) CreateInfisicalManagedKubeSecret(ctx context
|
||||
// create a new secret as specified by the managed secret spec of CRD
|
||||
newKubeSecretInstance := &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: infisicalSecret.Spec.ManagedSecret.SecretName,
|
||||
Namespace: infisicalSecret.Spec.ManagedSecret.SecretNamespace,
|
||||
Name: infisicalSecret.Spec.ManagedSecretReference.SecretName,
|
||||
Namespace: infisicalSecret.Spec.ManagedSecretReference.SecretNamespace,
|
||||
},
|
||||
Type: "Opaque",
|
||||
Data: plainProcessedSecrets,
|
||||
@ -94,15 +94,15 @@ func (r *InfisicalSecretReconciler) ReconcileInfisicalSecret(ctx context.Context
|
||||
}
|
||||
|
||||
managedKubeSecret, err := r.GetKubeSecretByNamespacedName(ctx, types.NamespacedName{
|
||||
Name: infisicalSecret.Spec.ManagedSecret.SecretName,
|
||||
Namespace: infisicalSecret.Spec.ManagedSecret.SecretNamespace,
|
||||
Name: infisicalSecret.Spec.ManagedSecretReference.SecretName,
|
||||
Namespace: infisicalSecret.Spec.ManagedSecretReference.SecretNamespace,
|
||||
})
|
||||
|
||||
if err != nil && !errors.IsNotFound(err) {
|
||||
return fmt.Errorf("something went wrong when fetching the managed Kubernetes secret [%w]", err)
|
||||
}
|
||||
|
||||
secretsFromApi, err := api.GetAllEnvironmentVariables(infisicalSecret.Spec.ProjectId, infisicalSecret.Spec.Environment, infisicalToken)
|
||||
secretsFromApi, err := api.GetAllEnvironmentVariables(infisicalSecret.Spec.ProjectId, infisicalSecret.Spec.Environment, infisicalToken, infisicalSecret.Spec.HostAPI)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -9,7 +9,7 @@ metadata:
|
||||
app.kubernetes.io/name: namespace
|
||||
app.kubernetes.io/part-of: k8-operator
|
||||
control-plane: controller-manager
|
||||
name: k8-operator-system
|
||||
name: infisical-operator-system
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
@ -46,19 +46,11 @@ spec:
|
||||
environment:
|
||||
description: The Infisical environment such as dev, prod, testing
|
||||
type: string
|
||||
infisicalToken:
|
||||
properties:
|
||||
secretName:
|
||||
description: The name of the Kubernetes Secret
|
||||
type: string
|
||||
secretNamespace:
|
||||
description: The name space where the Kubernetes Secret is located
|
||||
type: string
|
||||
required:
|
||||
- secretName
|
||||
- secretNamespace
|
||||
type: object
|
||||
managedSecret:
|
||||
hostAPI:
|
||||
default: https://app.infisical.com/api
|
||||
description: Infisical host to pull secrets from
|
||||
type: string
|
||||
managedSecretReference:
|
||||
properties:
|
||||
secretName:
|
||||
description: The name of the Kubernetes Secret
|
||||
@ -73,6 +65,18 @@ spec:
|
||||
projectId:
|
||||
description: The Infisical project id
|
||||
type: string
|
||||
tokenSecretReference:
|
||||
properties:
|
||||
secretName:
|
||||
description: The name of the Kubernetes Secret
|
||||
type: string
|
||||
secretNamespace:
|
||||
description: The name space where the Kubernetes Secret is located
|
||||
type: string
|
||||
required:
|
||||
- secretName
|
||||
- secretNamespace
|
||||
type: object
|
||||
required:
|
||||
- environment
|
||||
- projectId
|
||||
@ -142,8 +146,8 @@ metadata:
|
||||
app.kubernetes.io/managed-by: kustomize
|
||||
app.kubernetes.io/name: serviceaccount
|
||||
app.kubernetes.io/part-of: k8-operator
|
||||
name: k8-operator-controller-manager
|
||||
namespace: k8-operator-system
|
||||
name: infisical-operator-controller-manager
|
||||
namespace: infisical-operator-system
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
@ -155,8 +159,8 @@ metadata:
|
||||
app.kubernetes.io/managed-by: kustomize
|
||||
app.kubernetes.io/name: role
|
||||
app.kubernetes.io/part-of: k8-operator
|
||||
name: k8-operator-leader-election-role
|
||||
namespace: k8-operator-system
|
||||
name: infisical-operator-leader-election-role
|
||||
namespace: infisical-operator-system
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
@ -194,7 +198,7 @@ apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: k8-operator-manager-role
|
||||
name: infisical-operator-manager-role
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
@ -253,7 +257,7 @@ metadata:
|
||||
app.kubernetes.io/managed-by: kustomize
|
||||
app.kubernetes.io/name: clusterrole
|
||||
app.kubernetes.io/part-of: k8-operator
|
||||
name: k8-operator-metrics-reader
|
||||
name: infisical-operator-metrics-reader
|
||||
rules:
|
||||
- nonResourceURLs:
|
||||
- /metrics
|
||||
@ -270,7 +274,7 @@ metadata:
|
||||
app.kubernetes.io/managed-by: kustomize
|
||||
app.kubernetes.io/name: clusterrole
|
||||
app.kubernetes.io/part-of: k8-operator
|
||||
name: k8-operator-proxy-role
|
||||
name: infisical-operator-proxy-role
|
||||
rules:
|
||||
- apiGroups:
|
||||
- authentication.k8s.io
|
||||
@ -295,16 +299,16 @@ metadata:
|
||||
app.kubernetes.io/managed-by: kustomize
|
||||
app.kubernetes.io/name: rolebinding
|
||||
app.kubernetes.io/part-of: k8-operator
|
||||
name: k8-operator-leader-election-rolebinding
|
||||
namespace: k8-operator-system
|
||||
name: infisical-operator-leader-election-rolebinding
|
||||
namespace: infisical-operator-system
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: k8-operator-leader-election-role
|
||||
name: infisical-operator-leader-election-role
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: k8-operator-controller-manager
|
||||
namespace: k8-operator-system
|
||||
name: infisical-operator-controller-manager
|
||||
namespace: infisical-operator-system
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
@ -316,15 +320,15 @@ metadata:
|
||||
app.kubernetes.io/managed-by: kustomize
|
||||
app.kubernetes.io/name: clusterrolebinding
|
||||
app.kubernetes.io/part-of: k8-operator
|
||||
name: k8-operator-manager-rolebinding
|
||||
name: infisical-operator-manager-rolebinding
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: k8-operator-manager-role
|
||||
name: infisical-operator-manager-role
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: k8-operator-controller-manager
|
||||
namespace: k8-operator-system
|
||||
name: infisical-operator-controller-manager
|
||||
namespace: infisical-operator-system
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
@ -336,15 +340,15 @@ metadata:
|
||||
app.kubernetes.io/managed-by: kustomize
|
||||
app.kubernetes.io/name: clusterrolebinding
|
||||
app.kubernetes.io/part-of: k8-operator
|
||||
name: k8-operator-proxy-rolebinding
|
||||
name: infisical-operator-proxy-rolebinding
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: k8-operator-proxy-role
|
||||
name: infisical-operator-proxy-role
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: k8-operator-controller-manager
|
||||
namespace: k8-operator-system
|
||||
name: infisical-operator-controller-manager
|
||||
namespace: infisical-operator-system
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
@ -357,8 +361,8 @@ metadata:
|
||||
app.kubernetes.io/name: service
|
||||
app.kubernetes.io/part-of: k8-operator
|
||||
control-plane: controller-manager
|
||||
name: k8-operator-controller-manager-metrics-service
|
||||
namespace: k8-operator-system
|
||||
name: infisical-operator-controller-manager-metrics-service
|
||||
namespace: infisical-operator-system
|
||||
spec:
|
||||
ports:
|
||||
- name: https
|
||||
@ -379,8 +383,8 @@ metadata:
|
||||
app.kubernetes.io/name: deployment
|
||||
app.kubernetes.io/part-of: k8-operator
|
||||
control-plane: controller-manager
|
||||
name: k8-operator-controller-manager
|
||||
namespace: k8-operator-system
|
||||
name: infisical-operator-controller-manager
|
||||
namespace: infisical-operator-system
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
@ -467,5 +471,5 @@ spec:
|
||||
- ALL
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
serviceAccountName: k8-operator-controller-manager
|
||||
serviceAccountName: infisical-operator-controller-manager
|
||||
terminationGracePeriodSeconds: 10
|
||||
|
@ -13,10 +13,8 @@ import (
|
||||
"golang.org/x/crypto/nacl/box"
|
||||
)
|
||||
|
||||
const INFISICAL_URL = "https://app.infisical.com/api"
|
||||
|
||||
func GetAllEnvironmentVariables(projectId string, envName string, infisicalToken string) ([]models.SingleEnvironmentVariable, error) {
|
||||
envsFromApi, err := GetSecretsFromAPIUsingInfisicalToken(infisicalToken, envName, projectId)
|
||||
func GetAllEnvironmentVariables(projectId string, envName string, infisicalToken string, hostAPI string) ([]models.SingleEnvironmentVariable, error) {
|
||||
envsFromApi, err := GetSecretsFromAPIUsingInfisicalToken(infisicalToken, envName, projectId, hostAPI)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -24,7 +22,7 @@ func GetAllEnvironmentVariables(projectId string, envName string, infisicalToken
|
||||
return SubstituteSecrets(envsFromApi), nil
|
||||
}
|
||||
|
||||
func GetSecretsFromAPIUsingInfisicalToken(infisicalToken string, envName string, projectId string) ([]models.SingleEnvironmentVariable, error) {
|
||||
func GetSecretsFromAPIUsingInfisicalToken(infisicalToken string, envName string, projectId string, hostAPI string) ([]models.SingleEnvironmentVariable, error) {
|
||||
if infisicalToken == "" || projectId == "" || envName == "" {
|
||||
return nil, errors.New("infisical token, project id and or environment name cannot be empty")
|
||||
}
|
||||
@ -44,7 +42,7 @@ func GetSecretsFromAPIUsingInfisicalToken(infisicalToken string, envName string,
|
||||
SetQueryParam("environment", envName).
|
||||
SetQueryParam("channel", "cli").
|
||||
SetResult(&pullSecretsByInfisicalTokenResponse).
|
||||
Get(fmt.Sprintf("%v/v1/secret/%v/service-token", INFISICAL_URL, projectId))
|
||||
Get(fmt.Sprintf("%v/v1/secret/%v/service-token", hostAPI, projectId))
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
Reference in New Issue
Block a user