mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-08 06:27:40 +00:00
feat(k8s): generators
This commit is contained in:
@@ -0,0 +1,150 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
// +kubebuilder:validation:Optional
|
||||||
|
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 1 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: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:default=false
|
||||||
|
NoUpper bool `json:"noUpper"`
|
||||||
|
|
||||||
|
// set AllowRepeat to true to allow repeating characters.
|
||||||
|
// +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,94 @@
|
|||||||
|
---
|
||||||
|
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
|
||||||
|
required:
|
||||||
|
- allowRepeat
|
||||||
|
- length
|
||||||
|
- noUpper
|
||||||
|
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,73 @@
|
|||||||
|
---
|
||||||
|
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
|
||||||
|
required:
|
||||||
|
- allowRepeat
|
||||||
|
- length
|
||||||
|
- noUpper
|
||||||
|
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 1 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: {}
|
||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -108,23 +108,25 @@ func (r *InfisicalPushSecretReconciler) Reconcile(ctx context.Context, req ctrl.
|
|||||||
return ctrl.Result{}, nil
|
return ctrl.Result{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if infisicalPushSecretCRD.Spec.ResyncInterval != "" {
|
duration, err := util.ConvertIntervalToDuration(infisicalPushSecretCRD.Spec.ResyncInterval)
|
||||||
|
|
||||||
duration, err := util.ConvertIntervalToDuration(infisicalPushSecretCRD.Spec.ResyncInterval)
|
if err != nil {
|
||||||
|
// if resyncInterval is nil, we don't want to reconcile automatically
|
||||||
if err != nil {
|
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 +139,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 +159,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 +179,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 +250,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,50 @@ func (r *InfisicalPushSecretReconciler) updateResourceVariables(infisicalPushSec
|
|||||||
infisicalPushSecretResourceVariablesMap[string(infisicalPushSecret.UID)] = resourceVariables
|
infisicalPushSecretResourceVariablesMap[string(infisicalPushSecret.UID)] = resourceVariables
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *InfisicalPushSecretReconciler) processGenerators(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(context.TODO(), 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
|
||||||
|
|
||||||
|
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 {
|
||||||
|
|
||||||
|
fmt.Printf("clusterGenerator: %+v\n", clusterGenerator)
|
||||||
|
|
||||||
|
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 +217,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(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
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ require (
|
|||||||
github.com/mitchellh/copystructure v1.2.0 // indirect
|
github.com/mitchellh/copystructure v1.2.0 // indirect
|
||||||
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||||
github.com/segmentio/asm v1.2.0 // indirect
|
github.com/segmentio/asm v1.2.0 // indirect
|
||||||
|
github.com/sethvargo/go-password v0.3.1 // indirect
|
||||||
github.com/shopspring/decimal v1.4.0 // indirect
|
github.com/shopspring/decimal v1.4.0 // indirect
|
||||||
github.com/spf13/cast v1.7.0 // indirect
|
github.com/spf13/cast v1.7.0 // indirect
|
||||||
go.opencensus.io v0.24.0 // indirect
|
go.opencensus.io v0.24.0 // 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=
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
package generator
|
||||||
@@ -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 {
|
||||||
|
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
|
||||||
|
}
|
||||||
@@ -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 {
|
||||||
|
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