-
Notifications
You must be signed in to change notification settings - Fork 50
/
secret_mapping_types.go
176 lines (151 loc) · 5.05 KB
/
secret_mapping_types.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
package v1alpha1
import (
"os"
"github.com/jenkins-x/jx-api/v4/pkg/util"
"github.com/pkg/errors"
"gopkg.in/validator.v2"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/yaml"
)
const (
// SecretMappingFileName default name of the secret mappings file
SecretMappingFileName = "secret-mappings.yaml"
)
// +genclient
// +genclient:noStatus
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// SecretMapping represents a collection of mappings of Secrets to destinations in the underlying secret store (e.g. Vault keys)
//
// +k8s:openapi-gen=true
type SecretMapping struct {
metav1.TypeMeta `json:",inline"`
// +optional
metav1.ObjectMeta `json:"metadata"`
// Spec holds the desired state of the SecretMapping from the client
// +optional
Spec SecretMappingSpec `json:"spec"`
}
// SecretMappingSpec defines the desired state of SecretMapping.
type SecretMappingSpec struct {
// Secrets rules for each secret
Secrets []SecretRule `json:"secrets,omitempty"`
Defaults `json:"defaults,omitempty" validate:"nonzero"`
}
// Defaults contains default mapping configuration for any Kubernetes secrets to External Secrets
type Defaults struct {
// DefaultBackendType the default back end to use if there's no specific mapping
BackendType BackendType `json:"backendType,omitempty" validate:"nonzero"`
// GcpSecretsManager config
GcpSecretsManager GcpSecretsManager `json:"gcpSecretsManager,omitempty"`
}
// SecretMappingList contains a list of SecretMapping
//
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type SecretMappingList struct {
metav1.TypeMeta `json:",inline"`
// +optional
metav1.ListMeta `json:"metadata,omitempty"`
Items []SecretMapping `json:"items"`
}
// SecretRule the rules for a specific Secret
type SecretRule struct {
// Name name of the secret
Name string `json:"name,omitempty"`
// Namespace name of the secret
Namespace string `json:"namespace,omitempty"`
// BackendType for the secret
BackendType BackendType `json:"backendType"`
// Mappings one more mappings
Mappings []Mapping `json:"mappings,omitempty"`
// Mandatory marks this secret as being mandatory
Mandatory bool `json:"mandatory,omitempty"`
// GcpSecretsManager config
GcpSecretsManager GcpSecretsManager `json:"gcpSecretsManager,omitempty"`
}
// BackendType describes a secrets backend
type BackendType string
const (
// BackendTypeVault Vault is the Backed service
BackendTypeVault BackendType = "vault"
// BackendTypeGSM Google Secrets Manager is the Backed service
BackendTypeGSM BackendType = "gcpSecretsManager"
// BackendTypeNone if none is configured
BackendTypeNone BackendType = ""
)
// GcpSecretsManager the predicates which must be true to invoke the associated tasks/pipelines
type GcpSecretsManager struct {
// Version of the referenced secret
Version string `json:"version,omitempty"`
// ProjectId for the secret, defaults to the current GCP project
ProjectID string `json:"projectId,omitempty"`
// UniquePrefix needs to be a unique prefix in the GCP project where the secret resides, defaults to cluster name
UniquePrefix string `json:"uniquePrefix,omitempty"`
}
// Mapping the predicates which must be true to invoke the associated tasks/pipelines
type Mapping struct {
// Name the secret entry name which maps to the Key of the Secret.Data map
Name string `json:"name,omitempty"`
// Key the Vault key to load the secret value
// +optional
Key string `json:"key,omitempty"`
// Property the Vault property on the key to load the secret value
// +optional
Property string `json:"property,omitempty"`
}
// FindRule finds a secret rule for the given secret name
func (c *SecretMapping) FindRule(namespace, secretName string) SecretRule {
for i := range c.Spec.Secrets {
m := c.Spec.Secrets[i]
if m.Name == secretName && (m.Namespace == "" || m.Namespace == namespace) {
return m
}
}
return SecretRule{
BackendType: c.Spec.Defaults.BackendType,
}
}
// Find finds a secret rule for the given secret name
func (c *SecretMapping) Find(secretName, dataKey string) *Mapping {
for i := range c.Spec.Secrets {
m := c.Spec.Secrets[i]
if m.Name == secretName {
return m.Find(dataKey)
}
}
return nil
}
// Find finds a secret rule for the given secret name
func (c *SecretMapping) FindSecret(secretName string) *SecretRule {
for i := range c.Spec.Secrets {
m := c.Spec.Secrets[i]
if m.Name == secretName {
return &m
}
}
return nil
}
// Find finds a mapping for the given data name
func (r *SecretRule) Find(dataKey string) *Mapping {
for i, m := range r.Mappings {
if m.Name == dataKey {
return &r.Mappings[i]
}
}
return nil
}
// validate the secrete mapping fields
func (c *SecretMapping) Validate() error {
return validator.Validate(c)
}
// SaveConfig saves the configuration file to the given project directory
func (c *SecretMapping) SaveConfig(fileName string) error {
data, err := yaml.Marshal(c)
if err != nil {
return err
}
err = os.WriteFile(fileName, data, util.DefaultWritePermissions)
if err != nil {
return errors.Wrapf(err, "failed to save file %s", fileName)
}
return nil
}