@@ -29,6 +29,7 @@ import (
29
29
"k8s.io/apimachinery/pkg/util/sets"
30
30
"k8s.io/client-go/dynamic"
31
31
kubescheme "k8s.io/client-go/kubernetes/scheme"
32
+ appsclient "k8s.io/client-go/kubernetes/typed/apps/v1"
32
33
certificatesv1beta1 "k8s.io/client-go/kubernetes/typed/certificates/v1beta1"
33
34
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
34
35
policyclient "k8s.io/client-go/kubernetes/typed/policy/v1beta1"
@@ -42,6 +43,7 @@ import (
42
43
configv1client "github.com/openshift/client-go/config/clientset/versioned/typed/config/v1"
43
44
imageregistryv1 "github.com/openshift/client-go/imageregistry/clientset/versioned/typed/imageregistry/v1"
44
45
networkv1client "github.com/openshift/client-go/network/clientset/versioned/typed/network/v1"
46
+ appsv1 "k8s.io/api/apps/v1"
45
47
_ "k8s.io/apimachinery/pkg/runtime/serializer/yaml"
46
48
47
49
"github.com/openshift/insights-operator/pkg/record"
81
83
openshiftSerializer = openshiftscheme .Codecs .LegacyCodec (configv1 .SchemeGroupVersion )
82
84
kubeSerializer = kubescheme .Codecs .LegacyCodec (corev1 .SchemeGroupVersion )
83
85
policyV1Beta1Serializer = kubescheme .Codecs .LegacyCodec (policyv1beta1 .SchemeGroupVersion )
86
+ appsV1Serializer = kubescheme .Codecs .LegacyCodec (appsv1 .SchemeGroupVersion )
84
87
// maxEventTimeInterval represents the "only keep events that are maximum 1h old"
85
88
// TODO: make this dynamic like the reporting window based on configured interval
86
89
maxEventTimeInterval = 1 * time .Hour
@@ -120,14 +123,15 @@ type Gatherer struct {
120
123
registryClient imageregistryv1.ImageregistryV1Interface
121
124
crdClient apixv1beta1client.ApiextensionsV1beta1Interface
122
125
policyClient policyclient.PolicyV1beta1Interface
126
+ appsClient appsclient.AppsV1Interface
123
127
lock sync.Mutex
124
128
lastVersion * configv1.ClusterVersion
125
129
}
126
130
127
131
// New creates new Gatherer
128
132
func New (client configv1client.ConfigV1Interface , coreClient corev1client.CoreV1Interface , certClient certificatesv1beta1.CertificatesV1beta1Interface , metricsClient rest.Interface ,
129
133
registryClient imageregistryv1.ImageregistryV1Interface , crdClient apixv1beta1client.ApiextensionsV1beta1Interface , networkClient networkv1client.NetworkV1Interface ,
130
- dynamicClient dynamic.Interface , policyClient policyclient.PolicyV1beta1Interface ) * Gatherer {
134
+ dynamicClient dynamic.Interface , policyClient policyclient.PolicyV1beta1Interface , appsclient appsclient. AppsV1Interface ) * Gatherer {
131
135
return & Gatherer {
132
136
client : client ,
133
137
coreClient : coreClient ,
@@ -138,6 +142,7 @@ func New(client configv1client.ConfigV1Interface, coreClient corev1client.CoreV1
138
142
networkClient : networkClient ,
139
143
dynamicClient : dynamicClient ,
140
144
policyClient : policyClient ,
145
+ appsClient : appsclient ,
141
146
}
142
147
}
143
148
@@ -172,6 +177,7 @@ func (i *Gatherer) Gather(ctx context.Context, recorder record.Interface) error
172
177
GatherServiceAccounts (i ),
173
178
GatherMachineConfigPool (i ),
174
179
GatherContainerRuntimeConfig (i ),
180
+ GatherStatefulSets (i ),
175
181
)
176
182
}
177
183
@@ -1054,6 +1060,47 @@ func GatherContainerRuntimeConfig(i *Gatherer) func() ([]record.Record, []error)
1054
1060
}
1055
1061
}
1056
1062
1063
+ //GatherStatefulSets collects StatefulSet configs from default namespaces
1064
+ //
1065
+ // The Kubernetes API https://github.com/kubernetes/api/blob/master/apps/v1/types.go
1066
+ // Response see https://docs.openshift.com/container-platform/4.5/rest_api/workloads_apis/statefulset-apps-v1.html#statefulset-apps-v1
1067
+ //
1068
+ // Location in archive: config/statefulsets/
1069
+ func GatherStatefulSets (i * Gatherer ) func () ([]record.Record , []error ) {
1070
+ return func () ([]record.Record , []error ) {
1071
+ namespaces , err := getAllNamespaces (i )
1072
+ if errors .IsNotFound (err ) {
1073
+ return nil , nil
1074
+ }
1075
+ if err != nil {
1076
+ return nil , []error {err }
1077
+ }
1078
+
1079
+ osNamespaces := defaultNamespaces
1080
+ for _ , item := range namespaces .Items {
1081
+ if strings .HasPrefix (item .Name , "openshift" ) {
1082
+ osNamespaces = append (osNamespaces , item .Name )
1083
+ }
1084
+ }
1085
+ records := []record.Record {}
1086
+ for _ , namespace := range osNamespaces {
1087
+ sets , err := i .appsClient .StatefulSets (namespace ).List (i .ctx , metav1.ListOptions {})
1088
+ if err != nil {
1089
+ klog .V (2 ).Infof ("Unable to read StatefulSets in namespace %s error %s" , namespace , err )
1090
+ continue
1091
+ }
1092
+
1093
+ for _ , i := range sets .Items {
1094
+ records = append (records , record.Record {
1095
+ Name : fmt .Sprintf ("config/statefulsets/%s/%s" , namespace , i .GetName ()),
1096
+ Item : StatefulSetAnonymizer {& i },
1097
+ })
1098
+ }
1099
+ }
1100
+ return records , nil
1101
+ }
1102
+ }
1103
+
1057
1104
func (i * Gatherer ) gatherNamespaceEvents (namespace string ) ([]record.Record , []error ) {
1058
1105
// do not accidentally collect events for non-openshift namespace
1059
1106
if ! strings .HasPrefix (namespace , "openshift-" ) {
@@ -1837,3 +1884,16 @@ func (a ServiceAccountsMarshaller) Marshal(_ context.Context) ([]byte, error) {
1837
1884
func (a ServiceAccountsMarshaller ) GetExtension () string {
1838
1885
return "json"
1839
1886
}
1887
+
1888
+ // StatefulSetAnonymizer implements StatefulSet serialization without anonymization
1889
+ type StatefulSetAnonymizer struct { * appsv1.StatefulSet }
1890
+
1891
+ // Marshal implements StatefulSet serialization
1892
+ func (a StatefulSetAnonymizer ) Marshal (_ context.Context ) ([]byte , error ) {
1893
+ return runtime .Encode (appsV1Serializer , a .StatefulSet )
1894
+ }
1895
+
1896
+ // GetExtension returns extension for StatefulSet object
1897
+ func (a StatefulSetAnonymizer ) GetExtension () string {
1898
+ return "json"
1899
+ }
0 commit comments