8000 Collect count of secrets (#5404) · nginx/kubernetes-ingress@3ab4514 · GitHub
[go: up one dir, main page]

Skip to content

Commit 3ab4514

Browse files
authored
Collect count of secrets (#5404)
1 parent 434ce02 commit 3ab4514

File tree

14 files changed

+235
-22
lines changed

14 files changed

+235
-22
lines changed

charts/nginx-ingress/values.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -265,19 +265,19 @@ controller:
265265
## The Ingress Controller processes all the resources that do not have the "ingressClassName" field for all versions of kubernetes.
266266
name: nginx
267267

268-
## Creates a new IngressClass object with the name "controller.ingressClass.name". Set to false to use an existing IngressClass with the same name. If you use helm upgrade, do not change the values from the previous release as helm will delete IngressClass objects managed by helm. If you are upgrading from a release earlier than 3.3.0, do not set the value to false.
268+
## Creates a new IngressClass object with the name "controller.ingressClass.name". To use an existing IngressClass with the same name, set this value to false. If you use helm upgrade, do not change the values from the previous release as helm will delete IngressClass objects managed by helm. If you are upgrading from a release earlier than 3.3.0, do not set the value to false.
269269
create: true
270270

271271
## New Ingresses without an ingressClassName field specified will be assigned the class specified in `controller.ingressClass`. Requires "controller.ingressClass.create".
272272
setAsDefaultIngress: false
273273

274-
## Comma separated list of namespaces to watch for Ingress resources. By default the Ingress Controller watches all namespaces. Mutually exclusive with "controller.watchNamespaceLabel".
274+
## Comma separated list of namespaces to watch for Ingress resources. By default, the 8000 Ingress Controller watches all namespaces. Mutually exclusive with "controller.watchNamespaceLabel".
275275
watchNamespace: ""
276276

277-
## Configures the Ingress Controller to watch only those namespaces with label foo=bar. By default the Ingress Controller watches all namespaces. Mutually exclusive with "controller.watchNamespace".
277+
## Configures the Ingress Controller to watch only those namespaces with label foo=bar. By default, the Ingress Controller watches all namespaces. Mutually exclusive with "controller.watchNamespace".
278278
watchNamespaceLabel: ""
279279

280-
## Comma separated list of namespaces to watch for Secret resources. By default the Ingress Controller watches all namespaces.
280+
## Comma separated list of namespaces to watch for Secret resources. By default, the Ingress Controller watches all namespaces.
281281
watchSecretNamespace: ""
282282

283283
## Enable the custom resources.

cmd/nginx-ingress/main.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ func main() {
135135
nginxManager.CreateTLSPassthroughHostsConfig(emptyFile)
136136
}
137137

138-
cpcfg := startChildProcesses(nginxManager)
138+
process := startChildProcesses(nginxManager)
139139

140140
plusClient := createPlusClient(*nginxPlus, useFakeNginxManager, nginxManager)
141141

@@ -227,7 +227,7 @@ func main() {
227227
}()
228228
}
229229

230-
go handleTermination(lbc, nginxManager, syslogListener, cpcfg)
230+
go handleTermination(lbc, nginxManager, syslogListener, process)
231231

232232
lbc.Run()
233233

@@ -439,7 +439,7 @@ func getAgentVersionInfo(nginxManager nginx.Manager) string {
439439
return nginxManager.AgentVersion()
440440
}
441441

442-
type childProcessConfig struct {
442+
type childProcesses struct {
443443
nginxDone chan error
444444
aPPluginEnable bool
445445
aPPluginDone chan error
@@ -449,7 +449,9 @@ type childProcessConfig struct {
449449
agentDone chan error
450450
}
451451

452-
func startChildProcesses(nginxManager nginx.Manager) childProcessConfig {
452+
// newChildProcesses starts the several child processes based on flags set.
453+
// AppProtect. AppProtectDos, Agent.
454+
func startChildProcesses(nginxManager nginx.Manager) childProcesses {
453455
var aPPluginDone chan error
454456

455457
if *appProtect {
@@ -473,7 +475,7 @@ func startChildProcesses(nginxManager nginx.Manager) childProcessConfig {
473475
nginxManager.AgentStart(agentDone, *agentInstanceGroup)
474476
}
475477

476-
return childProcessConfig{
478+
return childProcesses{
477479
nginxDone: nginxDone,
478480
aPPluginEnable: *appProtect,
479481
aPPluginDone: aPPluginDone,
@@ -566,7 +568,7 @@ func processNginxConfig(staticCfgParams *configs.StaticConfigParams, cfgParams *
566568
}
567569
}
568570

569-
// getSocketClient gets an http.Client with the a unix socket transport.
571+
// getSocketClient gets a http.Client with a unix socket transport.
570572
func getSocketClient(sockPath string) *http.Client {
571573
return &http.Client{
572574
Transport: &http.Transport{
@@ -594,7 +596,7 @@ func getAndValidateSecret(kubeClient *kubernetes.Clientset, secretNsName string)
594596
return secret, nil
595597
}
596598

597-
func handleTermination(lbc *k8s.LoadBalancerController, nginxManager nginx.Manager, listener metrics.SyslogListener, cpcfg childProcessConfig) {
599+
func handleTermination(lbc *k8s.LoadBalancerController, nginxManager nginx.Manager, listener metrics.SyslogListener, cpcfg childProcesses) {
598600
signalChan := make(chan os.Signal, 1)
599601
signal.Notify(signalChan, syscall.SIGTERM)
600602

docs/content/overview/product-telemetry.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ These are the data points collected and reported by NGINX Ingress Controller:
3232
- **VirtualServerRoutes** The number of VirtualServerRoute resources managed by NGINX Ingress Controller.
3333
- **TransportServers** The number of TransportServer resources managed by NGINX Ingress Controller.
3434
- **Replicas** Number of Deployment replicas, or Daemonset instances.
35+
- **Secrets** Number of Secret resources managed by NGINX Ingress Controller.
3536

3637
## Opt out
3738

internal/k8s/controller.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,7 @@ func NewLoadBalancerController(input NewLoadBalancerControllerInput) *LoadBalanc
364364
CustomK8sClientReader: input.ConfClient,
365365
Period: 24 * time.Hour,
366366
Configurator: lbc.configurator,
367+
SecretStore: lbc.secretStore,
367368
Version: input.NICVersion,
368369
PodNSName: types.NamespacedName{
369370
Namespace: os.Getenv("POD_NAMESPACE"),

internal/k8s/secrets/store.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ type SecretStore interface {
2525
AddOrUpdateSecret(secret *api_v1.Secret)
2626
DeleteSecret(key string)
2727
GetSecret(key string) *SecretReference
28+
GetSecretReferenceMap() map[string]*SecretReference
2829
}
2930

3031
// LocalSecretStore implements SecretStore interface.
@@ -101,6 +102,11 @@ func (s *LocalSecretStore) GetSecret(key string) *SecretReference {
101102
return secretRef
102103
}
103104

105+
// GetSecretReferenceMap returns a map that maps a secret key <namespace/name> to a SecretReference
106+
func (s *LocalSecretStore) GetSecretReferenceMap() map[string]*SecretReference {
107+
return s.secrets
108+
}
109+
104110
func getResourceKey(meta *metav1.ObjectMeta) string {
105111
return fmt.Sprintf("%s/%s", meta.Namespace, meta.Name)
106112
}
@@ -150,3 +156,8 @@ func (s *FakeSecretStore) GetSecret(key string) *SecretReference {
150156

151157
return secretRef
152158
}
159+
160+
// GetSecretReferenceMap returns a map that maps a secret key <namespace/name> to a SecretReference
161+
func (s *FakeSecretStore) GetSecretReferenceMap() map[string]*SecretReference {
162+
return s.secrets
163+
}

internal/k8s/secrets/store_test.go

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package secrets
22

33
import (
44
"errors"
5+
"fmt"
56
"testing"
67

78
"github.com/google/go-cmp/cmp"
@@ -101,7 +102,7 @@ func TestAddOrUpdateSecret(t *testing.T) {
101102
// Make the secret invalid
102103

103104
expectedManager = &fakeSecretFileManager{
104-
DeletedSecret: "default/tls-secret",
105+
DeletedSecret: fmt.Sprintf("%s/%s", validSecret.Namespace, validSecret.Name),
105106
}
106107

107108
manager.Reset()
@@ -116,7 +117,7 @@ func TestAddOrUpdateSecret(t *testing.T) {
116117
expectedSecretRef = &SecretReference{
117118
Secret: invalidSecret,
118119
Path: "",
119-
Error: errors.New("Failed to validate TLS cert and key: x509: malformed certificate"),
120+
Error: errors.New("failed to validate TLS cert and key: x509: malformed certificate"),
120121
}
121122
expectedManager = &fakeSecretFileManager{}
122123

@@ -303,3 +304,38 @@ func TestDeleteSecretInvalidSecret(t *testing.T) {
303304
t.Errorf("DeleteSecret() returned unexpected result (-want +got):\n%s", diff)
304305
}
305306
}
307+
308+
func TestGetSecretReferenceMapAddSecret(t *testing.T) {
309+
t.Parallel()
310+
311+
testCases := []struct {
312+
testName string
313+
manager *fakeSecretFileManager
314+
secret *api_v1.Secret
315+
expectedSecretKey string
316+
}{
317+
{
318+
testName: "Add valid secret to store",
319+
manager: &fakeSecretFileManager{},
320+
secret: validSecret,
321+
expectedSecretKey: getResourceKey(&validSecret.ObjectMeta),
322+
},
323+
{
324+
testName: "Add invalid secret to store",
325+
manager: &fakeSecretFileManager{},
326+
secret: invalidSecret,
327+
expectedSecretKey: getResourceKey(&invalidSecret.ObjectMeta),
328+
},
329+
}
330+
331+
for _, test := range testCases {
332+
store := NewLocalSecretStore(test.manager)
333+
store.AddOrUpdateSecret(test.secret)
334+
335+
secretRefMap := store.GetSecretReferenceMap()
336+
337+
if _, ok := secretRefMap[test.expectedSecretKey]; !ok {
338+
t.Errorf("test case %s expected secret %v to be in store", test.testName, store.GetSecret(test.expectedSecretKey).Secret)
339+
}
340+
}
341+
}

internal/k8s/secrets/validation.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ func ValidateTLSSecret(secret *api_v1.Secret) error {
4444

4545
_, err := tls.X509KeyPair(secret.Data[api_v1.TLSCertKey], secret.Data[api_v1.TLSPrivateKeyKey])
4646
if err != nil {
47-
return fmt.Errorf("Failed to validate TLS cert and key: %w", err)
47+
return fmt.Errorf("failed to validate TLS cert and key: %w", err)
4848
}
4949

5050
return nil
@@ -86,7 +86,7 @@ func ValidateCASecret(secret *api_v1.Secret) error {
8686

8787
_, err := x509.ParseCertificate(block.Bytes)
8888
if err != nil {
89-
return fmt.Errorf("Failed to validate certificate: %w", err)
89+
return fmt.Errorf("failed to validate certificate: %w", err)
9090
}
9191

9292
return nil

internal/telemetry/cluster.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,14 @@ func (c *Collector) InstallationID(ctx context.Context) (_ string, err error) {
115115
}
116116
}
117117

118+
// Secrets returns the number of secrets watched by NIC.
119+
func (c *Collector) Secrets() (int, error) {
120+
if c.Config.SecretStore == nil {
121+
return 0, errors.New("nil secret store")
122+
}
123+
return len(c.Config.SecretStore.GetSecretReferenceMap()), nil
124+
}
125+
118126
// lookupPlatform takes a string representing a K8s PlatformID
119127
// retrieved from a cluster node and returns a string
120128
// representing the platform name.

internal/telemetry/cluster_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -892,3 +892,24 @@ var (
892892
},
893893
}
894894
)
895+
896+
// Secrets for testing.
897+
var (
898+
secret1 = &apiCoreV1.Secret{
899+
ObjectMeta: metaV1.ObjectMeta{
900+
Name: "tls-secret-1",
901+
Namespace: "default",
902+
},
903+
Type: apiCoreV1.SecretTypeTLS,
904+
Data: map[string][]byte{},
905+
}
906+
907+
secret2 = &apiCoreV1.Secret{
908+
ObjectMeta: metaV1.ObjectMeta{
909+
Name: "tls-secret-2",
910+
Namespace: "default",
911+
},
912+
Type: apiCoreV1.SecretTypeTLS,
913+
Data: map[string][]byte{},
914+
}
915+
)

internal/telemetry/collector.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import (
77
"runtime"
88
"time"
99

10+
"github.com/nginxinc/kubernetes-ingress/internal/k8s/secrets"
11+
1012
tel "github.com/nginxinc/telemetry-exporter/pkg/telemetry"
1113

1214
"github.com/nginxinc/kubernetes-ingress/internal/configs"
@@ -57,6 +59,9 @@ type CollectorConfig struct {
5759

5860
Configurator *configs.Configurator
5961

62+
// SecretStore for access to secrets managed by NIC.
63+
SecretStore secrets.SecretStore
64+
6065
// Version represents NIC version.
6166
Version string
6267

@@ -110,6 +115,7 @@ func (c *Collector) Collect(ctx context.Context) {
110115
VirtualServerRoutes: int64(report.VirtualServerRoutes),
111116
TransportServers: int64(report.TransportServers),
112117
Replicas: int64(report.NICReplicaCount),
118+
Secrets: int64(report.Secrets),
113119
},
114120
}
115121

@@ -136,6 +142,7 @@ type Report struct {
136142
VirtualServers int
137143
VirtualServerRoutes int
138144
TransportServers int
145+
Secrets int
139146
}
140147

141148
// BuildReport takes context, collects telemetry data and builds the report.
@@ -179,6 +186,11 @@ func (c *Collector) BuildReport(ctx context.Context) (Report, error) {
179186
glog.Errorf("Error collecting telemetry data: InstallationID: %v", err)
180187
}
181188

189+
secrets, err := c.Secrets()
190+
if err != nil {
191+
glog.Errorf("Error collecting telemetry data: Secrets: %v", err)
192+
}
193+
182194
return Report{
183195
Name: "NIC",
184196
Version: c.Config.Version,
@@ -192,5 +204,6 @@ func (c *Collector) BuildReport(ctx context.Context) (Report, error) {
192204
VirtualServers: vsCount,
193205
VirtualServerRoutes: vsrCount,
194206
TransportServers: tsCount,
207+
Secrets: secrets,
195208
}, err
196209
}

0 commit comments

Comments
 (0)
0