Skip to content

Commit 09e6457

Browse files
Merge pull request #880 from cdoern/f-IR-390
IR-390: Make a configmap for MCO to consume CAs
2 parents ea479d1 + 9404a02 commit 09e6457

File tree

5 files changed

+230
-6
lines changed

5 files changed

+230
-6
lines changed

pkg/defaults/defaults.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ const (
2929
// CAs to be trusted during image pullthrough
3030
ImageRegistryCertificatesName = "image-registry-certificates"
3131

32+
// ImageRegistryCAName is the name of the configmap managed by the registry operator
33+
// on the openshift-config-managed namespace. This config map is nearly identical to
34+
// ImageRegistryCertificatesName, but it does not include the additionalTrustedCA
35+
// from images.config.openshift.io/cluster.
36+
ImageRegistryCAName = "image-registry-ca"
37+
3238
// ImageRegistryPrivateConfiguration is the name of a secret that is managed by the
3339
// registry operator and which provides credentials to the registry for things like
3440
// accessing S3 storage

pkg/operator/imageregistrycertificates.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ type ImageRegistryCertificatesController struct {
3232
coreClient corev1client.CoreV1Interface
3333
operatorClient v1helpers.OperatorClient
3434
configMapLister corev1listers.ConfigMapNamespaceLister
35+
configMapManagedLister corev1listers.ConfigMapLister
3536
serviceLister corev1listers.ServiceNamespaceLister
3637
imageConfigLister configv1listers.ImageLister
3738
openshiftConfigLister corev1listers.ConfigMapNamespaceLister
@@ -60,6 +61,7 @@ func NewImageRegistryCertificatesController(
6061
coreClient: coreClient,
6162
operatorClient: operatorClient,
6263
configMapLister: configMapInformer.Lister().ConfigMaps(defaults.ImageRegistryOperatorNamespace),
64+
configMapManagedLister: openshiftConfigManagedInformer.Lister(),
6365
serviceLister: serviceInformer.Lister().Services(defaults.ImageRegistryOperatorNamespace),
6466
imageConfigLister: imageConfigInformer.Lister(),
6567
openshiftConfigLister: openshiftConfigInformer.Lister().ConfigMaps(defaults.OpenShiftConfigNamespace),
@@ -162,6 +164,31 @@ func (c *ImageRegistryCertificatesController) sync() error {
162164
return utilerrors.NewAggregate([]error{err, updateError})
163165
}
164166

167+
g = resource.NewGeneratorImageRegistryCA(
168+
c.configMapLister,
169+
c.configMapManagedLister,
170+
c.imageConfigLister,
171+
c.openshiftConfigLister,
172+
c.serviceLister,
173+
c.imageRegistryConfigLister,
174+
c.storageListers,
175+
c.kubeconfig,
176+
c.coreClient,
177+
)
178+
err = resource.ApplyMutator(g)
179+
if err != nil {
180+
_, _, updateError := v1helpers.UpdateStatus(
181+
ctx,
182+
c.operatorClient,
183+
v1helpers.UpdateConditionFn(operatorv1.OperatorCondition{
184+
Type: "ImageRegistryCertificatesControllerDegraded",
185+
Status: operatorv1.ConditionTrue,
186+
Reason: "Error",
187+
Message: err.Error(),
188+
}))
189+
return utilerrors.NewAggregate([]error{err, updateError})
190+
}
191+
165192
_, _, err = v1helpers.UpdateStatus(
166193
ctx,
167194
c.operatorClient,

pkg/resource/caconfig.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -112,12 +112,12 @@ func (gcac *generatorCAConfig) expected() (runtime.Object, error) {
112112
if errors.IsNotFound(err) {
113113
klog.V(4).Infof("missing the service CA configmap: %s", err)
114114
} else if err != nil {
115-
return cm, err
115+
return cm, fmt.Errorf("%s: %s", gcac.GetName(), err)
116116
} else {
117117
if cert, ok := serviceCA.Data["service-ca.crt"]; ok {
118118
internalHostnames, err := getServiceHostnames(gcac.serviceLister, defaults.ServiceName)
119119
if err != nil {
120-
return cm, err
120+
return cm, fmt.Errorf("%s: %s", gcac.GetName(), err)
121121
}
122122
if len(internalHostnames) == 0 {
123123
klog.Infof("unable to get the service name to add service-ca.crt")
@@ -137,11 +137,11 @@ func (gcac *generatorCAConfig) expected() (runtime.Object, error) {
137137
if errors.IsNotFound(err) {
138138
klog.V(4).Infof("missing the image config: %s", err)
139139
} else if err != nil {
140-
return cm, err
140+
return cm, fmt.Errorf("%s: %s", gcac.GetName(), err)
141141
} else if caConfigName := imageConfig.Spec.AdditionalTrustedCA.Name; caConfigName != "" {
142142
upstreamConfig, err := gcac.openshiftConfigLister.Get(caConfigName)
143143
if err != nil {
144-
return nil, err
144+
return nil, fmt.Errorf("%s: %s", gcac.GetName(), err)
145145
}
146146

147147
for k, v := range upstreamConfig.Data {
@@ -154,12 +154,12 @@ func (gcac *generatorCAConfig) expected() (runtime.Object, error) {
154154

155155
driver, canRedirect, err := gcac.storageDriver()
156156
if err != nil {
157-
return cm, err
157+
return cm, fmt.Errorf("%s: %s", gcac.GetName(), err)
158158
}
159159
if driver != nil {
160160
storageCABundle, _, err := driver.CABundle()
161161
if err != nil {
162-
return cm, err
162+
return cm, fmt.Errorf("%s: %s", gcac.GetName(), err)
163163
}
164164
if storageCABundle != "" {
165165
klog.V(4).Infof("using storage ca bundle (%d bytes)", len(storageCABundle))

pkg/resource/generator.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ func ApplyMutator(gen Mutator) error {
4444

4545
klog.Infof("object %s created: %s", Name(gen), str)
4646
return nil
47+
4748
}
4849

4950
n, updated, err := gen.Update(o.DeepCopyObject())

pkg/resource/imageregistryca.go

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
package resource
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"strings"
7+
8+
corev1 "k8s.io/api/core/v1"
9+
"k8s.io/apimachinery/pkg/api/errors"
10+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
11+
"k8s.io/apimachinery/pkg/runtime"
12+
coreset "k8s.io/client-go/kubernetes/typed/core/v1"
13+
corelisters "k8s.io/client-go/listers/core/v1"
14+
restclient "k8s.io/client-go/rest"
15+
"k8s.io/klog/v2"
16+
17+
operatorv1 "github.com/openshift/api/operator/v1"
18+
configlisters "github.com/openshift/client-go/config/listers/config/v1"
19+
imageregistryv1listers "github.com/openshift/client-go/imageregistry/listers/imageregistry/v1"
20+
21+
"github.com/openshift/cluster-image-registry-operator/pkg/client"
22+
"github.com/openshift/cluster-image-registry-operator/pkg/defaults"
23+
"github.com/openshift/cluster-image-registry-operator/pkg/storage"
24+
)
25+
26+
var _ Mutator = &generatorImageRegistryCA{}
27+
28+
type generatorImageRegistryCA struct {
29+
lister corelisters.ConfigMapNamespaceLister
30+
managedLister corelisters.ConfigMapLister
31+
imageConfigLister configlisters.ImageLister
32+
openshiftConfigLister corelisters.ConfigMapNamespaceLister
33+
serviceLister corelisters.ServiceNamespaceLister
34+
imageRegistryConfigLister imageregistryv1listers.ConfigLister
35+
storageListers *client.StorageListers
36+
kubeconfig *restclient.Config
37+
client coreset.CoreV1Interface
38+
}
39+
40+
func NewGeneratorImageRegistryCA(
41+
lister corelisters.ConfigMapNamespaceLister,
42+
managedLister corelisters.ConfigMapLister,
43+
imageConfigLister configlisters.ImageLister,
44+
openshiftConfigLister corelisters.ConfigMapNamespaceLister,
45+
serviceLister corelisters.ServiceNamespaceLister,
46+
imageRegistryConfigLister imageregistryv1listers.ConfigLister,
47+
storageListers *client.StorageListers,
48+
kubeconfig *restclient.Config,
49+
client coreset.CoreV1Interface,
50+
) Mutator {
51+
return &generatorImageRegistryCA{
52+
lister: lister,
53+
managedLister: managedLister,
54+
imageConfigLister: imageConfigLister,
55+
openshiftConfigLister: openshiftConfigLister,
56+
serviceLister: serviceLister,
57+
imageRegistryConfigLister: imageRegistryConfigLister,
58+
storageListers: storageListers,
59+
kubeconfig: kubeconfig,
60+
client: client,
61+
}
62+
}
63+
64+
func (girca *generatorImageRegistryCA) Type() runtime.Object {
65+
return &corev1.ConfigMap{}
66+
}
67+
68+
func (girca *generatorImageRegistryCA) GetNamespace() string {
69+
return defaults.OpenShiftConfigManagedNamespace
70+
}
71+
72+
func (girca *generatorImageRegistryCA) GetName() string {
73+
return defaults.ImageRegistryCAName
74+
}
75+
76+
func (girca *generatorImageRegistryCA) storageDriver() (storage.Driver, bool, error) {
77+
imageRegistryConfig, err := girca.imageRegistryConfigLister.Get("cluster")
78+
if errors.IsNotFound(err) {
79+
return nil, false, nil
80+
} else if err != nil {
81+
return nil, false, err
82+
}
83+
84+
if imageRegistryConfig.Spec.ManagementState == operatorv1.Removed {
85+
// The certificates controller does not need to know about
86+
// storage when the management state is Removed.
87+
return nil, false, nil
88+
}
89+
90+
driver, err := storage.NewDriver(&imageRegistryConfig.Spec.Storage, girca.kubeconfig, girca.storageListers)
91+
if err == storage.ErrStorageNotConfigured || storage.IsMultiStoragesError(err) {
92+
return nil, false, nil
93+
} else if err != nil {
94+
return nil, false, err
95+
}
96+
97+
canRedirect := !imageRegistryConfig.Spec.DisableRedirect
98+
99+
return driver, canRedirect, nil
100+
}
101+
102+
func (girca *generatorImageRegistryCA) expected() (runtime.Object, error) {
103+
cm := &corev1.ConfigMap{
104+
ObjectMeta: metav1.ObjectMeta{
105+
Name: girca.GetName(),
106+
Namespace: girca.GetNamespace(),
107+
},
108+
Data: map[string]string{},
109+
BinaryData: map[string][]byte{},
110+
}
111+
112+
var ownHostnameKeys []string
113+
114+
serviceCA, err := girca.lister.Get(defaults.ServiceCAName)
115+
if errors.IsNotFound(err) {
116+
klog.V(4).Infof("missing the service CA configmap: %s", err)
117+
} else if err != nil {
118+
return cm, fmt.Errorf("%s: %s", girca.GetName(), err)
119+
} else {
120+
if cert, ok := serviceCA.Data["service-ca.crt"]; ok {
121+
internalHostnames, err := getServiceHostnames(girca.serviceLister, defaults.ServiceName)
122+
if err != nil {
123+
return cm, fmt.Errorf("%s: %s", girca.GetName(), err)
124+
}
125+
if len(internalHostnames) == 0 {
126+
klog.Infof("unable to get the service name to add service-ca.crt")
127+
} else {
128+
for _, internalHostname := range internalHostnames {
129+
key := strings.Replace(internalHostname, ":", "..", -1)
130+
ownHostnameKeys = append(ownHostnameKeys, key)
131+
cm.Data[key] = cert
132+
}
133+
}
134+
} else {
135+
klog.Infof("the service CA is not injected yet")
136+
}
137+
}
138+
139+
driver, canRedirect, err := girca.storageDriver()
140+
if err != nil {
141+
return cm, fmt.Errorf("%s: %s", girca.GetName(), err)
142+
}
143+
if driver != nil {
144+
storageCABundle, _, err := driver.CABundle()
145+
if err != nil {
146+
return cm, fmt.Errorf("%s: %s", girca.GetName(), err)
147+
}
148+
if storageCABundle != "" {
149+
klog.V(4).Infof("using storage ca bundle (%d bytes)", len(storageCABundle))
150+
if canRedirect {
151+
klog.V(4).Infof("injecting storage ca bundle into registry certificates...")
152+
for _, key := range ownHostnameKeys {
153+
cm.Data[key] += "\n" + storageCABundle
154+
}
155+
}
156+
}
157+
}
158+
159+
return cm, nil
160+
}
161+
162+
func (girca *generatorImageRegistryCA) Get() (runtime.Object, error) {
163+
return girca.managedLister.ConfigMaps(defaults.OpenShiftConfigManagedNamespace).Get(girca.GetName())
164+
}
165+
166+
func (girca *generatorImageRegistryCA) Create() (runtime.Object, error) {
167+
return commonCreate(girca, func(obj runtime.Object) (runtime.Object, error) {
168+
return girca.client.ConfigMaps(girca.GetNamespace()).Create(
169+
context.TODO(), obj.(*corev1.ConfigMap), metav1.CreateOptions{},
170+
)
171+
})
172+
}
173+
174+
func (girca *generatorImageRegistryCA) Update(o runtime.Object) (runtime.Object, bool, error) {
175+
return commonUpdate(girca, o, func(obj runtime.Object) (runtime.Object, error) {
176+
return girca.client.ConfigMaps(girca.GetNamespace()).Update(
177+
context.TODO(), obj.(*corev1.ConfigMap), metav1.UpdateOptions{},
178+
)
179+
})
180+
}
181+
182+
func (girca *generatorImageRegistryCA) Delete(opts metav1.DeleteOptions) error {
183+
return girca.client.ConfigMaps(girca.GetNamespace()).Delete(
184+
context.TODO(), girca.GetName(), opts,
185+
)
186+
}
187+
188+
func (g *generatorImageRegistryCA) Owned() bool {
189+
return true
190+
}

0 commit comments

Comments
 (0)