-
Notifications
You must be signed in to change notification settings - Fork 39
/
common.go
230 lines (199 loc) · 10.2 KB
/
common.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
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
package pki
import (
"context"
"crypto/tls"
"fmt"
"github.com/go-logr/logr"
"github.com/konpyutaika/nifikop/api/v1alpha1"
"github.com/konpyutaika/nifikop/pkg/resources/templates"
certutil "github.com/konpyutaika/nifikop/pkg/util/cert"
"github.com/konpyutaika/nifikop/pkg/util/nifi"
"k8s.io/apimachinery/pkg/runtime"
)
const (
// NodeSelfSignerTemplate is the template used for self-signer resources
NodeSelfSignerTemplate = "%s-self-signer"
// NodeCACertTemplate is the template used for CA certificate resources
NodeCACertTemplate = "%s-ca-certificate"
// NodeServerCertTemplate is the template used for node certificate resources
NodeServerCertTemplate = "%s-%d-server-certificate"
// NodeIssuerTemplate is the template used for node issuer resources
NodeIssuerTemplate = "%s-issuer"
// NodeControllerFQDNTemplate is combined with the above and cluster namespace
// to create a 'fake' full-name for the controller user
NodeControllerFQDNTemplate = "%s.%s.mgt.%s"
//
SpiffeIdTemplate = "spiffe://%s/ns/%s/nifiuser/%s"
// CAIntermediateTemplate is the template used for intermediate CA resources
CAIntermediateTemplate = "%s-intermediate.%s"
// CAFQDNTemplate is the template used for the FQDN of a CA
CAFQDNTemplate = "%s-ca.%s.%s"
)
// Manager is the main interface for objects performing PKI operations
type Manager interface {
// ReconcilePKI ensures a PKI for a nifi cluster - should be idempotent.
// This method should at least setup any issuer needed for user certificates
// as well as node secrets
ReconcilePKI(ctx context.Context, logger logr.Logger, scheme *runtime.Scheme, externalHostnames []string) error
// FinalizePKI performs any cleanup steps necessary for a PKI backend
FinalizePKI(ctx context.Context, logger logr.Logger) error
// ReconcileUserCertificate ensures and returns a user certificate - should be idempotent
ReconcileUserCertificate(ctx context.Context, user *v1alpha1.NifiUser, scheme *runtime.Scheme) (*UserCertificate, error)
// FinalizeUserCertificate removes/revokes a user certificate
FinalizeUserCertificate(ctx context.Context, user *v1alpha1.NifiUser) error
// GetControllerTLSConfig retrieves a TLS configuration for a controller nifi client
GetControllerTLSConfig() (*tls.Config, error)
}
// UserCertificate is a struct representing the key components of a user TLS certificate
// for use across operations from other packages and internally.
type UserCertificate struct {
CA []byte
Certificate []byte
Key []byte
// TODO : Add Vault
// Serial is used by vault backend for certificate revocations
// Serial string
// TODO : Add Vault
// jks and password are used by vault backend for passing jks info between itself
// the cert-manager backend passes it through the k8s secret
//JKS []byte
//Password []byte
}
// DN returns the Distinguished Name of a TLS certificate
func (u *UserCertificate) DN() string {
// cert has already been validated so we can assume no error
cert, _ := certutil.DecodeCertificate(u.Certificate)
return cert.Subject.String()
}
// GetInternalDNSNames returns all potential DNS names for a nifi cluster - including nodes
func GetInternalDNSNames(cluster *v1alpha1.NifiCluster, nodeId int32) (dnsNames []string) {
dnsNames = make([]string, 0)
dnsNames = append(dnsNames, ClusterDNSNames(cluster, nodeId)...)
return
}
//func GetCommonName(cluster *v1alpha1.NifiCluster) string {
// return nifi.ComputeNiFiHostname(cluster.Name, cluster.Namespace, cluster.Spec.Service.HeadlessEnabled,
// cluster.Spec.ListenersConfig.GetClusterDomain(), cluster.Spec.ListenersConfig.UseExternalDNS)
//}
func GetNodeUserName(cluster *v1alpha1.NifiCluster, nodeId int32) string {
if cluster.Spec.NodeUserIdentityTemplate != nil {
return fmt.Sprintf(*cluster.Spec.NodeUserIdentityTemplate, nodeId)
}
return nifi.ComputeRequestNiFiNodeHostname(nodeId, cluster.Name, cluster.Namespace,
cluster.Spec.Service.HeadlessEnabled, cluster.Spec.ListenersConfig.GetClusterDomain(),
cluster.Spec.ListenersConfig.UseExternalDNS, cluster.Spec.Service.GetServiceTemplate())
}
// ClusterDNSNames returns all the possible DNS Names for a NiFi Cluster
func ClusterDNSNames(cluster *v1alpha1.NifiCluster, nodeId int32) (names []string) {
names = make([]string, 0)
// FQDN
names = append(names,
nifi.ComputeRequestNiFiAllNodeHostname(cluster.Name, cluster.Namespace,
cluster.Spec.ListenersConfig.GetClusterDomain(), cluster.Spec.ListenersConfig.UseExternalDNS,
cluster.Spec.Service.GetServiceTemplate()))
names = append(names,
nifi.ComputeRequestNiFiNodeHostname(nodeId, cluster.Name, cluster.Namespace,
cluster.Spec.Service.HeadlessEnabled, cluster.Spec.ListenersConfig.GetClusterDomain(),
cluster.Spec.ListenersConfig.UseExternalDNS, cluster.Spec.Service.GetServiceTemplate()))
if !cluster.Spec.ListenersConfig.UseExternalDNS {
// SVC notation
names = append(names,
nifi.ComputeRequestNiFiAllNodeNamespaceFull(cluster.Name, cluster.Namespace,
cluster.Spec.ListenersConfig.UseExternalDNS, cluster.Spec.Service.GetServiceTemplate()))
names = append(names,
nifi.ComputeRequestNiFiNodeNamespaceFull(nodeId, cluster.Name, cluster.Namespace,
cluster.Spec.Service.HeadlessEnabled, cluster.Spec.ListenersConfig.UseExternalDNS,
cluster.Spec.Service.GetServiceTemplate()))
// Namespace notation
names = append(names,
nifi.ComputeRequestNiFiAllNodeNamespace(cluster.Name, cluster.Namespace,
cluster.Spec.ListenersConfig.UseExternalDNS, cluster.Spec.Service.GetServiceTemplate()))
names = append(names,
nifi.ComputeRequestNiFiNodeNamespace(nodeId, cluster.Name, cluster.Namespace,
cluster.Spec.Service.HeadlessEnabled, cluster.Spec.ListenersConfig.UseExternalDNS,
cluster.Spec.Service.GetServiceTemplate()))
// Service name only
names = append(names,
nifi.ComputeRequestNiFiAllNodeService(cluster.Name, cluster.Spec.Service.GetServiceTemplate()))
names = append(names,
nifi.ComputeRequestNiFiNodeService(nodeId, cluster.Name, cluster.Spec.Service.HeadlessEnabled,
cluster.Spec.Service.GetServiceTemplate()))
// Pod name only
if cluster.Spec.Service.HeadlessEnabled {
names = append(names,
nifi.ComputeNodeName(nodeId, cluster.Name))
} else {
names = append(names, nifi.ComputeHostListenerNodeHostname(
nodeId, cluster.Name, cluster.Namespace, cluster.Spec.ListenersConfig.GetClusterDomain(),
cluster.Spec.ListenersConfig.UseExternalDNS, cluster.Spec.Service.GetServiceTemplate()))
}
}
return
}
// LabelsForNifiPKI returns kubernetes labels for a PKI object
func LabelsForNifiPKI(name string) map[string]string {
return map[string]string{"app": "nifi", "nifi_issuer": fmt.Sprintf(NodeIssuerTemplate, name)}
}
// NodeUsersForCluster returns a NifiUser CR for the node certificates in a NifiCluster
func NodeUsersForCluster(cluster *v1alpha1.NifiCluster, additionalHostnames []string) []*v1alpha1.NifiUser {
additionalHostnames = append(additionalHostnames)
var nodeUsers []*v1alpha1.NifiUser
for _, node := range cluster.Spec.Nodes {
nodeUsers = append(nodeUsers, nodeUserForClusterNode(cluster, node.Id, additionalHostnames))
}
return nodeUsers
}
// NodeUserForClusterNode returns a NifiUser CR for the node certificates in a NifiCluster
func nodeUserForClusterNode(cluster *v1alpha1.NifiCluster, nodeId int32, additionalHostnames []string) *v1alpha1.NifiUser {
additionalHostnames = append(additionalHostnames)
return &v1alpha1.NifiUser{
ObjectMeta: templates.ObjectMeta(GetNodeUserName(cluster, nodeId), LabelsForNifiPKI(cluster.Name), cluster),
Spec: v1alpha1.NifiUserSpec{
SecretName: fmt.Sprintf(NodeServerCertTemplate, cluster.Name, nodeId),
DNSNames: append(GetInternalDNSNames(cluster, nodeId), additionalHostnames...),
IncludeJKS: true,
ClusterRef: v1alpha1.ClusterReference{
Name: cluster.Name,
Namespace: cluster.Namespace,
},
AccessPolicies: []v1alpha1.AccessPolicy{
{Type: v1alpha1.GlobalAccessPolicyType, Action: v1alpha1.ReadAccessPolicyAction, Resource: v1alpha1.ProxyAccessPolicyResource},
{Type: v1alpha1.GlobalAccessPolicyType, Action: v1alpha1.WriteAccessPolicyAction, Resource: v1alpha1.ProxyAccessPolicyResource},
},
},
}
}
// ControllerUserForCluster returns a NifiUser CR for the controller/cc certificates in a NifiCluster
func ControllerUserForCluster(cluster *v1alpha1.NifiCluster) *v1alpha1.NifiUser {
/*nodeControllerName := fmt.Sprintf(NodeControllerFQDNTemplate,
cluster.GetNifiControllerUserIdentity(),
cluster.Namespace,
cluster.Spec.ListenersConfig.GetClusterDomain())*/
return &v1alpha1.NifiUser{
ObjectMeta: templates.ObjectMeta(
cluster.GetNifiControllerUserIdentity(),
LabelsForNifiPKI(cluster.Name), cluster,
),
Spec: v1alpha1.NifiUserSpec{
DNSNames: []string{cluster.GetNifiControllerUserIdentity()},
SecretName: cluster.GetNifiControllerUserIdentity(),
IncludeJKS: true,
ClusterRef: v1alpha1.ClusterReference{
Name: cluster.Name,
Namespace: cluster.Namespace,
},
AccessPolicies: []v1alpha1.AccessPolicy{
{Type: v1alpha1.GlobalAccessPolicyType, Action: v1alpha1.ReadAccessPolicyAction, Resource: v1alpha1.FlowAccessPolicyResource},
{Type: v1alpha1.GlobalAccessPolicyType, Action: v1alpha1.WriteAccessPolicyAction, Resource: v1alpha1.FlowAccessPolicyResource},
{Type: v1alpha1.GlobalAccessPolicyType, Action: v1alpha1.ReadAccessPolicyAction, Resource: v1alpha1.ControllerAccessPolicyResource},
{Type: v1alpha1.GlobalAccessPolicyType, Action: v1alpha1.WriteAccessPolicyAction, Resource: v1alpha1.ControllerAccessPolicyResource},
{Type: v1alpha1.GlobalAccessPolicyType, Action: v1alpha1.ReadAccessPolicyAction, Resource: v1alpha1.RestrictedComponentsAccessPolicyResource},
{Type: v1alpha1.GlobalAccessPolicyType, Action: v1alpha1.WriteAccessPolicyAction, Resource: v1alpha1.RestrictedComponentsAccessPolicyResource},
{Type: v1alpha1.GlobalAccessPolicyType, Action: v1alpha1.ReadAccessPolicyAction, Resource: v1alpha1.PoliciesAccessPolicyResource},
{Type: v1alpha1.GlobalAccessPolicyType, Action: v1alpha1.WriteAccessPolicyAction, Resource: v1alpha1.PoliciesAccessPolicyResource},
{Type: v1alpha1.GlobalAccessPolicyType, Action: v1alpha1.ReadAccessPolicyAction, Resource: v1alpha1.TenantsAccessPolicyResource},
{Type: v1alpha1.GlobalAccessPolicyType, Action: v1alpha1.WriteAccessPolicyAction, Resource: v1alpha1.TenantsAccessPolicyResource},
},
},
}
}