allow host api in spec and update spec names

This commit is contained in:
Maidul Islam
2022-12-17 13:27:36 -05:00
parent 6af59e47f5
commit 19daf1410a
12 changed files with 119 additions and 120 deletions
@@ -26,16 +26,4 @@ jobs:
context: k8-operator context: k8-operator
push: true push: true
platforms: linux/amd64,linux/arm64 platforms: linux/amd64,linux/arm64
tags: infisical/kubernetes-operator:latest 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 }}
@@ -38,19 +38,11 @@ spec:
environment: environment:
description: The Infisical environment such as dev, prod, testing description: The Infisical environment such as dev, prod, testing
type: string type: string
infisicalToken: hostAPI:
properties: default: https://app.infisical.com/api
secretName: description: Infisical host to pull secrets from
description: The name of the Kubernetes Secret type: string
type: string managedSecretReference:
secretNamespace:
description: The name space where the Kubernetes Secret is located
type: string
required:
- secretName
- secretNamespace
type: object
managedSecret:
properties: properties:
secretName: secretName:
description: The name of the Kubernetes Secret description: The name of the Kubernetes Secret
@@ -65,6 +57,18 @@ spec:
projectId: projectId:
description: The Infisical project id description: The Infisical project id
type: string 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: required:
- environment - environment
- projectId - projectId
@@ -16,8 +16,8 @@ type KubeSecretReference struct {
// InfisicalSecretSpec defines the desired state of InfisicalSecret // InfisicalSecretSpec defines the desired state of InfisicalSecret
type InfisicalSecretSpec struct { type InfisicalSecretSpec struct {
InfisicalToken KubeSecretReference `json:"infisicalToken,omitempty"` TokenSecretReference KubeSecretReference `json:"tokenSecretReference,omitempty"`
ManagedSecret KubeSecretReference `json:"managedSecret,omitempty"` ManagedSecretReference KubeSecretReference `json:"managedSecretReference,omitempty"`
// The Infisical project id // The Infisical project id
// +kubebuilder:validation:Required // +kubebuilder:validation:Required
@@ -26,6 +26,10 @@ type InfisicalSecretSpec struct {
// The Infisical environment such as dev, prod, testing // The Infisical environment such as dev, prod, testing
// +kubebuilder:validation:Required // +kubebuilder:validation:Required
Environment string `json:"environment"` 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 // 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. // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *InfisicalSecretSpec) DeepCopyInto(out *InfisicalSecretSpec) { func (in *InfisicalSecretSpec) DeepCopyInto(out *InfisicalSecretSpec) {
*out = *in *out = *in
out.InfisicalToken = in.InfisicalToken out.TokenSecretReference = in.TokenSecretReference
out.ManagedSecret = in.ManagedSecret out.ManagedSecretReference = in.ManagedSecretReference
} }
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InfisicalSecretSpec. // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InfisicalSecretSpec.
@@ -38,19 +38,11 @@ spec:
environment: environment:
description: The Infisical environment such as dev, prod, testing description: The Infisical environment such as dev, prod, testing
type: string type: string
infisicalToken: hostAPI:
properties: default: https://app.infisical.com/api
secretName: description: Infisical host to pull secrets from
description: The name of the Kubernetes Secret type: string
type: string managedSecretReference:
secretNamespace:
description: The name space where the Kubernetes Secret is located
type: string
required:
- secretName
- secretNamespace
type: object
managedSecret:
properties: properties:
secretName: secretName:
description: The name of the Kubernetes Secret description: The name of the Kubernetes Secret
@@ -65,6 +57,18 @@ spec:
projectId: projectId:
description: The Infisical project id description: The Infisical project id
type: string 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: required:
- environment - environment
- projectId - projectId
@@ -1,12 +1,12 @@
# Adds namespace to all resources. # Adds namespace to all resources.
namespace: k8-operator-system namespace: infisical-operator-system
# Value of this field is prepended to the # Value of this field is prepended to the
# names of all resources, e.g. a deployment named # names of all resources, e.g. a deployment named
# "wordpress" becomes "alices-wordpress". # "wordpress" becomes "alices-wordpress".
# Note that it should also match with the prefix (text before '-') of the namespace # Note that it should also match with the prefix (text before '-') of the namespace
# field above. # field above.
namePrefix: k8-operator- namePrefix: infisical-operator-
# Labels to add to all resources and selectors. # Labels to add to all resources and selectors.
#commonLabels: #commonLabels:
+14
View 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 var infisicalSecretCR v1alpha1.InfisicalSecret
err := r.Get(ctx, req.NamespacedName, &infisicalSecretCR) err := r.Get(ctx, req.NamespacedName, &infisicalSecretCR)
requeueTime := time.Minute * 5
if err != nil { if err != nil {
if errors.IsNotFound(err) { if errors.IsNotFound(err) {
log.Info("Infisical Secret not found") log.Info("Infisical Secret not found")
@@ -43,7 +45,7 @@ func (r *InfisicalSecretReconciler) Reconcile(ctx context.Context, req ctrl.Requ
} else { } else {
log.Error(err, "Unable to fetch Infisical Secret from cluster. Will retry") log.Error(err, "Unable to fetch Infisical Secret from cluster. Will retry")
return ctrl.Result{ return ctrl.Result{
RequeueAfter: time.Minute, RequeueAfter: requeueTime,
}, nil }, nil
} }
} }
@@ -58,13 +60,13 @@ func (r *InfisicalSecretReconciler) Reconcile(ctx context.Context, req ctrl.Requ
if err != nil { if err != nil {
log.Error(err, "Unable to reconcile Infisical Secret and will try again") log.Error(err, "Unable to reconcile Infisical Secret and will try again")
return ctrl.Result{ return ctrl.Result{
RequeueAfter: time.Minute, RequeueAfter: requeueTime,
}, nil }, nil
} }
// Sync again after the specified time // Sync again after the specified time
return ctrl.Result{ return ctrl.Result{
RequeueAfter: time.Minute, RequeueAfter: requeueTime,
}, nil }, nil
} }
@@ -29,12 +29,12 @@ func (r *InfisicalSecretReconciler) GetKubeSecretByNamespacedName(ctx context.Co
func (r *InfisicalSecretReconciler) GetInfisicalToken(ctx context.Context, infisicalSecret v1alpha1.InfisicalSecret) (string, error) { func (r *InfisicalSecretReconciler) GetInfisicalToken(ctx context.Context, infisicalSecret v1alpha1.InfisicalSecret) (string, error) {
tokenSecret, err := r.GetKubeSecretByNamespacedName(ctx, types.NamespacedName{ tokenSecret, err := r.GetKubeSecretByNamespacedName(ctx, types.NamespacedName{
Namespace: infisicalSecret.Spec.InfisicalToken.SecretNamespace, Namespace: infisicalSecret.Spec.TokenSecretReference.SecretNamespace,
Name: infisicalSecret.Spec.InfisicalToken.SecretName, Name: infisicalSecret.Spec.TokenSecretReference.SecretName,
}) })
if err != nil { 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] 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 // create a new secret as specified by the managed secret spec of CRD
newKubeSecretInstance := &corev1.Secret{ newKubeSecretInstance := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: infisicalSecret.Spec.ManagedSecret.SecretName, Name: infisicalSecret.Spec.ManagedSecretReference.SecretName,
Namespace: infisicalSecret.Spec.ManagedSecret.SecretNamespace, Namespace: infisicalSecret.Spec.ManagedSecretReference.SecretNamespace,
}, },
Type: "Opaque", Type: "Opaque",
Data: plainProcessedSecrets, Data: plainProcessedSecrets,
@@ -94,15 +94,15 @@ func (r *InfisicalSecretReconciler) ReconcileInfisicalSecret(ctx context.Context
} }
managedKubeSecret, err := r.GetKubeSecretByNamespacedName(ctx, types.NamespacedName{ managedKubeSecret, err := r.GetKubeSecretByNamespacedName(ctx, types.NamespacedName{
Name: infisicalSecret.Spec.ManagedSecret.SecretName, Name: infisicalSecret.Spec.ManagedSecretReference.SecretName,
Namespace: infisicalSecret.Spec.ManagedSecret.SecretNamespace, Namespace: infisicalSecret.Spec.ManagedSecretReference.SecretNamespace,
}) })
if err != nil && !errors.IsNotFound(err) { if err != nil && !errors.IsNotFound(err) {
return fmt.Errorf("something went wrong when fetching the managed Kubernetes secret [%w]", 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 { if err != nil {
return err return err
@@ -9,7 +9,7 @@ metadata:
app.kubernetes.io/name: namespace app.kubernetes.io/name: namespace
app.kubernetes.io/part-of: k8-operator app.kubernetes.io/part-of: k8-operator
control-plane: controller-manager control-plane: controller-manager
name: k8-operator-system name: infisical-operator-system
--- ---
apiVersion: apiextensions.k8s.io/v1 apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition kind: CustomResourceDefinition
@@ -46,19 +46,11 @@ spec:
environment: environment:
description: The Infisical environment such as dev, prod, testing description: The Infisical environment such as dev, prod, testing
type: string type: string
infisicalToken: hostAPI:
properties: default: https://app.infisical.com/api
secretName: description: Infisical host to pull secrets from
description: The name of the Kubernetes Secret type: string
type: string managedSecretReference:
secretNamespace:
description: The name space where the Kubernetes Secret is located
type: string
required:
- secretName
- secretNamespace
type: object
managedSecret:
properties: properties:
secretName: secretName:
description: The name of the Kubernetes Secret description: The name of the Kubernetes Secret
@@ -73,6 +65,18 @@ spec:
projectId: projectId:
description: The Infisical project id description: The Infisical project id
type: string 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: required:
- environment - environment
- projectId - projectId
@@ -142,8 +146,8 @@ metadata:
app.kubernetes.io/managed-by: kustomize app.kubernetes.io/managed-by: kustomize
app.kubernetes.io/name: serviceaccount app.kubernetes.io/name: serviceaccount
app.kubernetes.io/part-of: k8-operator app.kubernetes.io/part-of: k8-operator
name: k8-operator-controller-manager name: infisical-operator-controller-manager
namespace: k8-operator-system namespace: infisical-operator-system
--- ---
apiVersion: rbac.authorization.k8s.io/v1 apiVersion: rbac.authorization.k8s.io/v1
kind: Role kind: Role
@@ -155,8 +159,8 @@ metadata:
app.kubernetes.io/managed-by: kustomize app.kubernetes.io/managed-by: kustomize
app.kubernetes.io/name: role app.kubernetes.io/name: role
app.kubernetes.io/part-of: k8-operator app.kubernetes.io/part-of: k8-operator
name: k8-operator-leader-election-role name: infisical-operator-leader-election-role
namespace: k8-operator-system namespace: infisical-operator-system
rules: rules:
- apiGroups: - apiGroups:
- "" - ""
@@ -194,7 +198,7 @@ apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole kind: ClusterRole
metadata: metadata:
creationTimestamp: null creationTimestamp: null
name: k8-operator-manager-role name: infisical-operator-manager-role
rules: rules:
- apiGroups: - apiGroups:
- "" - ""
@@ -253,7 +257,7 @@ metadata:
app.kubernetes.io/managed-by: kustomize app.kubernetes.io/managed-by: kustomize
app.kubernetes.io/name: clusterrole app.kubernetes.io/name: clusterrole
app.kubernetes.io/part-of: k8-operator app.kubernetes.io/part-of: k8-operator
name: k8-operator-metrics-reader name: infisical-operator-metrics-reader
rules: rules:
- nonResourceURLs: - nonResourceURLs:
- /metrics - /metrics
@@ -270,7 +274,7 @@ metadata:
app.kubernetes.io/managed-by: kustomize app.kubernetes.io/managed-by: kustomize
app.kubernetes.io/name: clusterrole app.kubernetes.io/name: clusterrole
app.kubernetes.io/part-of: k8-operator app.kubernetes.io/part-of: k8-operator
name: k8-operator-proxy-role name: infisical-operator-proxy-role
rules: rules:
- apiGroups: - apiGroups:
- authentication.k8s.io - authentication.k8s.io
@@ -295,16 +299,16 @@ metadata:
app.kubernetes.io/managed-by: kustomize app.kubernetes.io/managed-by: kustomize
app.kubernetes.io/name: rolebinding app.kubernetes.io/name: rolebinding
app.kubernetes.io/part-of: k8-operator app.kubernetes.io/part-of: k8-operator
name: k8-operator-leader-election-rolebinding name: infisical-operator-leader-election-rolebinding
namespace: k8-operator-system namespace: infisical-operator-system
roleRef: roleRef:
apiGroup: rbac.authorization.k8s.io apiGroup: rbac.authorization.k8s.io
kind: Role kind: Role
name: k8-operator-leader-election-role name: infisical-operator-leader-election-role
subjects: subjects:
- kind: ServiceAccount - kind: ServiceAccount
name: k8-operator-controller-manager name: infisical-operator-controller-manager
namespace: k8-operator-system namespace: infisical-operator-system
--- ---
apiVersion: rbac.authorization.k8s.io/v1 apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding kind: ClusterRoleBinding
@@ -316,15 +320,15 @@ metadata:
app.kubernetes.io/managed-by: kustomize app.kubernetes.io/managed-by: kustomize
app.kubernetes.io/name: clusterrolebinding app.kubernetes.io/name: clusterrolebinding
app.kubernetes.io/part-of: k8-operator app.kubernetes.io/part-of: k8-operator
name: k8-operator-manager-rolebinding name: infisical-operator-manager-rolebinding
roleRef: roleRef:
apiGroup: rbac.authorization.k8s.io apiGroup: rbac.authorization.k8s.io
kind: ClusterRole kind: ClusterRole
name: k8-operator-manager-role name: infisical-operator-manager-role
subjects: subjects:
- kind: ServiceAccount - kind: ServiceAccount
name: k8-operator-controller-manager name: infisical-operator-controller-manager
namespace: k8-operator-system namespace: infisical-operator-system
--- ---
apiVersion: rbac.authorization.k8s.io/v1 apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding kind: ClusterRoleBinding
@@ -336,15 +340,15 @@ metadata:
app.kubernetes.io/managed-by: kustomize app.kubernetes.io/managed-by: kustomize
app.kubernetes.io/name: clusterrolebinding app.kubernetes.io/name: clusterrolebinding
app.kubernetes.io/part-of: k8-operator app.kubernetes.io/part-of: k8-operator
name: k8-operator-proxy-rolebinding name: infisical-operator-proxy-rolebinding
roleRef: roleRef:
apiGroup: rbac.authorization.k8s.io apiGroup: rbac.authorization.k8s.io
kind: ClusterRole kind: ClusterRole
name: k8-operator-proxy-role name: infisical-operator-proxy-role
subjects: subjects:
- kind: ServiceAccount - kind: ServiceAccount
name: k8-operator-controller-manager name: infisical-operator-controller-manager
namespace: k8-operator-system namespace: infisical-operator-system
--- ---
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
@@ -357,8 +361,8 @@ metadata:
app.kubernetes.io/name: service app.kubernetes.io/name: service
app.kubernetes.io/part-of: k8-operator app.kubernetes.io/part-of: k8-operator
control-plane: controller-manager control-plane: controller-manager
name: k8-operator-controller-manager-metrics-service name: infisical-operator-controller-manager-metrics-service
namespace: k8-operator-system namespace: infisical-operator-system
spec: spec:
ports: ports:
- name: https - name: https
@@ -379,8 +383,8 @@ metadata:
app.kubernetes.io/name: deployment app.kubernetes.io/name: deployment
app.kubernetes.io/part-of: k8-operator app.kubernetes.io/part-of: k8-operator
control-plane: controller-manager control-plane: controller-manager
name: k8-operator-controller-manager name: infisical-operator-controller-manager
namespace: k8-operator-system namespace: infisical-operator-system
spec: spec:
replicas: 1 replicas: 1
selector: selector:
@@ -467,5 +471,5 @@ spec:
- ALL - ALL
securityContext: securityContext:
runAsNonRoot: true runAsNonRoot: true
serviceAccountName: k8-operator-controller-manager serviceAccountName: infisical-operator-controller-manager
terminationGracePeriodSeconds: 10 terminationGracePeriodSeconds: 10
+4 -6
View File
@@ -13,10 +13,8 @@ import (
"golang.org/x/crypto/nacl/box" "golang.org/x/crypto/nacl/box"
) )
const INFISICAL_URL = "https://app.infisical.com/api" func GetAllEnvironmentVariables(projectId string, envName string, infisicalToken string, hostAPI string) ([]models.SingleEnvironmentVariable, error) {
envsFromApi, err := GetSecretsFromAPIUsingInfisicalToken(infisicalToken, envName, projectId, hostAPI)
func GetAllEnvironmentVariables(projectId string, envName string, infisicalToken string) ([]models.SingleEnvironmentVariable, error) {
envsFromApi, err := GetSecretsFromAPIUsingInfisicalToken(infisicalToken, envName, projectId)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -24,7 +22,7 @@ func GetAllEnvironmentVariables(projectId string, envName string, infisicalToken
return SubstituteSecrets(envsFromApi), nil 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 == "" { if infisicalToken == "" || projectId == "" || envName == "" {
return nil, errors.New("infisical token, project id and or environment name cannot be empty") 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("environment", envName).
SetQueryParam("channel", "cli"). SetQueryParam("channel", "cli").
SetResult(&pullSecretsByInfisicalTokenResponse). 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 { if err != nil {
return nil, err return nil, err