Skip to content

Commit 66179bb

Browse files
Merge pull request #100 from mfojtik/collect-image-registry
Bug 1832232: Gather image registry config
2 parents f730f2b + 79019f7 commit 66179bb

File tree

69 files changed

+11892
-32
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+11892
-32
lines changed

docs/gathered-data.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,13 @@ Location in archive: config/id/
4444
See: docs/insights-archive-sample/config/id
4545

4646

47+
## ClusterImageRegistry
48+
49+
fetches the cluster Image Registry configuration
50+
51+
Location in archive: config/imageregistry/
52+
53+
4754
## ClusterInfrastructure
4855

4956
fetches the cluster Infrastructure - the Infrastructure with name cluster.

manifests/03-clusterrole.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,14 @@ rules:
9595
- events
9696
verbs:
9797
- list
98+
- apiGroups:
99+
- imageregistry.operator.openshift.io
100+
resources:
101+
- configs
102+
verbs:
103+
- get
104+
- list
105+
- watch
98106
- apiGroups:
99107
- ""
100108
resources:

pkg/controller/operator.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ import (
1818
configv1client "github.com/openshift/client-go/config/clientset/versioned/typed/config/v1"
1919
"github.com/openshift/library-go/pkg/controller/controllercmd"
2020

21+
imageregistryv1client "github.com/openshift/client-go/imageregistry/clientset/versioned"
22+
2123
"github.com/openshift/insights-operator/pkg/authorizer/clusterauthorizer"
2224
"github.com/openshift/insights-operator/pkg/config"
2325
"github.com/openshift/insights-operator/pkg/config/configobserver"
@@ -107,6 +109,11 @@ func (s *Support) Run(ctx context.Context, controller *controllercmd.ControllerC
107109
return err
108110
}
109111

112+
registryClient, err := imageregistryv1client.NewForConfig(gatherKubeConfig)
113+
if err != nil {
114+
return err
115+
}
116+
110117
// ensure the insight snapshot directory exists
111118
if _, err := os.Stat(s.StoragePath); err != nil && os.IsNotExist(err) {
112119
if err := os.MkdirAll(s.StoragePath, 0777); err != nil {
@@ -129,7 +136,7 @@ func (s *Support) Run(ctx context.Context, controller *controllercmd.ControllerC
129136

130137
// the gatherers periodically check the state of the cluster and report any
131138
// config to the recorder
132-
configPeriodic := clusterconfig.New(gatherConfigClient, gatherKubeClient.CoreV1(), gatherKubeClient.CertificatesV1beta1(), metricsClient)
139+
configPeriodic := clusterconfig.New(gatherConfigClient, gatherKubeClient.CoreV1(), gatherKubeClient.CertificatesV1beta1(), metricsClient, registryClient.ImageregistryV1())
133140
periodic := periodic.New(configObserver, recorder, map[string]gather.Interface{
134141
"config": configPeriodic,
135142
})

pkg/gather/clusterconfig/clusterconfig.go

Lines changed: 95 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,61 +2,75 @@ package clusterconfig
22

33
import (
44
"context"
5+
"encoding/base64"
6+
"encoding/pem"
57
"fmt"
68
"regexp"
79
"sort"
810
"strings"
911
"sync"
1012
"time"
1113

12-
configv1 "github.com/openshift/api/config/v1"
13-
"github.com/openshift/client-go/config/clientset/versioned/scheme"
14-
configv1client "github.com/openshift/client-go/config/clientset/versioned/typed/config/v1"
15-
certificatesv1beta1 "k8s.io/client-go/kubernetes/typed/certificates/v1beta1"
16-
17-
"encoding/base64"
18-
"encoding/pem"
19-
2014
corev1 "k8s.io/api/core/v1"
2115
"k8s.io/apimachinery/pkg/api/errors"
2216
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2317
"k8s.io/apimachinery/pkg/runtime"
18+
"k8s.io/apimachinery/pkg/runtime/serializer"
2419
"k8s.io/apimachinery/pkg/util/json"
20+
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
2521
"k8s.io/apimachinery/pkg/util/sets"
2622
kubescheme "k8s.io/client-go/kubernetes/scheme"
23+
certificatesv1beta1 "k8s.io/client-go/kubernetes/typed/certificates/v1beta1"
2724
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
2825
"k8s.io/client-go/rest"
2926
"k8s.io/klog"
3027

28+
configv1 "github.com/openshift/api/config/v1"
29+
registryv1 "github.com/openshift/api/imageregistry/v1"
30+
openshiftscheme "github.com/openshift/client-go/config/clientset/versioned/scheme"
31+
configv1client "github.com/openshift/client-go/config/clientset/versioned/typed/config/v1"
32+
imageregistryv1 "github.com/openshift/client-go/imageregistry/clientset/versioned/typed/imageregistry/v1"
33+
3134
"github.com/openshift/insights-operator/pkg/record"
3235
)
3336

3437
var (
35-
serializer = scheme.Codecs.LegacyCodec(configv1.SchemeGroupVersion)
36-
kubeSerializer = kubescheme.Codecs.LegacyCodec(corev1.SchemeGroupVersion)
38+
openshiftSerializer = openshiftscheme.Codecs.LegacyCodec(configv1.SchemeGroupVersion)
39+
kubeSerializer = kubescheme.Codecs.LegacyCodec(corev1.SchemeGroupVersion)
3740

3841
// maxEventTimeInterval represents the "only keep events that are maximum 1h old"
3942
// TODO: make this dynamic like the reporting window based on configured interval
4043
maxEventTimeInterval = 1 * time.Hour
44+
45+
registrySerializer serializer.CodecFactory
46+
registryScheme = runtime.NewScheme()
4147
)
4248

49+
func init() {
50+
utilruntime.Must(registryv1.AddToScheme(registryScheme))
51+
registrySerializer = serializer.NewCodecFactory(registryScheme)
52+
}
53+
4354
// Gatherer is a driving instance invoking collection of data
4455
type Gatherer struct {
45-
client configv1client.ConfigV1Interface
46-
coreClient corev1client.CoreV1Interface
47-
metricsClient rest.Interface
48-
certClient certificatesv1beta1.CertificatesV1beta1Interface
49-
lock sync.Mutex
50-
lastVersion *configv1.ClusterVersion
56+
client configv1client.ConfigV1Interface
57+
coreClient corev1client.CoreV1Interface
58+
metricsClient rest.Interface
59+
certClient certificatesv1beta1.CertificatesV1beta1Interface
60+
registryClient imageregistryv1.ImageregistryV1Interface
61+
lock sync.Mutex
62+
lastVersion *configv1.ClusterVersion
5163
}
5264

5365
// New creates new Gatherer
54-
func New(client configv1client.ConfigV1Interface, coreClient corev1client.CoreV1Interface, certClient certificatesv1beta1.CertificatesV1beta1Interface, metricsClient rest.Interface) *Gatherer {
66+
func New(client configv1client.ConfigV1Interface, coreClient corev1client.CoreV1Interface, certClient certificatesv1beta1.CertificatesV1beta1Interface, metricsClient rest.Interface,
67+
registryClient imageregistryv1.ImageregistryV1Interface) *Gatherer {
5568
return &Gatherer{
56-
client: client,
57-
coreClient: coreClient,
58-
certClient: certClient,
59-
metricsClient: metricsClient,
69+
client: client,
70+
coreClient: coreClient,
71+
certClient: certClient,
72+
metricsClient: metricsClient,
73+
registryClient: registryClient,
6074
}
6175
}
6276

@@ -74,6 +88,7 @@ func (i *Gatherer) Gather(ctx context.Context, recorder record.Interface) error
7488
GatherClusterInfrastructure(i),
7589
GatherClusterNetwork(i),
7690
GatherClusterAuthentication(i),
91+
GatherClusterImageRegistry(i),
7792
GatherClusterFeatureGates(i),
7893
GatherClusterOAuth(i),
7994
GatherClusterIngress(i),
@@ -329,6 +344,22 @@ func GatherClusterAuthentication(i *Gatherer) func() ([]record.Record, []error)
329344
}
330345
}
331346

347+
// GatherClusterImageRegistry fetches the cluster Image Registry configuration
348+
//
349+
// Location in archive: config/imageregistry/
350+
func GatherClusterImageRegistry(i *Gatherer) func() ([]record.Record, []error) {
351+
return func() ([]record.Record, []error) {
352+
config, err := i.registryClient.Configs().Get("cluster", metav1.GetOptions{})
353+
if errors.IsNotFound(err) {
354+
return nil, nil
355+
}
356+
if err != nil {
357+
return nil, []error{err}
358+
}
359+
return []record.Record{{Name: "config/imageregistry", Item: ImageRegistryAnonymizer{config}}}, nil
360+
}
361+
}
362+
332363
// GatherClusterFeatureGates fetches the cluster FeatureGate - the FeatureGate with name cluster.
333364
//
334365
// The Kubernetes api https://github.com/openshift/client-go/blob/master/config/clientset/versioned/typed/config/v1/featuregate.go#L50
@@ -490,17 +521,17 @@ func (r Raw) Marshal(_ context.Context) ([]byte, error) {
490521
// Anonymizer returns serialized runtime.Object without change
491522
type Anonymizer struct{ runtime.Object }
492523

493-
// Marshal serializes with OpenShift client-go serializer
524+
// Marshal serializes with OpenShift client-go openshiftSerializer
494525
func (a Anonymizer) Marshal(_ context.Context) ([]byte, error) {
495-
return runtime.Encode(serializer, a.Object)
526+
return runtime.Encode(openshiftSerializer, a.Object)
496527
}
497528

498529
// InfrastructureAnonymizer anonymizes infrastructure
499530
type InfrastructureAnonymizer struct{ *configv1.Infrastructure }
500531

501532
// Marshal serializes Infrastructure with anonymization
502533
func (a InfrastructureAnonymizer) Marshal(_ context.Context) ([]byte, error) {
503-
return runtime.Encode(serializer, anonymizeInfrastructure(a.Infrastructure))
534+
return runtime.Encode(openshiftSerializer, anonymizeInfrastructure(a.Infrastructure))
504535
}
505536

506537
func anonymizeInfrastructure(config *configv1.Infrastructure) *configv1.Infrastructure {
@@ -517,15 +548,50 @@ type ClusterVersionAnonymizer struct{ *configv1.ClusterVersion }
517548
// Marshal serializes ClusterVersion with anonymization
518549
func (a ClusterVersionAnonymizer) Marshal(_ context.Context) ([]byte, error) {
519550
a.ClusterVersion.Spec.Upstream = configv1.URL(anonymizeURL(string(a.ClusterVersion.Spec.Upstream)))
520-
return runtime.Encode(serializer, a.ClusterVersion)
551+
return runtime.Encode(openshiftSerializer, a.ClusterVersion)
521552
}
522553

523554
// FeatureGateAnonymizer implements serializaton of FeatureGate with anonymization
524555
type FeatureGateAnonymizer struct{ *configv1.FeatureGate }
525556

526557
// Marshal serializes FeatureGate with anonymization
527558
func (a FeatureGateAnonymizer) Marshal(_ context.Context) ([]byte, error) {
528-
return runtime.Encode(serializer, a.FeatureGate)
559+
return runtime.Encode(openshiftSerializer, a.FeatureGate)
560+
}
561+
562+
// IngressAnonymizer implements serialization with marshalling
563+
type ImageRegistryAnonymizer struct {
564+
*registryv1.Config
565+
}
566+
567+
// Marshal implements serialization of Ingres.Spec.Domain with anonymization
568+
func (a ImageRegistryAnonymizer) Marshal(_ context.Context) ([]byte, error) {
569+
a.Spec.HTTPSecret = anonymizeString(a.Spec.HTTPSecret)
570+
if a.Spec.Storage.S3 != nil {
571+
a.Spec.Storage.S3.Bucket = anonymizeString(a.Spec.Storage.S3.Bucket)
572+
a.Spec.Storage.S3.KeyID = anonymizeString(a.Spec.Storage.S3.KeyID)
573+
a.Spec.Storage.S3.RegionEndpoint = anonymizeString(a.Spec.Storage.S3.RegionEndpoint)
574+
a.Spec.Storage.S3.Region = anonymizeString(a.Spec.Storage.S3.Region)
575+
}
576+
if a.Spec.Storage.Azure != nil {
577+
a.Spec.Storage.Azure.AccountName = anonymizeString(a.Spec.Storage.Azure.AccountName)
578+
a.Spec.Storage.Azure.Container = anonymizeString(a.Spec.Storage.Azure.Container)
579+
}
580+
if a.Spec.Storage.GCS != nil {
581+
a.Spec.Storage.GCS.Bucket = anonymizeString(a.Spec.Storage.GCS.Bucket)
582+
a.Spec.Storage.GCS.ProjectID = anonymizeString(a.Spec.Storage.GCS.ProjectID)
583+
a.Spec.Storage.GCS.KeyID = anonymizeString(a.Spec.Storage.GCS.KeyID)
584+
}
585+
if a.Spec.Storage.Swift != nil {
586+
a.Spec.Storage.Swift.AuthURL = anonymizeString(a.Spec.Storage.Swift.AuthURL)
587+
a.Spec.Storage.Swift.Container = anonymizeString(a.Spec.Storage.Swift.Container)
588+
a.Spec.Storage.Swift.Domain = anonymizeString(a.Spec.Storage.Swift.Domain)
589+
a.Spec.Storage.Swift.DomainID = anonymizeString(a.Spec.Storage.Swift.DomainID)
590+
a.Spec.Storage.Swift.Tenant = anonymizeString(a.Spec.Storage.Swift.Tenant)
591+
a.Spec.Storage.Swift.TenantID = anonymizeString(a.Spec.Storage.Swift.TenantID)
592+
a.Spec.Storage.Swift.RegionName = anonymizeString(a.Spec.Storage.Swift.RegionName)
593+
}
594+
return runtime.Encode(registrySerializer.LegacyCodec(registryv1.SchemeGroupVersion), a.Config)
529595
}
530596

531597
// IngressAnonymizer implements serialization with marshalling
@@ -534,7 +600,7 @@ type IngressAnonymizer struct{ *configv1.Ingress }
534600
// Marshal implements serialization of Ingres.Spec.Domain with anonymization
535601
func (a IngressAnonymizer) Marshal(_ context.Context) ([]byte, error) {
536602
a.Ingress.Spec.Domain = anonymizeURL(a.Ingress.Spec.Domain)
537-
return runtime.Encode(serializer, a.Ingress)
603+
return runtime.Encode(openshiftSerializer, a.Ingress)
538604
}
539605

540606
// CompactedEvent holds one Namespace Event
@@ -570,7 +636,7 @@ func (a ProxyAnonymizer) Marshal(_ context.Context) ([]byte, error) {
570636
a.Proxy.Status.HTTPProxy = anonymizeURLCSV(a.Proxy.Status.HTTPProxy)
571637
a.Proxy.Status.HTTPSProxy = anonymizeURLCSV(a.Proxy.Status.HTTPSProxy)
572638
a.Proxy.Status.NoProxy = anonymizeURLCSV(a.Proxy.Status.NoProxy)
573-
return runtime.Encode(serializer, a.Proxy)
639+
return runtime.Encode(openshiftSerializer, a.Proxy)
574640
}
575641

576642
func anonymizeURLCSV(s string) string {
@@ -596,7 +662,7 @@ type ClusterOperatorAnonymizer struct{ *configv1.ClusterOperator }
596662

597663
// Marshal serializes ClusterOperator
598664
func (a ClusterOperatorAnonymizer) Marshal(_ context.Context) ([]byte, error) {
599-
return runtime.Encode(serializer, a.ClusterOperator)
665+
return runtime.Encode(openshiftSerializer, a.ClusterOperator)
600666
}
601667

602668
func isHealthyOperator(operator *configv1.ClusterOperator) bool {

0 commit comments

Comments
 (0)