Merge branch 'main' into patch-k8s-dependency-vulnerability

This commit is contained in:
Maidul Islam
2023-12-08 15:36:45 -05:00
committed by GitHub
14 changed files with 144 additions and 19 deletions

View File

@@ -429,6 +429,9 @@ export const UpdateSecretByNameBatchV3 = z.object({
secretValueCiphertext: z.string().trim(),
secretValueIV: z.string().trim(),
secretValueTag: z.string().trim(),
secretKeyCiphertext: z.string().trim(),
secretKeyIV: z.string().trim(),
secretKeyTag: z.string().trim(),
secretCommentCiphertext: z.string().trim().optional(),
secretCommentIV: z.string().trim().optional(),
secretCommentTag: z.string().trim().optional(),

View File

@@ -1,6 +1,6 @@
---
title: "PostgreSQL/CockroachDB"
description: "Rotated database user password of a postgreSQL or cochroach db"
description: "Rotated database user password of a postgreSQL or cockroach db"
---
Infisical will update periodically the provided database user's password.

View File

@@ -161,12 +161,65 @@ Default re-sync interval is every 1 minute.
</Accordion>
<Accordion title="managedSecretReference">
The `managedSecretReference` field in the InfisicalSecret resource is used to specify the location where secrets retrieved from an Infisical project should be stored.
You should specify the name and namespace of the Kubernetes secret that will hold these secrets. The operator will create the secret for you, you just need to provide its name and namespace.
The `managedSecretReference` field is used to define the target location for storing secrets retrieved from an Infisical project.
This field requires specifying both the name and namespace of the Kubernetes secret that will hold these secrets.
The Infisical operator will automatically create the Kubernetes secret with the specified name/namespace and keep it continuously updated.
The managed secret be should be created in the same namespace as the deployment that will use it.
Note: The managed secret be should be created in the same namespace as the deployment that will use it.
</Accordion>
<Accordion title="managedSecretReference.secretName">
The name of the managed Kubernetes secret to be created
</Accordion>
<Accordion title="managedSecretReference.secretNamespace">
The namespace of the managed Kubernetes secret to be created.
</Accordion>
<Accordion title="managedSecretReference.secretType">
Override the default Opaque type for managed secrets with this field. Useful for creating kubernetes.io/dockerconfigjson secrets.
</Accordion>
### Propagating labels & annotations
The operator will transfer all labels & annotations present on the `InfisicalSecret` CRD to the managed Kubernetes secret to be created.
Thus, if a specific label is required on the resulting secret, it can be applied as demonstrated in the following example:
<Accordion title="Example propagation">
```yaml
apiVersion: secrets.infisical.com/v1alpha1
kind: InfisicalSecret
metadata:
name: infisicalsecret-sample
labels:
label-to-be-passed-to-managed-secret: sample-value
annotations:
example.com/annotation-to-be-passed-to-managed-secret: "sample-value"
spec:
..
authentication:
...
managedSecretReference:
...
```
This would result in the following managed secret to be created:
```yaml
apiVersion: v1
data:
...
kind: Secret
metadata:
annotations:
example.com/annotation-to-be-passed-to-managed-secret: sample-value
secrets.infisical.com/version: W/"3f1-ZyOSsrCLGSkAhhCkY2USPu2ivRw"
labels:
label-to-be-passed-to-managed-secret: sample-value
name: managed-token
namespace: default
type: Opaque
```
</Accordion>
### Apply the Infisical CRD to your cluster
Once you have configured the Infisical CRD with the required fields, you can apply it to your cluster.

View File

@@ -38,7 +38,7 @@ Other environment variables are listed below to increase the functionality of yo
Credential to connect to host (e.g. team@infisical.com)
</ParamField>
<ParamField query="SMTP_PASSWORD" type="string" default="587" optional>
<ParamField query="SMTP_PASSWORD" type="string" default="none" optional>
Credential to connect to host
</ParamField>

View File

@@ -14,6 +14,7 @@ import { Button, Modal, ModalContent } from "@app/components/v2";
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/context";
import { usePopUp, useToggle } from "@app/hooks";
import { useCreateSecretBatch, useUpdateSecretBatch } from "@app/hooks/api";
import { secretApprovalRequestKeys } from "@app/hooks/api/secretApprovalRequest/queries";
import { secretKeys } from "@app/hooks/api/secrets/queries";
import { DecryptedSecret, UserWsKeyPair } from "@app/hooks/api/types";
@@ -194,6 +195,7 @@ export const SecretDropzone = ({
queryClient.invalidateQueries(
secretKeys.getProjectSecret({ workspaceId, environment, secretPath })
);
queryClient.invalidateQueries(secretApprovalRequestKeys.count({ workspaceId }));
handlePopUpClose("overlapKeyWarning");
createNotification({
type: "success",
@@ -222,9 +224,9 @@ export const SecretDropzone = ({
onDragOver={handleDrag}
onDrop={handleDrop}
className={twMerge(
"relative mx-0.5 mb-4 mt-4 flex cursor-pointer items-center justify-center rounded-md bg-mineshaft-900 py-4 text-sm px-2 text-mineshaft-200 opacity-60 outline-dashed outline-2 outline-chicago-600 duration-200 hover:opacity-100",
"relative mx-0.5 mb-4 mt-4 flex cursor-pointer items-center justify-center rounded-md bg-mineshaft-900 py-4 px-2 text-sm text-mineshaft-200 opacity-60 outline-dashed outline-2 outline-chicago-600 duration-200 hover:opacity-100",
isDragActive && "opacity-100",
!isSmaller && "w-full max-w-3xl flex-col space-y-4 py-20 mx-auto",
!isSmaller && "mx-auto w-full max-w-3xl flex-col space-y-4 py-20",
isLoading && "bg-bunker-800"
)}
>
@@ -238,7 +240,7 @@ export const SecretDropzone = ({
/>
</div>
) : (
<div className="flex items-center justify-cente flex-col space-y-2">
<div className="justify-cente flex flex-col items-center space-y-2">
<div>
<FontAwesomeIcon icon={faUpload} size={isSmaller ? "2x" : "5x"} />
</div>

View File

@@ -7,6 +7,7 @@ import { CreateTagModal } from "@app/components/tags/CreateTagModal";
import { DeleteActionModal } from "@app/components/v2";
import { usePopUp } from "@app/hooks";
import { useCreateSecretV3, useDeleteSecretV3, useUpdateSecretV3 } from "@app/hooks/api";
import { secretApprovalRequestKeys } from "@app/hooks/api/secretApprovalRequest/queries";
import { secretKeys } from "@app/hooks/api/secrets/queries";
import { DecryptedSecret } from "@app/hooks/api/secrets/types";
import { secretSnapshotKeys } from "@app/hooks/api/secretSnapshots/queries";
@@ -262,6 +263,7 @@ export const SecretListView = ({
queryClient.invalidateQueries(
secretSnapshotKeys.count({ workspaceId, environment, directory: secretPath })
);
queryClient.invalidateQueries(secretApprovalRequestKeys.count({ workspaceId }));
handlePopUpClose("secretDetail");
createNotification({
type: "success",
@@ -284,6 +286,7 @@ export const SecretListView = ({
const { key, _id: secretId } = popUp.deleteSecret?.data as DecryptedSecret;
try {
await handleSecretOperation("delete", "shared", key, { secretId });
// wrap this in another function and then reuse
queryClient.invalidateQueries(
secretKeys.getProjectSecret({ workspaceId, environment, secretPath })
);
@@ -293,6 +296,7 @@ export const SecretListView = ({
queryClient.invalidateQueries(
secretSnapshotKeys.count({ workspaceId, environment, directory: secretPath })
);
queryClient.invalidateQueries(secretApprovalRequestKeys.count({ workspaceId }));
handlePopUpClose("deleteSecret");
handlePopUpClose("secretDetail");
createNotification({

View File

@@ -13,7 +13,7 @@ type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.2.1
version: 0.3.1
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.

View File

@@ -102,6 +102,11 @@ spec:
secretNamespace:
description: The name space where the Kubernetes Secret is located
type: string
secretType:
default: Opaque
description: 'The Kubernetes Secret type (experimental feature).
More info: https://kubernetes.io/docs/concepts/configuration/secret/#secret-types'
type: string
required:
- secretName
- secretNamespace

View File

@@ -43,6 +43,21 @@ type KubeSecretReference struct {
SecretNamespace string `json:"secretNamespace"`
}
type MangedKubeSecretConfig struct {
// The name of the Kubernetes Secret
// +kubebuilder:validation:Required
SecretName string `json:"secretName"`
// The name space where the Kubernetes Secret is located
// +kubebuilder:validation:Required
SecretNamespace string `json:"secretNamespace"`
// The Kubernetes Secret type (experimental feature). More info: https://kubernetes.io/docs/concepts/configuration/secret/#secret-types
// +kubebuilder:validation:Optional
// +kubebuilder:default:=Opaque
SecretType string `json:"secretType"`
}
// InfisicalSecretSpec defines the desired state of InfisicalSecret
type InfisicalSecretSpec struct {
// +kubebuilder:validation:Optional
@@ -52,7 +67,7 @@ type InfisicalSecretSpec struct {
Authentication Authentication `json:"authentication"`
// +kubebuilder:validation:Required
ManagedSecretReference KubeSecretReference `json:"managedSecretReference"`
ManagedSecretReference MangedKubeSecretConfig `json:"managedSecretReference"`
// +kubebuilder:default:=60
ResyncInterval int `json:"resyncInterval"`

View File

@@ -157,6 +157,21 @@ func (in *KubeSecretReference) DeepCopy() *KubeSecretReference {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *MangedKubeSecretConfig) DeepCopyInto(out *MangedKubeSecretConfig) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MangedKubeSecretConfig.
func (in *MangedKubeSecretConfig) DeepCopy() *MangedKubeSecretConfig {
if in == nil {
return nil
}
out := new(MangedKubeSecretConfig)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *SecretScopeInWorkspace) DeepCopyInto(out *SecretScopeInWorkspace) {
*out = *in

View File

@@ -102,6 +102,11 @@ spec:
secretNamespace:
description: The name space where the Kubernetes Secret is located
type: string
secretType:
default: Opaque
description: 'The Kubernetes Secret type (experimental feature).
More info: https://kubernetes.io/docs/concepts/configuration/secret/#secret-types'
type: string
required:
- secretName
- secretNamespace

View File

@@ -2,8 +2,12 @@ apiVersion: secrets.infisical.com/v1alpha1
kind: InfisicalSecret
metadata:
name: infisicalsecret-sample
labels:
label-to-be-passed-to-managed-secret: sample-value
annotations:
example.com/annotation-to-be-passed-to-managed-secret: "sample-value"
spec:
hostAPI: http://localhost:8764/api
hostAPI: https://app.infisical.com/api
resyncInterval: 10
authentication:
serviceAccount:
@@ -22,6 +26,8 @@ spec:
managedSecretReference:
secretName: managed-secret
secretNamespace: default
# secretType: kubernetes.io/dockerconfigjson
# # To be depreciated soon
# tokenSecretReference:
# secretName: service-token

View File

@@ -72,7 +72,6 @@ func (r *InfisicalSecretReconciler) GetInfisicalTokenFromKubeSecret(ctx context.
// default to new secret ref structure
secretName := infisicalSecret.Spec.Authentication.ServiceToken.ServiceTokenSecretReference.SecretName
secretNamespace := infisicalSecret.Spec.Authentication.ServiceToken.ServiceTokenSecretReference.SecretNamespace
// fall back to previous secret ref
if secretName == "" {
secretName = infisicalSecret.Spec.TokenSecretReference.SecretName
@@ -129,20 +128,34 @@ func (r *InfisicalSecretReconciler) GetInfisicalServiceAccountCredentialsFromKub
func (r *InfisicalSecretReconciler) CreateInfisicalManagedKubeSecret(ctx context.Context, infisicalSecret v1alpha1.InfisicalSecret, secretsFromAPI []model.SingleEnvironmentVariable, encryptedSecretsResponse api.GetEncryptedSecretsV3Response) error {
plainProcessedSecrets := make(map[string][]byte)
secretType := infisicalSecret.Spec.ManagedSecretReference.SecretType
for _, secret := range secretsFromAPI {
plainProcessedSecrets[secret.Key] = []byte(secret.Value) // plain process
}
// copy labels and annotations from InfisicalSecret CRD
labels := map[string]string{}
for k, v := range infisicalSecret.Labels {
labels[k] = v
}
annotations := map[string]string{}
for k, v := range infisicalSecret.Annotations {
annotations[k] = v
}
annotations[SECRET_VERSION_ANNOTATION] = encryptedSecretsResponse.ETag
// create a new secret as specified by the managed secret spec of CRD
newKubeSecretInstance := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: infisicalSecret.Spec.ManagedSecretReference.SecretName,
Namespace: infisicalSecret.Spec.ManagedSecretReference.SecretNamespace,
Annotations: map[string]string{
SECRET_VERSION_ANNOTATION: encryptedSecretsResponse.ETag,
Annotations: annotations,
Labels: labels,
},
},
Type: "Opaque",
Type: corev1.SecretType(secretType),
Data: plainProcessedSecrets,
}
@@ -151,7 +164,7 @@ func (r *InfisicalSecretReconciler) CreateInfisicalManagedKubeSecret(ctx context
return fmt.Errorf("unable to create the managed Kubernetes secret : %w", err)
}
fmt.Println("Successfully created a managed Kubernetes secret with your Infisical secrets")
fmt.Printf("Successfully created a managed Kubernetes secret with your Infisical secrets. Type: %s\n", secretType)
return nil
}

View File

@@ -108,6 +108,10 @@ spec:
secretNamespace:
description: The name space where the Kubernetes Secret is located
type: string
secretType:
default: Opaque
description: 'The Kubernetes Secret type (experimental feature). More info: https://kubernetes.io/docs/concepts/configuration/secret/#secret-types'
type: string
required:
- secretName
- secretNamespace