Skip to content

Commit f3ceaee

Browse files
committed
add internal and external URL handling for the docker pull secret
1 parent d70f43a commit f3ceaee

File tree

9 files changed

+81
-28
lines changed

9 files changed

+81
-28
lines changed

pkg/cmd/openshift-controller-manager/controller/serviceaccount.go

+4-3
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,10 @@ func RunServiceAccountPullSecretsController(ctx ControllerContext) (bool, error)
6868
go dockercfgController.Run(5, ctx.Stop)
6969

7070
dockerRegistryControllerOptions := serviceaccountcontrollers.DockerRegistryServiceControllerOptions{
71-
DockercfgController: dockercfgController,
72-
DockerURLsInitialized: dockerURLsInitialized,
73-
ClusterDNSSuffix: "cluster.local",
71+
DockercfgController: dockercfgController,
72+
DockerURLsInitialized: dockerURLsInitialized,
73+
ClusterDNSSuffix: "cluster.local",
74+
AdditionalRegistryURLs: ctx.OpenshiftControllerConfig.DockerPullSecret.RegistryURLs,
7475
}
7576
go serviceaccountcontrollers.NewDockerRegistryServiceController(
7677
ctx.ExternalKubeInformers.Core().V1().Secrets(),

pkg/cmd/openshift-controller-manager/conversion.go

+11
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,14 @@ func ConvertMasterConfigToOpenshiftControllerConfig(input *configapi.MasterConfi
2525
// deep copy to make sure no linger references are shared
2626
in := input.DeepCopy()
2727

28+
registryURLs := []string{}
29+
if len(in.ImagePolicyConfig.ExternalRegistryHostname) > 0 {
30+
registryURLs = append(registryURLs, in.ImagePolicyConfig.ExternalRegistryHostname)
31+
}
32+
if len(in.ImagePolicyConfig.InternalRegistryHostname) > 0 {
33+
registryURLs = append(registryURLs, in.ImagePolicyConfig.InternalRegistryHostname)
34+
}
35+
2836
ret := &configapi.OpenshiftControllerConfig{
2937
ClientConnectionOverrides: in.MasterClients.OpenShiftLoopbackClientConnectionOverrides,
3038
ServingInfo: &in.ServingInfo,
@@ -56,6 +64,9 @@ func ConvertMasterConfigToOpenshiftControllerConfig(input *configapi.MasterConfi
5664
ServiceAccount: configapi.ServiceAccountControllerConfig{
5765
ManagedNames: in.ServiceAccountConfig.ManagedNames,
5866
},
67+
DockerPullSecret: configapi.DockerPullSecretControllerConfig{
68+
RegistryURLs: registryURLs,
69+
},
5970
Network: configapi.NetworkControllerConfig{
6071
ClusterNetworks: in.NetworkConfig.ClusterNetworks,
6172
NetworkPluginName: in.NetworkConfig.NetworkPluginName,

pkg/cmd/server/apis/config/types.go

+6
Original file line numberDiff line numberDiff line change
@@ -1504,6 +1504,7 @@ type OpenshiftControllerConfig struct {
15041504
Deployer DeployerControllerConfig
15051505
Build BuildControllerConfig
15061506
ServiceAccount ServiceAccountControllerConfig
1507+
DockerPullSecret DockerPullSecretControllerConfig
15071508
Network NetworkControllerConfig
15081509
Ingress IngressControllerConfig
15091510
ImageImport ImageImportControllerConfig
@@ -1555,6 +1556,11 @@ type ServiceAccountControllerConfig struct {
15551556
ManagedNames []string
15561557
}
15571558

1559+
type DockerPullSecretControllerConfig struct {
1560+
// RegistryURLs is a list of urls that the docker pull secrets should be valid for.
1561+
RegistryURLs []string
1562+
}
1563+
15581564
type ImageImportControllerConfig struct {
15591565
// MaxScheduledImageImportsPerMinute is the maximum number of image streams that will be imported in the background per minute.
15601566
// The default value is 60. Set to -1 for unlimited.

pkg/serviceaccounts/controllers/create_dockercfg_secrets.go

+5-2
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,9 @@ func (e *DockercfgController) Run(workers int, stopCh <-chan struct{}) {
200200
defer utilruntime.HandleCrash()
201201
defer e.queue.ShutDown()
202202

203+
glog.Infof("Starting DockercfgController controller")
204+
defer glog.Infof("Shutting down DockercfgController controller")
205+
203206
// Wait for the store to sync before starting any work in this controller.
204207
ready := make(chan struct{})
205208
go e.waitForDockerURLs(ready, stopCh)
@@ -208,18 +211,18 @@ func (e *DockercfgController) Run(workers int, stopCh <-chan struct{}) {
208211
case <-stopCh:
209212
return
210213
}
214+
glog.V(1).Infof("urls found")
211215

212216
// Wait for the stores to fill
213217
if !cache.WaitForCacheSync(stopCh, e.serviceAccountController.HasSynced, e.secretController.HasSynced) {
214218
return
215219
}
220+
glog.V(1).Infof("caches synced")
216221

217-
glog.V(5).Infof("Starting workers")
218222
for i := 0; i < workers; i++ {
219223
go wait.Until(e.worker, time.Second, stopCh)
220224
}
221225
<-stopCh
222-
glog.V(1).Infof("Shutting down")
223226
}
224227

225228
func (c *DockercfgController) waitForDockerURLs(ready chan<- struct{}, stopCh <-chan struct{}) {

pkg/serviceaccounts/controllers/deleted_dockercfg_secrets.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -65,15 +65,16 @@ type DockercfgDeletedController struct {
6565
// Run processes the queue.
6666
func (e *DockercfgDeletedController) Run(stopCh <-chan struct{}) {
6767
defer utilruntime.HandleCrash()
68+
glog.Infof("Starting DockercfgDeletedController controller")
69+
defer glog.Infof("Shutting down DockercfgDeletedController controller")
6870

6971
// Wait for the stores to fill
7072
if !cache.WaitForCacheSync(stopCh, e.secretController.HasSynced) {
7173
return
7274
}
75+
glog.V(1).Infof("caches synced")
7376

74-
glog.V(5).Infof("Worker started")
7577
<-stopCh
76-
glog.V(1).Infof("Shutting down")
7778
}
7879

7980
// secretDeleted reacts to a Secret being deleted by looking to see if it's a dockercfg secret for a service account, in which case it

pkg/serviceaccounts/controllers/deleted_token_secrets.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -62,15 +62,16 @@ type DockercfgTokenDeletedController struct {
6262
// Runs controller loops and returns on shutdown
6363
func (e *DockercfgTokenDeletedController) Run(stopCh <-chan struct{}) {
6464
defer utilruntime.HandleCrash()
65+
glog.Infof("Starting DockercfgTokenDeletedController controller")
66+
defer glog.Infof("Shutting down DockercfgTokenDeletedController controller")
6567

6668
// Wait for the stores to fill
6769
if !cache.WaitForCacheSync(stopCh, e.secretController.HasSynced) {
6870
return
6971
}
72+
glog.V(1).Infof("caches synced")
7073

71-
glog.V(5).Infof("Worker started")
7274
<-stopCh
73-
glog.V(1).Infof("Shutting down")
7475
}
7576

7677
// secretDeleted reacts to a token secret being deleted by looking for a corresponding dockercfg secret and deleting it if it exists

pkg/serviceaccounts/controllers/docker_registry_service.go

+20-10
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ type DockerRegistryServiceControllerOptions struct {
3434

3535
DockercfgController *DockercfgController
3636

37+
// AdditionalRegistryURLs is a list of URLs that are always included
38+
AdditionalRegistryURLs []string
39+
3740
// DockerURLsInitialized is used to send a signal to the DockercfgController that it has the correct set of docker urls
3841
DockerURLsInitialized chan struct{}
3942
}
@@ -51,12 +54,13 @@ var serviceLocations = []serviceLocation{
5154
// NewDockerRegistryServiceController returns a new *DockerRegistryServiceController.
5255
func NewDockerRegistryServiceController(secrets informers.SecretInformer, serviceInformer informers.ServiceInformer, cl kclientset.Interface, options DockerRegistryServiceControllerOptions) *DockerRegistryServiceController {
5356
e := &DockerRegistryServiceController{
54-
client: cl,
55-
clusterDNSSuffix: options.ClusterDNSSuffix,
56-
dockercfgController: options.DockercfgController,
57-
registryLocationQueue: workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter()),
58-
secretsToUpdate: workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter()),
59-
dockerURLsInitialized: options.DockerURLsInitialized,
57+
client: cl,
58+
additionalRegistryURLs: options.AdditionalRegistryURLs,
59+
clusterDNSSuffix: options.ClusterDNSSuffix,
60+
dockercfgController: options.DockercfgController,
61+
registryLocationQueue: workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter()),
62+
secretsToUpdate: workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter()),
63+
dockerURLsInitialized: options.DockerURLsInitialized,
6064
}
6165

6266
// we're only watching two of these, but we already watch all services for the service serving cert signer
@@ -104,6 +108,8 @@ type DockerRegistryServiceController struct {
104108

105109
// clusterDNSSuffix is the suffix for in cluster DNS that can be added to service names
106110
clusterDNSSuffix string
111+
// additionalRegistryURLs is a list of URLs that are always included
112+
additionalRegistryURLs []string
107113

108114
dockercfgController *DockercfgController
109115

@@ -134,6 +140,9 @@ func (e *DockerRegistryServiceController) Run(workers int, stopCh <-chan struct{
134140
defer utilruntime.HandleCrash()
135141
defer e.registryLocationQueue.ShutDown()
136142

143+
glog.Infof("Starting DockerRegistryServiceController controller")
144+
defer glog.Infof("Shutting down DockerRegistryServiceController controller")
145+
137146
// Wait for the store to sync before starting any work in this controller.
138147
ready := make(chan struct{})
139148
go e.waitForDockerURLs(ready, stopCh)
@@ -142,14 +151,13 @@ func (e *DockerRegistryServiceController) Run(workers int, stopCh <-chan struct{
142151
case <-stopCh:
143152
return
144153
}
154+
glog.V(1).Infof("caches synced")
145155

146-
glog.V(5).Infof("Starting workers")
147156
go wait.Until(e.watchForDockerURLChanges, time.Second, stopCh)
148157
for i := 0; i < workers; i++ {
149158
go wait.Until(e.watchForDockercfgSecretUpdates, time.Second, stopCh)
150159
}
151160
<-stopCh
152-
glog.V(1).Infof("Shutting down")
153161
}
154162

155163
// enqueue adds to our queue. We only have one entry, but we never have to check it since we already know the things
@@ -225,10 +233,11 @@ func (e *DockerRegistryServiceController) watchForDockerURLChanges() {
225233

226234
// getDockerRegistryLocations returns the dns form and the ip form of the secret
227235
func (e *DockerRegistryServiceController) getDockerRegistryLocations() []string {
228-
ret := []string{}
236+
ret := append([]string{}, e.additionalRegistryURLs...)
229237
for _, location := range serviceLocations {
230238
ret = append(ret, getDockerRegistryLocations(e.serviceLister, location, e.clusterDNSSuffix)...)
231239
}
240+
glog.V(4).Infof("found docker registry urls: %v", ret)
232241
return ret
233242
}
234243

@@ -260,9 +269,10 @@ func (e *DockerRegistryServiceController) syncRegistryLocationChange() error {
260269
newDockerRegistryLocations := sets.NewString(newLocations...)
261270
existingURLs := e.getRegistryURLs()
262271
if existingURLs.Equal(newDockerRegistryLocations) && e.initialSecretsCheckDone {
263-
glog.V(4).Infof("No effective update: %v", newDockerRegistryLocations)
272+
glog.V(3).Infof("No effective update: %v", newDockerRegistryLocations)
264273
return nil
265274
}
275+
glog.V(1).Infof("Updating registry URLs from %v to %v", existingURLs, newDockerRegistryLocations)
266276

267277
// make sure that new dockercfg secrets get the correct locations
268278
e.dockercfgController.SetDockerURLs(newDockerRegistryLocations.List()...)

pkg/serviceaccounts/controllers/docker_registry_service_test.go

+4-2
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ func TestNoChangeNoOp(t *testing.T) {
123123
}
124124
}
125125

126-
func TestUpdateNewStyleSecretAndDNSSuffix(t *testing.T) {
126+
func TestUpdateNewStyleSecretAndDNSSuffixAndAdditionalURLs(t *testing.T) {
127127
stopChannel := make(chan struct{})
128128
defer close(stopChannel)
129129
received := make(chan bool)
@@ -143,6 +143,8 @@ func TestUpdateNewStyleSecretAndDNSSuffix(t *testing.T) {
143143

144144
kubeclient, fakeWatch, controller, informerFactory := controllerSetup([]runtime.Object{newStyleDockercfgSecret}, t, stopChannel)
145145
controller.clusterDNSSuffix = "something.else"
146+
// this bit also tests the additional registryURL options
147+
controller.additionalRegistryURLs = []string{"foo.bar.com"}
146148
controller.syncRegistryLocationHandler = wrapHandler(received, controller.syncRegistryLocationChange, t)
147149
controller.syncSecretHandler = wrapStringHandler(updatedSecret, controller.syncSecretUpdate, t)
148150
controller.initialSecretsCheckDone = false
@@ -180,7 +182,7 @@ func TestUpdateNewStyleSecretAndDNSSuffix(t *testing.T) {
180182
}
181183

182184
expectedDockercfgMap := credentialprovider.DockerConfig{}
183-
for _, key := range []string{"172.16.123.123:1235", "docker-registry.default.svc:1235", "docker-registry.default.svc.something.else:1235"} {
185+
for _, key := range []string{"foo.bar.com", "172.16.123.123:1235", "docker-registry.default.svc:1235", "docker-registry.default.svc.something.else:1235"} {
184186
expectedDockercfgMap[key] = credentialprovider.DockerConfigEntry{
185187
Username: "serviceaccount",
186188
Password: newStyleDockercfgSecret.Annotations[ServiceAccountTokenValueAnnotation],

test/integration/service_account_test.go

+25-7
Original file line numberDiff line numberDiff line change
@@ -165,9 +165,15 @@ func TestAutomaticCreationOfPullSecrets(t *testing.T) {
165165
saNamespace := api.NamespaceDefault
166166
saName := serviceaccountadmission.DefaultServiceAccountName
167167

168-
masterConfig, clusterAdminConfig, err := testserver.StartTestMaster()
168+
masterConfig, err := testserver.DefaultMasterOptions()
169169
if err != nil {
170-
t.Fatalf("unexpected error: %v", err)
170+
t.Fatalf("error creating config: %v", err)
171+
}
172+
masterConfig.ImagePolicyConfig.InternalRegistryHostname = "internal.registry.com:8080"
173+
masterConfig.ImagePolicyConfig.ExternalRegistryHostname = "external.registry.com"
174+
clusterAdminConfig, err := testserver.StartConfiguredMaster(masterConfig)
175+
if err != nil {
176+
t.Fatalf("error starting server: %v", err)
171177
}
172178
defer testserver.CleanupMasterEtcd(t, masterConfig)
173179
clusterAdminKubeClient, err := testutil.GetClusterAdminKubeClient(clusterAdminConfig)
@@ -192,17 +198,23 @@ func TestAutomaticCreationOfPullSecrets(t *testing.T) {
192198
if len(saPullSecret) == 0 {
193199
t.Errorf("pull secret was not created")
194200
}
201+
if !strings.Contains(saPullSecret, masterConfig.ImagePolicyConfig.InternalRegistryHostname) {
202+
t.Errorf("missing %q in %v", masterConfig.ImagePolicyConfig.InternalRegistryHostname, saPullSecret)
203+
}
204+
if !strings.Contains(saPullSecret, masterConfig.ImagePolicyConfig.ExternalRegistryHostname) {
205+
t.Errorf("missing %q in %v", masterConfig.ImagePolicyConfig.ExternalRegistryHostname, saPullSecret)
206+
}
195207
}
196208

197209
func waitForServiceAccountPullSecret(client kclientset.Interface, ns, name string, attempts int, interval time.Duration) (string, string, error) {
198210
for i := 0; i <= attempts; i++ {
199211
time.Sleep(interval)
200-
secretName, token, err := getServiceAccountPullSecret(client, ns, name)
212+
secretName, dockerCfg, err := getServiceAccountPullSecret(client, ns, name)
201213
if err != nil {
202214
return "", "", err
203215
}
204-
if len(token) > 0 {
205-
return secretName, token, nil
216+
if len(dockerCfg) > 2 {
217+
return secretName, dockerCfg, nil
206218
}
207219
}
208220
return "", "", nil
@@ -317,9 +329,15 @@ func TestEnforcingServiceAccount(t *testing.T) {
317329
}
318330

319331
func TestDockercfgTokenDeletedController(t *testing.T) {
320-
masterConfig, clusterAdminConfig, err := testserver.StartTestMaster()
332+
masterConfig, err := testserver.DefaultMasterOptions()
321333
if err != nil {
322-
t.Fatalf("unexpected error: %v", err)
334+
t.Fatalf("error creating config: %v", err)
335+
}
336+
masterConfig.ImagePolicyConfig.InternalRegistryHostname = "internal.registry.com:8080"
337+
masterConfig.ImagePolicyConfig.ExternalRegistryHostname = "external.registry.com"
338+
clusterAdminConfig, err := testserver.StartConfiguredMaster(masterConfig)
339+
if err != nil {
340+
t.Fatalf("error starting server: %v", err)
323341
}
324342
defer testserver.CleanupMasterEtcd(t, masterConfig)
325343
clusterAdminClientConfig, err := testutil.GetClusterAdminClientConfig(clusterAdminConfig)

0 commit comments

Comments
 (0)