mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
Merge pull request #3540 from Infisical/daniel/generators
feat(k8s): generator support
This commit is contained in:
@@ -34,7 +34,7 @@ Before applying the InfisicalPushSecret CRD, you need to create a Kubernetes sec
|
|||||||
metadata:
|
metadata:
|
||||||
name: infisical-push-secret-demo
|
name: infisical-push-secret-demo
|
||||||
spec:
|
spec:
|
||||||
resyncInterval: 1m
|
resyncInterval: 1m # Remove this field to disable automatic reconciliation of the InfisicalPushSecret CRD.
|
||||||
hostAPI: https://app.infisical.com/api
|
hostAPI: https://app.infisical.com/api
|
||||||
|
|
||||||
# Optional, defaults to no replacement.
|
# Optional, defaults to no replacement.
|
||||||
@@ -124,7 +124,9 @@ After applying the InfisicalPushSecret CRD, you should notice that the secrets y
|
|||||||
|
|
||||||
<Accordion title="resyncInterval">
|
<Accordion title="resyncInterval">
|
||||||
|
|
||||||
The `resyncInterval` is a string-formatted duration that defines the time between each resync.
|
The `resyncInterval` is a string-formatted duration that defines the time between each resync. The field is optional, and will default to no automatic resync if not defined.
|
||||||
|
|
||||||
|
If you don't want to automatically reconcile the InfisicalPushSecret CRD on an interval, you can remove the `resyncInterval` field entirely from your InfisicalPushSecret CRD.
|
||||||
|
|
||||||
The format of the field is `[duration][unit]` where `duration` is a number and `unit` is a string representing the unit of time.
|
The format of the field is `[duration][unit]` where `duration` is a number and `unit` is a string representing the unit of time.
|
||||||
|
|
||||||
@@ -459,6 +461,126 @@ Using Go templates, you can format, combine, and create new key-value pairs of s
|
|||||||
Please refer to the [templating functions documentation](/integrations/platforms/kubernetes/overview#available-helper-functions) for more information.
|
Please refer to the [templating functions documentation](/integrations/platforms/kubernetes/overview#available-helper-functions) for more information.
|
||||||
</Accordion>
|
</Accordion>
|
||||||
|
|
||||||
|
## Using generators to push secrets
|
||||||
|
|
||||||
|
Generators are a feature of the Infisical secrets operator that allows you to generate secrets on-reconcile and push them to Infisical. This is useful for secret rotation purposes, and fully operator-managed secrets.
|
||||||
|
A generator is a custom resource that is installed on the cluster that defines the logic for generating a secret.
|
||||||
|
|
||||||
|
Generators don't keep track of the secrets they generate, which means that on each reconciliation, a new value will be created and pushed.
|
||||||
|
For this reason you may want to disable automatic reconciliation of the InfisicalPushSecret CRD. You can do this by removing `resyncInterval` from the InfisicalPushSecret CRD.
|
||||||
|
|
||||||
|
**Supported generators**:
|
||||||
|
- `Password`: Generates a random password of string format.
|
||||||
|
- `UUID`: Generates a random v4 UUID.
|
||||||
|
|
||||||
|
To use a generator, you must specify at least one generator in the `push.generators[]` field. An example of a generator usage can be seen here:
|
||||||
|
|
||||||
|
<Accordion title="push.generators[]">
|
||||||
|
Define a generator in the `push.generators[]` field.
|
||||||
|
|
||||||
|
<Accordion title="push.generators[].destinationSecretName">
|
||||||
|
The name of the secret that will be created in Infisical.
|
||||||
|
</Accordion>
|
||||||
|
|
||||||
|
<Accordion title="push.generators[].generatorRef">
|
||||||
|
The reference to the generator resource.
|
||||||
|
|
||||||
|
Valid fields:
|
||||||
|
- `kind`: The kind of the generator resource, must match the generator kind.
|
||||||
|
- `name`: The name of the generator resource.
|
||||||
|
</Accordion>
|
||||||
|
</Accordion>
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
push:
|
||||||
|
secret:
|
||||||
|
secretName: push-secret-source-secret
|
||||||
|
secretNamespace: dev
|
||||||
|
generators:
|
||||||
|
- destinationSecretName: password-generator # Name of the secret that will be created in Infisical
|
||||||
|
generatorRef:
|
||||||
|
kind: Password|UUID # Kind of the resource, must match the generator kind.
|
||||||
|
name: custom-generator # Name of the generator resource
|
||||||
|
```
|
||||||
|
|
||||||
|
<Tabs>
|
||||||
|
<Tab title="Password Generator">
|
||||||
|
|
||||||
|
The Password generator is a custom resource that is installed on the cluster that defines the logic for generating a password.
|
||||||
|
<Accordion title="Spec definition">
|
||||||
|
|
||||||
|
- `kind`: The kind of the generator resource, must match the generator kind. For the Password generator, the kind is `Password`.
|
||||||
|
- `generator.passwordSpec`: The spec of the password generator.
|
||||||
|
|
||||||
|
<Accordion title="generator.passwordSpec">
|
||||||
|
- `length`: The length of the password.
|
||||||
|
- `digits`: The number of digits in the password.
|
||||||
|
- `symbols`: The number of symbols in the password.
|
||||||
|
- `symbolCharacters`: The characters to use for the symbols in the password.
|
||||||
|
- `noUpper`: Whether to include uppercase letters in the password.
|
||||||
|
- `allowRepeat`: Whether to allow repeating characters in the password.
|
||||||
|
</Accordion>
|
||||||
|
</Accordion>
|
||||||
|
|
||||||
|
```yaml password-cluster-generator.yaml
|
||||||
|
apiVersion: secrets.infisical.com/v1alpha1
|
||||||
|
kind: ClusterGenerator
|
||||||
|
metadata:
|
||||||
|
name: password-generator
|
||||||
|
spec:
|
||||||
|
kind: Password
|
||||||
|
generator:
|
||||||
|
passwordSpec:
|
||||||
|
length: 10
|
||||||
|
digits: 5
|
||||||
|
symbols: 5
|
||||||
|
symbolCharacters: "-_$@"
|
||||||
|
noUpper: false
|
||||||
|
allowRepeat: true
|
||||||
|
```
|
||||||
|
|
||||||
|
Example InfisicalPushSecret CRD using the Password generator:
|
||||||
|
```yaml infisical-push-secret-crd.yaml
|
||||||
|
push:
|
||||||
|
generators:
|
||||||
|
- destinationSecretName: password-generator-test
|
||||||
|
generatorRef:
|
||||||
|
kind: Password
|
||||||
|
name: password-generator
|
||||||
|
```
|
||||||
|
</Tab>
|
||||||
|
<Tab title="UUID Generator">
|
||||||
|
The UUID generator is a custom resource that is installed on the cluster that defines the logic for generating a UUID.
|
||||||
|
<Accordion title="Spec definition">
|
||||||
|
- `kind`: The kind of the generator resource, must match the generator kind. For the UUID generator, the kind is `UUID`.
|
||||||
|
- `generator.uuidSpec`: The spec of the UUID generator. For UUID's, this can be left empty.
|
||||||
|
</Accordion>
|
||||||
|
|
||||||
|
```yaml uuid-cluster-generator.yaml
|
||||||
|
apiVersion: secrets.infisical.com/v1alpha1
|
||||||
|
kind: ClusterGenerator
|
||||||
|
metadata:
|
||||||
|
name: uuid-generator
|
||||||
|
spec:
|
||||||
|
kind: UUID
|
||||||
|
generator:
|
||||||
|
uuidSpec:
|
||||||
|
```
|
||||||
|
|
||||||
|
Example InfisicalPushSecret CRD using the UUID generator:
|
||||||
|
```yaml infisical-push-secret-crd.yaml
|
||||||
|
push:
|
||||||
|
generators:
|
||||||
|
- destinationSecretName: uuid-generator-test
|
||||||
|
generatorRef:
|
||||||
|
kind: UUID
|
||||||
|
name: uuid-generator
|
||||||
|
```
|
||||||
|
</Tab>
|
||||||
|
</Tabs>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Applying the InfisicalPushSecret CRD to your cluster
|
## Applying the InfisicalPushSecret CRD to your cluster
|
||||||
|
|
||||||
Once you have configured the `InfisicalPushSecret` CRD with the required fields, you can apply it to your cluster.
|
Once you have configured the `InfisicalPushSecret` CRD with the required fields, you can apply it to your cluster.
|
||||||
|
|||||||
152
k8-operator/api/v1alpha1/generators.go
Normal file
152
k8-operator/api/v1alpha1/generators.go
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2022.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package v1alpha1
|
||||||
|
|
||||||
|
import (
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GeneratorKind represents a kind of generator.
|
||||||
|
// +kubebuilder:validation:Enum=Password;UUID
|
||||||
|
type GeneratorKind string
|
||||||
|
|
||||||
|
const (
|
||||||
|
GeneratorKindPassword GeneratorKind = "Password"
|
||||||
|
GeneratorKindUUID GeneratorKind = "UUID"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ClusterGeneratorSpec struct {
|
||||||
|
// Kind the kind of this generator.
|
||||||
|
Kind GeneratorKind `json:"kind"`
|
||||||
|
|
||||||
|
// Generator the spec for this generator, must match the kind.
|
||||||
|
Generator GeneratorSpec `json:"generator,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GeneratorSpec struct {
|
||||||
|
// +kubebuilder:validation:Optional
|
||||||
|
PasswordSpec *PasswordSpec `json:"passwordSpec,omitempty"`
|
||||||
|
// +kubebuilder:validation:Optional
|
||||||
|
UUIDSpec *UUIDSpec `json:"uuidSpec,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClusterGenerator represents a cluster-wide generator
|
||||||
|
// +kubebuilder:object:root=true
|
||||||
|
// +kubebuilder:storageversion
|
||||||
|
// +kubebuilder:subresource:status
|
||||||
|
// +kubebuilder:resource:scope=Cluster
|
||||||
|
type ClusterGenerator struct {
|
||||||
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||||
|
|
||||||
|
Spec ClusterGeneratorSpec `json:"spec,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// +kubebuilder:object:root=true
|
||||||
|
|
||||||
|
// ClusterGeneratorList contains a list of ClusterGenerator resources.
|
||||||
|
type ClusterGeneratorList struct {
|
||||||
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
metav1.ListMeta `json:"metadata,omitempty"`
|
||||||
|
Items []ClusterGenerator `json:"items"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ! UUID Generator
|
||||||
|
|
||||||
|
// UUIDSpec controls the behavior of the uuid generator.
|
||||||
|
type UUIDSpec struct{}
|
||||||
|
|
||||||
|
// UUID generates a version 4 UUID (e56657e3-764f-11ef-a397-65231a88c216).
|
||||||
|
// +kubebuilder:object:root=true
|
||||||
|
// +kubebuilder:subresource:status
|
||||||
|
type UUID struct {
|
||||||
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||||
|
|
||||||
|
Spec UUIDSpec `json:"spec,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// +kubebuilder:object:root=true
|
||||||
|
|
||||||
|
// UUIDList contains a list of UUID resources.
|
||||||
|
type UUIDList struct {
|
||||||
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
metav1.ListMeta `json:"metadata,omitempty"`
|
||||||
|
Items []UUID `json:"items"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ! Password Generator
|
||||||
|
|
||||||
|
// PasswordSpec controls the behavior of the password generator.
|
||||||
|
type PasswordSpec struct {
|
||||||
|
// Length of the password to be generated.
|
||||||
|
// Defaults to 24
|
||||||
|
// +kubebuilder:validation:Optional
|
||||||
|
// +kubebuilder:default=24
|
||||||
|
Length int `json:"length"`
|
||||||
|
|
||||||
|
// digits specifies the number of digits in the generated
|
||||||
|
// password. If omitted it defaults to 25% of the length of the password
|
||||||
|
Digits *int `json:"digits,omitempty"`
|
||||||
|
|
||||||
|
// symbols specifies the number of symbol characters in the generated
|
||||||
|
// password. If omitted it defaults to 25% of the length of the password
|
||||||
|
Symbols *int `json:"symbols,omitempty"`
|
||||||
|
|
||||||
|
// symbolCharacters specifies the special characters that should be used
|
||||||
|
// in the generated password.
|
||||||
|
SymbolCharacters *string `json:"symbolCharacters,omitempty"`
|
||||||
|
|
||||||
|
// Set noUpper to disable uppercase characters
|
||||||
|
// +kubebuilder:validation:Optional
|
||||||
|
// +kubebuilder:default=false
|
||||||
|
NoUpper bool `json:"noUpper"`
|
||||||
|
|
||||||
|
// set allowRepeat to true to allow repeating characters.
|
||||||
|
// +kubebuilder:validation:Optional
|
||||||
|
// +kubebuilder:default=false
|
||||||
|
AllowRepeat bool `json:"allowRepeat"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Password generates a random password based on the
|
||||||
|
// configuration parameters in spec.
|
||||||
|
// You can specify the length, characterset and other attributes.
|
||||||
|
// +kubebuilder:object:root=true
|
||||||
|
// +kubebuilder:storageversion
|
||||||
|
// +kubebuilder:subresource:status
|
||||||
|
// +kubebuilder:resource:scope=Namespaced
|
||||||
|
type Password struct {
|
||||||
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||||
|
|
||||||
|
Spec PasswordSpec `json:"spec,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// +kubebuilder:object:root=true
|
||||||
|
|
||||||
|
// PasswordList contains a list of Password resources.
|
||||||
|
type PasswordList struct {
|
||||||
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
metav1.ListMeta `json:"metadata,omitempty"`
|
||||||
|
Items []Password `json:"items"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
SchemeBuilder.Register(&Password{}, &PasswordList{})
|
||||||
|
SchemeBuilder.Register(&UUID{}, &UUIDList{})
|
||||||
|
SchemeBuilder.Register(&ClusterGenerator{}, &ClusterGeneratorList{})
|
||||||
|
}
|
||||||
@@ -29,9 +29,28 @@ type InfisicalPushSecretSecretSource struct {
|
|||||||
Template *SecretTemplate `json:"template,omitempty"`
|
Template *SecretTemplate `json:"template,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type SecretPush struct {
|
type GeneratorRef struct {
|
||||||
|
// Specify the Kind of the generator resource
|
||||||
|
// +kubebuilder:validation:Enum=Password;UUID
|
||||||
// +kubebuilder:validation:Required
|
// +kubebuilder:validation:Required
|
||||||
Secret InfisicalPushSecretSecretSource `json:"secret"`
|
Kind GeneratorKind `json:"kind"`
|
||||||
|
|
||||||
|
// +kubebuilder:validation:Required
|
||||||
|
Name string `json:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SecretPushGenerator struct {
|
||||||
|
// +kubebuilder:validation:Required
|
||||||
|
DestinationSecretName string `json:"destinationSecretName"`
|
||||||
|
// +kubebuilder:validation:Required
|
||||||
|
GeneratorRef GeneratorRef `json:"generatorRef"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SecretPush struct {
|
||||||
|
// +kubebuilder:validation:Optional
|
||||||
|
Secret *InfisicalPushSecretSecretSource `json:"secret,omitempty"`
|
||||||
|
// +kubebuilder:validation:Optional
|
||||||
|
Generators []SecretPushGenerator `json:"generators,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// InfisicalPushSecretSpec defines the desired state of InfisicalPushSecret
|
// InfisicalPushSecretSpec defines the desired state of InfisicalPushSecret
|
||||||
@@ -52,7 +71,8 @@ type InfisicalPushSecretSpec struct {
|
|||||||
// +kubebuilder:validation:Required
|
// +kubebuilder:validation:Required
|
||||||
Push SecretPush `json:"push"`
|
Push SecretPush `json:"push"`
|
||||||
|
|
||||||
ResyncInterval string `json:"resyncInterval"`
|
// +kubebuilder:validation:Optional
|
||||||
|
ResyncInterval *string `json:"resyncInterval,omitempty"`
|
||||||
|
|
||||||
// Infisical host to pull secrets from
|
// Infisical host to pull secrets from
|
||||||
// +kubebuilder:validation:Optional
|
// +kubebuilder:validation:Optional
|
||||||
|
|||||||
@@ -96,6 +96,80 @@ func (in *CaReference) DeepCopy() *CaReference {
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *ClusterGenerator) DeepCopyInto(out *ClusterGenerator) {
|
||||||
|
*out = *in
|
||||||
|
out.TypeMeta = in.TypeMeta
|
||||||
|
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||||
|
in.Spec.DeepCopyInto(&out.Spec)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterGenerator.
|
||||||
|
func (in *ClusterGenerator) DeepCopy() *ClusterGenerator {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(ClusterGenerator)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||||
|
func (in *ClusterGenerator) DeepCopyObject() runtime.Object {
|
||||||
|
if c := in.DeepCopy(); c != nil {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *ClusterGeneratorList) DeepCopyInto(out *ClusterGeneratorList) {
|
||||||
|
*out = *in
|
||||||
|
out.TypeMeta = in.TypeMeta
|
||||||
|
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||||
|
if in.Items != nil {
|
||||||
|
in, out := &in.Items, &out.Items
|
||||||
|
*out = make([]ClusterGenerator, len(*in))
|
||||||
|
for i := range *in {
|
||||||
|
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterGeneratorList.
|
||||||
|
func (in *ClusterGeneratorList) DeepCopy() *ClusterGeneratorList {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(ClusterGeneratorList)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||||
|
func (in *ClusterGeneratorList) DeepCopyObject() runtime.Object {
|
||||||
|
if c := in.DeepCopy(); c != nil {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *ClusterGeneratorSpec) DeepCopyInto(out *ClusterGeneratorSpec) {
|
||||||
|
*out = *in
|
||||||
|
in.Generator.DeepCopyInto(&out.Generator)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterGeneratorSpec.
|
||||||
|
func (in *ClusterGeneratorSpec) DeepCopy() *ClusterGeneratorSpec {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(ClusterGeneratorSpec)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
// 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 *DynamicSecretDetails) DeepCopyInto(out *DynamicSecretDetails) {
|
func (in *DynamicSecretDetails) DeepCopyInto(out *DynamicSecretDetails) {
|
||||||
*out = *in
|
*out = *in
|
||||||
@@ -143,6 +217,46 @@ func (in *GcpIamAuthDetails) DeepCopy() *GcpIamAuthDetails {
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *GeneratorRef) DeepCopyInto(out *GeneratorRef) {
|
||||||
|
*out = *in
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GeneratorRef.
|
||||||
|
func (in *GeneratorRef) DeepCopy() *GeneratorRef {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(GeneratorRef)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *GeneratorSpec) DeepCopyInto(out *GeneratorSpec) {
|
||||||
|
*out = *in
|
||||||
|
if in.PasswordSpec != nil {
|
||||||
|
in, out := &in.PasswordSpec, &out.PasswordSpec
|
||||||
|
*out = new(PasswordSpec)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
|
if in.UUIDSpec != nil {
|
||||||
|
in, out := &in.UUIDSpec, &out.UUIDSpec
|
||||||
|
*out = new(UUIDSpec)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GeneratorSpec.
|
||||||
|
func (in *GeneratorSpec) DeepCopy() *GeneratorSpec {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(GeneratorSpec)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
// 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 *GenericAwsIamAuth) DeepCopyInto(out *GenericAwsIamAuth) {
|
func (in *GenericAwsIamAuth) DeepCopyInto(out *GenericAwsIamAuth) {
|
||||||
*out = *in
|
*out = *in
|
||||||
@@ -483,6 +597,11 @@ func (in *InfisicalPushSecretSpec) DeepCopyInto(out *InfisicalPushSecretSpec) {
|
|||||||
out.Destination = in.Destination
|
out.Destination = in.Destination
|
||||||
in.Authentication.DeepCopyInto(&out.Authentication)
|
in.Authentication.DeepCopyInto(&out.Authentication)
|
||||||
in.Push.DeepCopyInto(&out.Push)
|
in.Push.DeepCopyInto(&out.Push)
|
||||||
|
if in.ResyncInterval != nil {
|
||||||
|
in, out := &in.ResyncInterval, &out.ResyncInterval
|
||||||
|
*out = new(string)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
out.TLS = in.TLS
|
out.TLS = in.TLS
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -746,10 +865,107 @@ func (in *ManagedKubeSecretConfig) DeepCopy() *ManagedKubeSecretConfig {
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *Password) DeepCopyInto(out *Password) {
|
||||||
|
*out = *in
|
||||||
|
out.TypeMeta = in.TypeMeta
|
||||||
|
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||||
|
in.Spec.DeepCopyInto(&out.Spec)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Password.
|
||||||
|
func (in *Password) DeepCopy() *Password {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(Password)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||||
|
func (in *Password) DeepCopyObject() runtime.Object {
|
||||||
|
if c := in.DeepCopy(); c != nil {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *PasswordList) DeepCopyInto(out *PasswordList) {
|
||||||
|
*out = *in
|
||||||
|
out.TypeMeta = in.TypeMeta
|
||||||
|
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||||
|
if in.Items != nil {
|
||||||
|
in, out := &in.Items, &out.Items
|
||||||
|
*out = make([]Password, len(*in))
|
||||||
|
for i := range *in {
|
||||||
|
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PasswordList.
|
||||||
|
func (in *PasswordList) DeepCopy() *PasswordList {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(PasswordList)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||||
|
func (in *PasswordList) DeepCopyObject() runtime.Object {
|
||||||
|
if c := in.DeepCopy(); c != nil {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *PasswordSpec) DeepCopyInto(out *PasswordSpec) {
|
||||||
|
*out = *in
|
||||||
|
if in.Digits != nil {
|
||||||
|
in, out := &in.Digits, &out.Digits
|
||||||
|
*out = new(int)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
if in.Symbols != nil {
|
||||||
|
in, out := &in.Symbols, &out.Symbols
|
||||||
|
*out = new(int)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
if in.SymbolCharacters != nil {
|
||||||
|
in, out := &in.SymbolCharacters, &out.SymbolCharacters
|
||||||
|
*out = new(string)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PasswordSpec.
|
||||||
|
func (in *PasswordSpec) DeepCopy() *PasswordSpec {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(PasswordSpec)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
// 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 *SecretPush) DeepCopyInto(out *SecretPush) {
|
func (in *SecretPush) DeepCopyInto(out *SecretPush) {
|
||||||
*out = *in
|
*out = *in
|
||||||
in.Secret.DeepCopyInto(&out.Secret)
|
if in.Secret != nil {
|
||||||
|
in, out := &in.Secret, &out.Secret
|
||||||
|
*out = new(InfisicalPushSecretSecretSource)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
|
if in.Generators != nil {
|
||||||
|
in, out := &in.Generators, &out.Generators
|
||||||
|
*out = make([]SecretPushGenerator, len(*in))
|
||||||
|
copy(*out, *in)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretPush.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretPush.
|
||||||
@@ -762,6 +978,22 @@ func (in *SecretPush) DeepCopy() *SecretPush {
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *SecretPushGenerator) DeepCopyInto(out *SecretPushGenerator) {
|
||||||
|
*out = *in
|
||||||
|
out.GeneratorRef = in.GeneratorRef
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretPushGenerator.
|
||||||
|
func (in *SecretPushGenerator) DeepCopy() *SecretPushGenerator {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(SecretPushGenerator)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
// 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 *SecretScopeInWorkspace) DeepCopyInto(out *SecretScopeInWorkspace) {
|
func (in *SecretScopeInWorkspace) DeepCopyInto(out *SecretScopeInWorkspace) {
|
||||||
*out = *in
|
*out = *in
|
||||||
@@ -848,6 +1080,79 @@ func (in *TLSConfig) DeepCopy() *TLSConfig {
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *UUID) DeepCopyInto(out *UUID) {
|
||||||
|
*out = *in
|
||||||
|
out.TypeMeta = in.TypeMeta
|
||||||
|
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||||
|
out.Spec = in.Spec
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UUID.
|
||||||
|
func (in *UUID) DeepCopy() *UUID {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(UUID)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||||
|
func (in *UUID) DeepCopyObject() runtime.Object {
|
||||||
|
if c := in.DeepCopy(); c != nil {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *UUIDList) DeepCopyInto(out *UUIDList) {
|
||||||
|
*out = *in
|
||||||
|
out.TypeMeta = in.TypeMeta
|
||||||
|
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||||
|
if in.Items != nil {
|
||||||
|
in, out := &in.Items, &out.Items
|
||||||
|
*out = make([]UUID, len(*in))
|
||||||
|
for i := range *in {
|
||||||
|
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UUIDList.
|
||||||
|
func (in *UUIDList) DeepCopy() *UUIDList {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(UUIDList)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||||
|
func (in *UUIDList) DeepCopyObject() runtime.Object {
|
||||||
|
if c := in.DeepCopy(); c != nil {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *UUIDSpec) DeepCopyInto(out *UUIDSpec) {
|
||||||
|
*out = *in
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UUIDSpec.
|
||||||
|
func (in *UUIDSpec) DeepCopy() *UUIDSpec {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(UUIDSpec)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
// 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 *UniversalAuthDetails) DeepCopyInto(out *UniversalAuthDetails) {
|
func (in *UniversalAuthDetails) DeepCopyInto(out *UniversalAuthDetails) {
|
||||||
*out = *in
|
*out = *in
|
||||||
|
|||||||
@@ -0,0 +1,90 @@
|
|||||||
|
---
|
||||||
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
|
kind: CustomResourceDefinition
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
controller-gen.kubebuilder.io/version: v0.10.0
|
||||||
|
creationTimestamp: null
|
||||||
|
name: clustergenerators.secrets.infisical.com
|
||||||
|
spec:
|
||||||
|
group: secrets.infisical.com
|
||||||
|
names:
|
||||||
|
kind: ClusterGenerator
|
||||||
|
listKind: ClusterGeneratorList
|
||||||
|
plural: clustergenerators
|
||||||
|
singular: clustergenerator
|
||||||
|
scope: Cluster
|
||||||
|
versions:
|
||||||
|
- name: v1alpha1
|
||||||
|
schema:
|
||||||
|
openAPIV3Schema:
|
||||||
|
description: ClusterGenerator represents a cluster-wide generator
|
||||||
|
properties:
|
||||||
|
apiVersion:
|
||||||
|
description: 'APIVersion defines the versioned schema of this representation
|
||||||
|
of an object. Servers should convert recognized schemas to the latest
|
||||||
|
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||||
|
type: string
|
||||||
|
kind:
|
||||||
|
description: 'Kind is a string value representing the REST resource this
|
||||||
|
object represents. Servers may infer this from the endpoint the client
|
||||||
|
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||||
|
type: string
|
||||||
|
metadata:
|
||||||
|
type: object
|
||||||
|
spec:
|
||||||
|
properties:
|
||||||
|
generator:
|
||||||
|
description: Generator the spec for this generator, must match the
|
||||||
|
kind.
|
||||||
|
properties:
|
||||||
|
passwordSpec:
|
||||||
|
description: PasswordSpec controls the behavior of the password
|
||||||
|
generator.
|
||||||
|
properties:
|
||||||
|
allowRepeat:
|
||||||
|
default: false
|
||||||
|
description: set allowRepeat to true to allow repeating characters.
|
||||||
|
type: boolean
|
||||||
|
digits:
|
||||||
|
description: digits specifies the number of digits in the
|
||||||
|
generated password. If omitted it defaults to 25% of the
|
||||||
|
length of the password
|
||||||
|
type: integer
|
||||||
|
length:
|
||||||
|
default: 24
|
||||||
|
description: Length of the password to be generated. Defaults
|
||||||
|
to 24
|
||||||
|
type: integer
|
||||||
|
noUpper:
|
||||||
|
default: false
|
||||||
|
description: Set noUpper to disable uppercase characters
|
||||||
|
type: boolean
|
||||||
|
symbolCharacters:
|
||||||
|
description: symbolCharacters specifies the special characters
|
||||||
|
that should be used in the generated password.
|
||||||
|
type: string
|
||||||
|
symbols:
|
||||||
|
description: symbols specifies the number of symbol characters
|
||||||
|
in the generated password. If omitted it defaults to 25%
|
||||||
|
of the length of the password
|
||||||
|
type: integer
|
||||||
|
type: object
|
||||||
|
uuidSpec:
|
||||||
|
description: UUIDSpec controls the behavior of the uuid generator.
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
kind:
|
||||||
|
description: Kind the kind of this generator.
|
||||||
|
enum:
|
||||||
|
- Password
|
||||||
|
- UUID
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- kind
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
served: true
|
||||||
|
storage: true
|
||||||
|
subresources:
|
||||||
|
status: {}
|
||||||
@@ -142,6 +142,34 @@ spec:
|
|||||||
type: string
|
type: string
|
||||||
push:
|
push:
|
||||||
properties:
|
properties:
|
||||||
|
generators:
|
||||||
|
items:
|
||||||
|
properties:
|
||||||
|
destinationSecretName:
|
||||||
|
type: string
|
||||||
|
generatorRef:
|
||||||
|
properties:
|
||||||
|
kind:
|
||||||
|
allOf:
|
||||||
|
- enum:
|
||||||
|
- Password
|
||||||
|
- UUID
|
||||||
|
- enum:
|
||||||
|
- Password
|
||||||
|
- UUID
|
||||||
|
description: Specify the Kind of the generator resource
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- kind
|
||||||
|
- name
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- destinationSecretName
|
||||||
|
- generatorRef
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
secret:
|
secret:
|
||||||
properties:
|
properties:
|
||||||
secretName:
|
secretName:
|
||||||
@@ -168,8 +196,6 @@ spec:
|
|||||||
- secretName
|
- secretName
|
||||||
- secretNamespace
|
- secretNamespace
|
||||||
type: object
|
type: object
|
||||||
required:
|
|
||||||
- secret
|
|
||||||
type: object
|
type: object
|
||||||
resyncInterval:
|
resyncInterval:
|
||||||
type: string
|
type: string
|
||||||
@@ -200,7 +226,6 @@ spec:
|
|||||||
required:
|
required:
|
||||||
- destination
|
- destination
|
||||||
- push
|
- push
|
||||||
- resyncInterval
|
|
||||||
type: object
|
type: object
|
||||||
status:
|
status:
|
||||||
description: InfisicalPushSecretStatus defines the observed state of InfisicalPushSecret
|
description: InfisicalPushSecretStatus defines the observed state of InfisicalPushSecret
|
||||||
|
|||||||
@@ -0,0 +1,69 @@
|
|||||||
|
---
|
||||||
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
|
kind: CustomResourceDefinition
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
controller-gen.kubebuilder.io/version: v0.10.0
|
||||||
|
creationTimestamp: null
|
||||||
|
name: passwords.secrets.infisical.com
|
||||||
|
spec:
|
||||||
|
group: secrets.infisical.com
|
||||||
|
names:
|
||||||
|
kind: Password
|
||||||
|
listKind: PasswordList
|
||||||
|
plural: passwords
|
||||||
|
singular: password
|
||||||
|
scope: Namespaced
|
||||||
|
versions:
|
||||||
|
- name: v1alpha1
|
||||||
|
schema:
|
||||||
|
openAPIV3Schema:
|
||||||
|
description: Password generates a random password based on the configuration
|
||||||
|
parameters in spec. You can specify the length, characterset and other attributes.
|
||||||
|
properties:
|
||||||
|
apiVersion:
|
||||||
|
description: 'APIVersion defines the versioned schema of this representation
|
||||||
|
of an object. Servers should convert recognized schemas to the latest
|
||||||
|
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||||
|
type: string
|
||||||
|
kind:
|
||||||
|
description: 'Kind is a string value representing the REST resource this
|
||||||
|
object represents. Servers may infer this from the endpoint the client
|
||||||
|
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||||
|
type: string
|
||||||
|
metadata:
|
||||||
|
type: object
|
||||||
|
spec:
|
||||||
|
description: PasswordSpec controls the behavior of the password generator.
|
||||||
|
properties:
|
||||||
|
allowRepeat:
|
||||||
|
default: false
|
||||||
|
description: set allowRepeat to true to allow repeating characters.
|
||||||
|
type: boolean
|
||||||
|
digits:
|
||||||
|
description: digits specifies the number of digits in the generated
|
||||||
|
password. If omitted it defaults to 25% of the length of the password
|
||||||
|
type: integer
|
||||||
|
length:
|
||||||
|
default: 24
|
||||||
|
description: Length of the password to be generated. Defaults to 24
|
||||||
|
type: integer
|
||||||
|
noUpper:
|
||||||
|
default: false
|
||||||
|
description: Set noUpper to disable uppercase characters
|
||||||
|
type: boolean
|
||||||
|
symbolCharacters:
|
||||||
|
description: symbolCharacters specifies the special characters that
|
||||||
|
should be used in the generated password.
|
||||||
|
type: string
|
||||||
|
symbols:
|
||||||
|
description: symbols specifies the number of symbol characters in
|
||||||
|
the generated password. If omitted it defaults to 25% of the length
|
||||||
|
of the password
|
||||||
|
type: integer
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
served: true
|
||||||
|
storage: true
|
||||||
|
subresources:
|
||||||
|
status: {}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
---
|
||||||
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
|
kind: CustomResourceDefinition
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
controller-gen.kubebuilder.io/version: v0.10.0
|
||||||
|
creationTimestamp: null
|
||||||
|
name: uuids.secrets.infisical.com
|
||||||
|
spec:
|
||||||
|
group: secrets.infisical.com
|
||||||
|
names:
|
||||||
|
kind: UUID
|
||||||
|
listKind: UUIDList
|
||||||
|
plural: uuids
|
||||||
|
singular: uuid
|
||||||
|
scope: Namespaced
|
||||||
|
versions:
|
||||||
|
- name: v1alpha1
|
||||||
|
schema:
|
||||||
|
openAPIV3Schema:
|
||||||
|
description: UUID generates a version 4 UUID (e56657e3-764f-11ef-a397-65231a88c216).
|
||||||
|
properties:
|
||||||
|
apiVersion:
|
||||||
|
description: 'APIVersion defines the versioned schema of this representation
|
||||||
|
of an object. Servers should convert recognized schemas to the latest
|
||||||
|
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||||
|
type: string
|
||||||
|
kind:
|
||||||
|
description: 'Kind is a string value representing the REST resource this
|
||||||
|
object represents. Servers may infer this from the endpoint the client
|
||||||
|
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||||
|
type: string
|
||||||
|
metadata:
|
||||||
|
type: object
|
||||||
|
spec:
|
||||||
|
description: UUIDSpec controls the behavior of the uuid generator.
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
served: true
|
||||||
|
storage: true
|
||||||
|
subresources:
|
||||||
|
status: {}
|
||||||
@@ -5,6 +5,7 @@ resources:
|
|||||||
- bases/secrets.infisical.com_infisicalsecrets.yaml
|
- bases/secrets.infisical.com_infisicalsecrets.yaml
|
||||||
- bases/secrets.infisical.com_infisicalpushsecrets.yaml
|
- bases/secrets.infisical.com_infisicalpushsecrets.yaml
|
||||||
- bases/secrets.infisical.com_infisicaldynamicsecrets.yaml
|
- bases/secrets.infisical.com_infisicaldynamicsecrets.yaml
|
||||||
|
- bases/secrets.infisical.com_clustergenerators.yaml
|
||||||
#+kubebuilder:scaffold:crdkustomizeresource
|
#+kubebuilder:scaffold:crdkustomizeresource
|
||||||
|
|
||||||
patchesStrategicMerge:
|
patchesStrategicMerge:
|
||||||
|
|||||||
@@ -74,6 +74,18 @@ rules:
|
|||||||
- tokenreviews
|
- tokenreviews
|
||||||
verbs:
|
verbs:
|
||||||
- create
|
- create
|
||||||
|
- apiGroups:
|
||||||
|
- secrets.infisical.com
|
||||||
|
resources:
|
||||||
|
- clustergenerators
|
||||||
|
verbs:
|
||||||
|
- create
|
||||||
|
- delete
|
||||||
|
- get
|
||||||
|
- list
|
||||||
|
- patch
|
||||||
|
- update
|
||||||
|
- watch
|
||||||
- apiGroups:
|
- apiGroups:
|
||||||
- secrets.infisical.com
|
- secrets.infisical.com
|
||||||
resources:
|
resources:
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
apiVersion: secrets.infisical.com/v1alpha1
|
||||||
|
kind: ClusterGenerator
|
||||||
|
metadata:
|
||||||
|
name: password-generator
|
||||||
|
spec:
|
||||||
|
kind: Password
|
||||||
|
generator:
|
||||||
|
passwordSpec:
|
||||||
|
length: 10
|
||||||
|
digits: 5
|
||||||
|
symbols: 5
|
||||||
|
symbolCharacters: "-_$@"
|
||||||
|
noUpper: false
|
||||||
|
allowRepeat: true
|
||||||
@@ -393,7 +393,7 @@ func (r *InfisicalDynamicSecretReconciler) ReconcileInfisicalDynamicSecret(ctx c
|
|||||||
|
|
||||||
// Max TTL
|
// Max TTL
|
||||||
if infisicalDynamicSecret.Status.MaxTTL != "" {
|
if infisicalDynamicSecret.Status.MaxTTL != "" {
|
||||||
maxTTLDuration, err := util.ConvertIntervalToDuration(infisicalDynamicSecret.Status.MaxTTL)
|
maxTTLDuration, err := util.ConvertIntervalToDuration(&infisicalDynamicSecret.Status.MaxTTL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return defaultNextReconcile, fmt.Errorf("unable to parse MaxTTL duration: %w", err)
|
return defaultNextReconcile, fmt.Errorf("unable to parse MaxTTL duration: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ func (r *InfisicalPushSecretReconciler) GetLogger(req ctrl.Request) logr.Logger
|
|||||||
//+kubebuilder:rbac:groups="",resources=pods,verbs=get;list
|
//+kubebuilder:rbac:groups="",resources=pods,verbs=get;list
|
||||||
//+kubebuilder:rbac:groups="authentication.k8s.io",resources=tokenreviews,verbs=create
|
//+kubebuilder:rbac:groups="authentication.k8s.io",resources=tokenreviews,verbs=create
|
||||||
//+kubebuilder:rbac:groups="",resources=serviceaccounts/token,verbs=create
|
//+kubebuilder:rbac:groups="",resources=serviceaccounts/token,verbs=create
|
||||||
|
// +kubebuilder:rbac:groups=secrets.infisical.com,resources=clustergenerators,verbs=get;list;watch;create;update;patch;delete
|
||||||
// Reconcile is part of the main kubernetes reconciliation loop which aims to
|
// Reconcile is part of the main kubernetes reconciliation loop which aims to
|
||||||
// move the current state of the cluster closer to the desired state.
|
// move the current state of the cluster closer to the desired state.
|
||||||
// For more details, check Reconcile and its Result here:
|
// For more details, check Reconcile and its Result here:
|
||||||
@@ -108,23 +108,30 @@ func (r *InfisicalPushSecretReconciler) Reconcile(ctx context.Context, req ctrl.
|
|||||||
return ctrl.Result{}, nil
|
return ctrl.Result{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if infisicalPushSecretCRD.Spec.ResyncInterval != "" {
|
if infisicalPushSecretCRD.Spec.Push.Secret == nil && infisicalPushSecretCRD.Spec.Push.Generators == nil {
|
||||||
|
logger.Info("No secret or generators found, skipping reconciliation. Please define ")
|
||||||
|
return ctrl.Result{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
duration, err := util.ConvertIntervalToDuration(infisicalPushSecretCRD.Spec.ResyncInterval)
|
duration, err := util.ConvertIntervalToDuration(infisicalPushSecretCRD.Spec.ResyncInterval)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
// if resyncInterval is nil, we don't want to reconcile automatically
|
||||||
|
if infisicalPushSecretCRD.Spec.ResyncInterval != nil {
|
||||||
logger.Error(err, fmt.Sprintf("unable to convert resync interval to duration. Will requeue after [requeueTime=%v]", requeueTime))
|
logger.Error(err, fmt.Sprintf("unable to convert resync interval to duration. Will requeue after [requeueTime=%v]", requeueTime))
|
||||||
return ctrl.Result{
|
return ctrl.Result{
|
||||||
RequeueAfter: requeueTime,
|
RequeueAfter: requeueTime,
|
||||||
}, nil
|
}, nil
|
||||||
|
} else {
|
||||||
|
logger.Error(err, "unable to convert resync interval to duration")
|
||||||
|
return ctrl.Result{}, err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
requeueTime = duration
|
requeueTime = duration
|
||||||
|
|
||||||
|
if requeueTime != 0 {
|
||||||
logger.Info(fmt.Sprintf("Manual re-sync interval set. Interval: %v", requeueTime))
|
logger.Info(fmt.Sprintf("Manual re-sync interval set. Interval: %v", requeueTime))
|
||||||
|
|
||||||
} else {
|
|
||||||
logger.Info(fmt.Sprintf("Re-sync interval set. Interval: %v", requeueTime))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the resource is already marked for deletion
|
// Check if the resource is already marked for deletion
|
||||||
@@ -137,10 +144,15 @@ func (r *InfisicalPushSecretReconciler) Reconcile(ctx context.Context, req ctrl.
|
|||||||
// Get modified/default config
|
// Get modified/default config
|
||||||
infisicalConfig, err := controllerhelpers.GetInfisicalConfigMap(ctx, r.Client)
|
infisicalConfig, err := controllerhelpers.GetInfisicalConfigMap(ctx, r.Client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error(err, fmt.Sprintf("unable to fetch infisical-config. Will requeue after [requeueTime=%v]", requeueTime))
|
if requeueTime != 0 {
|
||||||
return ctrl.Result{
|
logger.Error(err, fmt.Sprintf("unable to fetch infisical-config. Will requeue after [requeueTime=%v]", requeueTime))
|
||||||
RequeueAfter: requeueTime,
|
return ctrl.Result{
|
||||||
}, nil
|
RequeueAfter: requeueTime,
|
||||||
|
}, nil
|
||||||
|
} else {
|
||||||
|
logger.Error(err, "unable to fetch infisical-config")
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if infisicalPushSecretCRD.Spec.HostAPI == "" {
|
if infisicalPushSecretCRD.Spec.HostAPI == "" {
|
||||||
@@ -152,10 +164,15 @@ func (r *InfisicalPushSecretReconciler) Reconcile(ctx context.Context, req ctrl.
|
|||||||
if infisicalPushSecretCRD.Spec.TLS.CaRef.SecretName != "" {
|
if infisicalPushSecretCRD.Spec.TLS.CaRef.SecretName != "" {
|
||||||
api.API_CA_CERTIFICATE, err = r.getInfisicalCaCertificateFromKubeSecret(ctx, infisicalPushSecretCRD)
|
api.API_CA_CERTIFICATE, err = r.getInfisicalCaCertificateFromKubeSecret(ctx, infisicalPushSecretCRD)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error(err, fmt.Sprintf("unable to fetch CA certificate. Will requeue after [requeueTime=%v]", requeueTime))
|
if requeueTime != 0 {
|
||||||
return ctrl.Result{
|
logger.Error(err, fmt.Sprintf("unable to fetch CA certificate. Will requeue after [requeueTime=%v]", requeueTime))
|
||||||
RequeueAfter: requeueTime,
|
return ctrl.Result{
|
||||||
}, nil
|
RequeueAfter: requeueTime,
|
||||||
|
}, nil
|
||||||
|
} else {
|
||||||
|
logger.Error(err, "unable to fetch CA certificate")
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Info("Using custom CA certificate...")
|
logger.Info("Using custom CA certificate...")
|
||||||
@@ -167,17 +184,27 @@ func (r *InfisicalPushSecretReconciler) Reconcile(ctx context.Context, req ctrl.
|
|||||||
r.SetReconcileStatusCondition(ctx, &infisicalPushSecretCRD, err)
|
r.SetReconcileStatusCondition(ctx, &infisicalPushSecretCRD, err)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error(err, fmt.Sprintf("unable to reconcile Infisical Push Secret. Will requeue after [requeueTime=%v]", requeueTime))
|
if requeueTime != 0 {
|
||||||
return ctrl.Result{
|
logger.Error(err, fmt.Sprintf("unable to reconcile Infisical Push Secret. Will requeue after [requeueTime=%v]", requeueTime))
|
||||||
RequeueAfter: requeueTime,
|
return ctrl.Result{
|
||||||
}, nil
|
RequeueAfter: requeueTime,
|
||||||
|
}, nil
|
||||||
|
} else {
|
||||||
|
logger.Error(err, "unable to reconcile Infisical Push Secret")
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sync again after the specified time
|
// Sync again after the specified time
|
||||||
logger.Info(fmt.Sprintf("Operator will requeue after [%v]", requeueTime))
|
if requeueTime != 0 {
|
||||||
return ctrl.Result{
|
logger.Info(fmt.Sprintf("Operator will requeue after [%v]", requeueTime))
|
||||||
RequeueAfter: requeueTime,
|
return ctrl.Result{
|
||||||
}, nil
|
RequeueAfter: requeueTime,
|
||||||
|
}, nil
|
||||||
|
} else {
|
||||||
|
logger.Info("Operator will reconcile on next spec change")
|
||||||
|
return ctrl.Result{}, nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *InfisicalPushSecretReconciler) SetupWithManager(mgr ctrl.Manager) error {
|
func (r *InfisicalPushSecretReconciler) SetupWithManager(mgr ctrl.Manager) error {
|
||||||
@@ -228,27 +255,67 @@ func (r *InfisicalPushSecretReconciler) SetupWithManager(mgr ctrl.Manager) error
|
|||||||
)).
|
)).
|
||||||
Watches(
|
Watches(
|
||||||
&source.Kind{Type: &corev1.Secret{}},
|
&source.Kind{Type: &corev1.Secret{}},
|
||||||
handler.EnqueueRequestsFromMapFunc(func(o client.Object) []reconcile.Request {
|
handler.EnqueueRequestsFromMapFunc(r.findPushSecretsForSecret),
|
||||||
ctx := context.Background()
|
).
|
||||||
pushSecrets := &secretsv1alpha1.InfisicalPushSecretList{}
|
Watches(
|
||||||
if err := r.List(ctx, pushSecrets); err != nil {
|
&source.Kind{Type: &secretsv1alpha1.ClusterGenerator{}},
|
||||||
return []reconcile.Request{}
|
handler.EnqueueRequestsFromMapFunc(r.findPushSecretsForClusterGenerator),
|
||||||
}
|
|
||||||
|
|
||||||
requests := []reconcile.Request{}
|
|
||||||
for _, pushSecret := range pushSecrets.Items {
|
|
||||||
if pushSecret.Spec.Push.Secret.SecretName == o.GetName() &&
|
|
||||||
pushSecret.Spec.Push.Secret.SecretNamespace == o.GetNamespace() {
|
|
||||||
requests = append(requests, reconcile.Request{
|
|
||||||
NamespacedName: types.NamespacedName{
|
|
||||||
Name: pushSecret.GetName(),
|
|
||||||
Namespace: pushSecret.GetNamespace(),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return requests
|
|
||||||
}),
|
|
||||||
).
|
).
|
||||||
Complete(r)
|
Complete(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *InfisicalPushSecretReconciler) findPushSecretsForClusterGenerator(o client.Object) []reconcile.Request {
|
||||||
|
ctx := context.Background()
|
||||||
|
pushSecrets := &secretsv1alpha1.InfisicalPushSecretList{}
|
||||||
|
if err := r.List(ctx, pushSecrets); err != nil {
|
||||||
|
return []reconcile.Request{}
|
||||||
|
}
|
||||||
|
|
||||||
|
clusterGenerator, ok := o.(*secretsv1alpha1.ClusterGenerator)
|
||||||
|
if !ok {
|
||||||
|
return []reconcile.Request{}
|
||||||
|
}
|
||||||
|
|
||||||
|
requests := []reconcile.Request{}
|
||||||
|
for _, pushSecret := range pushSecrets.Items {
|
||||||
|
if pushSecret.Spec.Push.Generators != nil {
|
||||||
|
for _, generator := range pushSecret.Spec.Push.Generators {
|
||||||
|
if generator.GeneratorRef.Name == clusterGenerator.GetName() {
|
||||||
|
requests = append(requests, reconcile.Request{
|
||||||
|
NamespacedName: types.NamespacedName{
|
||||||
|
Name: pushSecret.GetName(),
|
||||||
|
Namespace: pushSecret.GetNamespace(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return requests
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *InfisicalPushSecretReconciler) findPushSecretsForSecret(o client.Object) []reconcile.Request {
|
||||||
|
ctx := context.Background()
|
||||||
|
pushSecrets := &secretsv1alpha1.InfisicalPushSecretList{}
|
||||||
|
if err := r.List(ctx, pushSecrets); err != nil {
|
||||||
|
return []reconcile.Request{}
|
||||||
|
}
|
||||||
|
|
||||||
|
requests := []reconcile.Request{}
|
||||||
|
for _, pushSecret := range pushSecrets.Items {
|
||||||
|
if pushSecret.Spec.Push.Secret != nil &&
|
||||||
|
pushSecret.Spec.Push.Secret.SecretName == o.GetName() &&
|
||||||
|
pushSecret.Spec.Push.Secret.SecretNamespace == o.GetNamespace() {
|
||||||
|
requests = append(requests, reconcile.Request{
|
||||||
|
NamespacedName: types.NamespacedName{
|
||||||
|
Name: pushSecret.GetName(),
|
||||||
|
Namespace: pushSecret.GetNamespace(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return requests
|
||||||
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
|
|
||||||
|
generatorUtil "github.com/Infisical/infisical/k8-operator/packages/generator"
|
||||||
infisicalSdk "github.com/infisical/go-sdk"
|
infisicalSdk "github.com/infisical/go-sdk"
|
||||||
k8Errors "k8s.io/apimachinery/pkg/api/errors"
|
k8Errors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
)
|
)
|
||||||
@@ -106,6 +107,52 @@ func (r *InfisicalPushSecretReconciler) updateResourceVariables(infisicalPushSec
|
|||||||
infisicalPushSecretResourceVariablesMap[string(infisicalPushSecret.UID)] = resourceVariables
|
infisicalPushSecretResourceVariablesMap[string(infisicalPushSecret.UID)] = resourceVariables
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *InfisicalPushSecretReconciler) processGenerators(ctx context.Context, infisicalPushSecret v1alpha1.InfisicalPushSecret) (map[string]string, error) {
|
||||||
|
|
||||||
|
processedSecrets := make(map[string]string)
|
||||||
|
|
||||||
|
if len(infisicalPushSecret.Spec.Push.Generators) == 0 {
|
||||||
|
return processedSecrets, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, generator := range infisicalPushSecret.Spec.Push.Generators {
|
||||||
|
generatorRef := generator.GeneratorRef
|
||||||
|
|
||||||
|
clusterGenerator := &v1alpha1.ClusterGenerator{}
|
||||||
|
err := r.Client.Get(ctx, types.NamespacedName{Name: generatorRef.Name}, clusterGenerator)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("unable to get ClusterGenerator resource [err=%s]", err)
|
||||||
|
}
|
||||||
|
if generatorRef.Kind == v1alpha1.GeneratorKindPassword {
|
||||||
|
// get the custom ClusterGenerator resource from the cluster
|
||||||
|
|
||||||
|
if clusterGenerator.Spec.Generator.PasswordSpec == nil {
|
||||||
|
return nil, fmt.Errorf("password spec is not defined in the ClusterGenerator resource")
|
||||||
|
}
|
||||||
|
|
||||||
|
password, err := generatorUtil.GeneratorPassword(*clusterGenerator.Spec.Generator.PasswordSpec)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("unable to generate password [err=%s]", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
processedSecrets[generator.DestinationSecretName] = password
|
||||||
|
}
|
||||||
|
|
||||||
|
if generatorRef.Kind == v1alpha1.GeneratorKindUUID {
|
||||||
|
|
||||||
|
uuid, err := generatorUtil.GeneratorUUID()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("unable to generate UUID [err=%s]", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
processedSecrets[generator.DestinationSecretName] = uuid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return processedSecrets, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func (r *InfisicalPushSecretReconciler) processTemplatedSecrets(infisicalPushSecret v1alpha1.InfisicalPushSecret, kubePushSecret *corev1.Secret, destination v1alpha1.InfisicalPushSecretDestination) (map[string]string, error) {
|
func (r *InfisicalPushSecretReconciler) processTemplatedSecrets(infisicalPushSecret v1alpha1.InfisicalPushSecret, kubePushSecret *corev1.Secret, destination v1alpha1.InfisicalPushSecretDestination) (map[string]string, error) {
|
||||||
|
|
||||||
processedSecrets := make(map[string]string)
|
processedSecrets := make(map[string]string)
|
||||||
@@ -172,18 +219,31 @@ func (r *InfisicalPushSecretReconciler) ReconcileInfisicalPushSecret(ctx context
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
kubePushSecret, err := util.GetKubeSecretByNamespacedName(ctx, r.Client, types.NamespacedName{
|
processedSecrets := make(map[string]string)
|
||||||
Namespace: infisicalPushSecret.Spec.Push.Secret.SecretNamespace,
|
|
||||||
Name: infisicalPushSecret.Spec.Push.Secret.SecretName,
|
|
||||||
})
|
|
||||||
|
|
||||||
if err != nil {
|
if infisicalPushSecret.Spec.Push.Secret != nil {
|
||||||
return fmt.Errorf("unable to fetch kube secret [err=%s]", err)
|
kubePushSecret, err := util.GetKubeSecretByNamespacedName(ctx, r.Client, types.NamespacedName{
|
||||||
|
Namespace: infisicalPushSecret.Spec.Push.Secret.SecretNamespace,
|
||||||
|
Name: infisicalPushSecret.Spec.Push.Secret.SecretName,
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to fetch kube secret [err=%s]", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
processedSecrets, err = r.processTemplatedSecrets(infisicalPushSecret, kubePushSecret, infisicalPushSecret.Spec.Destination)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to process templated secrets [err=%s]", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
processedSecrets, err := r.processTemplatedSecrets(infisicalPushSecret, kubePushSecret, infisicalPushSecret.Spec.Destination)
|
generatorSecrets, err := r.processGenerators(ctx, infisicalPushSecret)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to process templated secrets [err=%s]", err)
|
return fmt.Errorf("unable to process generators [err=%s]", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for key, value := range generatorSecrets {
|
||||||
|
processedSecrets[key] = value
|
||||||
}
|
}
|
||||||
|
|
||||||
destination := infisicalPushSecret.Spec.Destination
|
destination := infisicalPushSecret.Spec.Destination
|
||||||
|
|||||||
@@ -4,10 +4,12 @@ go 1.21
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/Masterminds/sprig/v3 v3.3.0
|
github.com/Masterminds/sprig/v3 v3.3.0
|
||||||
|
github.com/aws/smithy-go v1.20.3
|
||||||
github.com/infisical/go-sdk v0.4.4
|
github.com/infisical/go-sdk v0.4.4
|
||||||
github.com/lestrrat-go/jwx/v2 v2.1.4
|
github.com/lestrrat-go/jwx/v2 v2.1.4
|
||||||
github.com/onsi/ginkgo/v2 v2.6.0
|
github.com/onsi/ginkgo/v2 v2.6.0
|
||||||
github.com/onsi/gomega v1.24.1
|
github.com/onsi/gomega v1.24.1
|
||||||
|
github.com/sethvargo/go-password v0.3.1
|
||||||
k8s.io/apimachinery v0.26.1
|
k8s.io/apimachinery v0.26.1
|
||||||
k8s.io/client-go v0.26.1
|
k8s.io/client-go v0.26.1
|
||||||
sigs.k8s.io/controller-runtime v0.14.4
|
sigs.k8s.io/controller-runtime v0.14.4
|
||||||
@@ -34,7 +36,6 @@ require (
|
|||||||
github.com/aws/aws-sdk-go-v2/service/sso v1.22.1 // indirect
|
github.com/aws/aws-sdk-go-v2/service/sso v1.22.1 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.2 // indirect
|
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.2 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/sts v1.30.1 // indirect
|
github.com/aws/aws-sdk-go-v2/service/sts v1.30.1 // indirect
|
||||||
github.com/aws/smithy-go v1.20.3 // indirect
|
|
||||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect
|
||||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||||
github.com/go-logr/stdr v1.2.2 // indirect
|
github.com/go-logr/stdr v1.2.2 // indirect
|
||||||
@@ -85,7 +86,7 @@ require (
|
|||||||
github.com/google/gnostic v0.5.7-v3refs // indirect
|
github.com/google/gnostic v0.5.7-v3refs // indirect
|
||||||
github.com/google/go-cmp v0.6.0 // indirect
|
github.com/google/go-cmp v0.6.0 // indirect
|
||||||
github.com/google/gofuzz v1.1.0 // indirect
|
github.com/google/gofuzz v1.1.0 // indirect
|
||||||
github.com/google/uuid v1.6.0 // indirect
|
github.com/google/uuid v1.6.0
|
||||||
github.com/imdario/mergo v0.3.12 // indirect
|
github.com/imdario/mergo v0.3.12 // indirect
|
||||||
github.com/josharian/intern v1.0.0 // indirect
|
github.com/josharian/intern v1.0.0 // indirect
|
||||||
github.com/json-iterator/go v1.1.12 // indirect
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
|
|||||||
@@ -338,6 +338,8 @@ github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZV
|
|||||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||||
github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys=
|
github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys=
|
||||||
github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs=
|
github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs=
|
||||||
|
github.com/sethvargo/go-password v0.3.1 h1:WqrLTjo7X6AcVYfC6R7GtSyuUQR9hGyAj/f1PYQZCJU=
|
||||||
|
github.com/sethvargo/go-password v0.3.1/go.mod h1:rXofC1zT54N7R8K/h1WDUdkf9BOx5OptoxrMBcrXzvs=
|
||||||
github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
|
github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
|
||||||
github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
|
github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
|
||||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||||
|
|||||||
1
k8-operator/packages/generator/generator.go
Normal file
1
k8-operator/packages/generator/generator.go
Normal file
@@ -0,0 +1 @@
|
|||||||
|
package generator
|
||||||
76
k8-operator/packages/generator/password.go
Normal file
76
k8-operator/packages/generator/password.go
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
package generator
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/Infisical/infisical/k8-operator/api/v1alpha1"
|
||||||
|
"github.com/sethvargo/go-password/password"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
defaultLength = 24
|
||||||
|
defaultSymbolChars = "~!@#$%^&*()_+`-={}|[]\\:\"<>?,./"
|
||||||
|
digitFactor = 0.25
|
||||||
|
symbolFactor = 0.25
|
||||||
|
)
|
||||||
|
|
||||||
|
func generateSafePassword(
|
||||||
|
passLen int,
|
||||||
|
symbols int,
|
||||||
|
symbolCharacters string,
|
||||||
|
digits int,
|
||||||
|
noUpper bool,
|
||||||
|
allowRepeat bool,
|
||||||
|
) (string, error) {
|
||||||
|
gen, err := password.NewGenerator(&password.GeneratorInput{
|
||||||
|
Symbols: symbolCharacters,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return gen.Generate(
|
||||||
|
passLen,
|
||||||
|
digits,
|
||||||
|
symbols,
|
||||||
|
noUpper,
|
||||||
|
allowRepeat,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GeneratorPassword(spec v1alpha1.PasswordSpec) (string, error) {
|
||||||
|
|
||||||
|
symbolCharacters := defaultSymbolChars
|
||||||
|
|
||||||
|
if spec.SymbolCharacters != nil && *spec.SymbolCharacters != "" {
|
||||||
|
symbolCharacters = *spec.SymbolCharacters
|
||||||
|
}
|
||||||
|
|
||||||
|
passwordLength := defaultLength
|
||||||
|
|
||||||
|
if spec.Length != 0 {
|
||||||
|
passwordLength = spec.Length
|
||||||
|
}
|
||||||
|
|
||||||
|
digits := int(float32(passwordLength) * digitFactor)
|
||||||
|
if spec.Digits != nil {
|
||||||
|
digits = *spec.Digits
|
||||||
|
}
|
||||||
|
|
||||||
|
symbols := int(float32(passwordLength) * symbolFactor)
|
||||||
|
if spec.Symbols != nil {
|
||||||
|
symbols = *spec.Symbols
|
||||||
|
}
|
||||||
|
|
||||||
|
pass, err := generateSafePassword(
|
||||||
|
passwordLength,
|
||||||
|
symbols,
|
||||||
|
symbolCharacters,
|
||||||
|
digits,
|
||||||
|
spec.NoUpper,
|
||||||
|
spec.AllowRepeat,
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return pass, nil
|
||||||
|
}
|
||||||
10
k8-operator/packages/generator/uuid.go
Normal file
10
k8-operator/packages/generator/uuid.go
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
package generator
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/google/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GeneratorUUID() (string, error) {
|
||||||
|
uuid := uuid.New().String()
|
||||||
|
return uuid, nil
|
||||||
|
}
|
||||||
@@ -7,14 +7,19 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ConvertIntervalToDuration(resyncInterval string) (time.Duration, error) {
|
func ConvertIntervalToDuration(resyncInterval *string) (time.Duration, error) {
|
||||||
length := len(resyncInterval)
|
|
||||||
|
if resyncInterval == nil || *resyncInterval == "" {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
length := len(*resyncInterval)
|
||||||
if length < 2 {
|
if length < 2 {
|
||||||
return 0, fmt.Errorf("invalid format")
|
return 0, fmt.Errorf("invalid format")
|
||||||
}
|
}
|
||||||
|
|
||||||
unit := resyncInterval[length-1:]
|
unit := (*resyncInterval)[length-1:]
|
||||||
numberPart := resyncInterval[:length-1]
|
numberPart := (*resyncInterval)[:length-1]
|
||||||
|
|
||||||
number, err := strconv.Atoi(numberPart)
|
number, err := strconv.Atoi(numberPart)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -40,16 +45,6 @@ func ConvertIntervalToDuration(resyncInterval string) (time.Duration, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
func AppendAPIEndpoint(address string) string {
|
||||||
if strings.HasSuffix(address, "/api") {
|
if strings.HasSuffix(address, "/api") {
|
||||||
return address
|
return address
|
||||||
|
|||||||
Reference in New Issue
Block a user