Skip to content

Commit 10fcce5

Browse files
committed
registry: report publicDockerImageRepository to image stream if configured
1 parent 3616a5b commit 10fcce5

File tree

23 files changed

+202
-79
lines changed

23 files changed

+202
-79
lines changed

pkg/cmd/server/admission/init.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ type PluginInitializer struct {
2828
Informers kinternalinformers.SharedInformerFactory
2929
ClusterResourceQuotaInformer quotainformer.ClusterResourceQuotaInformer
3030
ClusterQuotaMapper clusterquotamapping.ClusterQuotaMapper
31-
DefaultRegistryFn imageapi.DefaultRegistryFunc
31+
RegistryHostnameRetriever imageapi.RegistryHostnameRetriever
3232
SecurityInformers securityinformer.SharedInformerFactory
3333
UserInformers userinformer.SharedInformerFactory
3434
}
@@ -70,7 +70,7 @@ func (i *PluginInitializer) Initialize(plugin admission.Interface) {
7070
wantsSecurityInformer.SetSecurityInformers(i.SecurityInformers)
7171
}
7272
if wantsDefaultRegistryFunc, ok := plugin.(WantsDefaultRegistryFunc); ok {
73-
wantsDefaultRegistryFunc.SetDefaultRegistryFunc(i.DefaultRegistryFn)
73+
wantsDefaultRegistryFunc.SetDefaultRegistryFunc(i.RegistryHostnameRetriever.InternalRegistryHostname)
7474
}
7575
if wantsUserInformer, ok := plugin.(WantsUserInformer); ok {
7676
wantsUserInformer.SetUserInformer(i.UserInformers)

pkg/cmd/server/admission/types.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import (
99

1010
"github.com/openshift/origin/pkg/client"
1111
configapi "github.com/openshift/origin/pkg/cmd/server/api"
12-
imageapi "github.com/openshift/origin/pkg/image/apis/image"
1312
"github.com/openshift/origin/pkg/project/cache"
1413
"github.com/openshift/origin/pkg/quota/controller/clusterquotamapping"
1514
quotainformer "github.com/openshift/origin/pkg/quota/generated/informers/internalversion/quota/internalversion"
@@ -79,7 +78,7 @@ type WantsSecurityInformer interface {
7978
// WantsDefaultRegistryFunc should be implemented by admission plugins that need to know the default registry
8079
// address.
8180
type WantsDefaultRegistryFunc interface {
82-
SetDefaultRegistryFunc(imageapi.DefaultRegistryFunc)
81+
SetDefaultRegistryFunc(func() (string, bool))
8382
admission.Validator
8483
}
8584

pkg/cmd/server/api/types.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,16 @@ type ImagePolicyConfig struct {
514514
// this policy - typically only administrators or system integrations will have those
515515
// permissions.
516516
AllowedRegistriesForImport *AllowedRegistries
517+
// InternalRegistryHostname sets the hostname for the default internal image
518+
// registry. The value must be in "hostname[:port]" format.
519+
// For backward compatibility, users can still use OPENSHIFT_DEFAULT_REGISTRY
520+
// environment variable but this setting overrides the environment variable.
521+
InternalRegistryHostname string
522+
// ExternalRegistryHostname sets the hostname for the default external image
523+
// registry. The external hostname should be set only when the image registry
524+
// is exposed externally. The value is used in 'publicDockerImageRepository'
525+
// field in ImageStreams. The value must be in "hostname[:port]" format.
526+
ExternalRegistryHostname string
517527
}
518528

519529
// AllowedRegistries represents a list of registries allowed for the image import.

pkg/cmd/server/api/v1/swagger_doc.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,8 @@ var map_ImagePolicyConfig = map[string]string{
339339
"scheduledImageImportMinimumIntervalSeconds": "ScheduledImageImportMinimumIntervalSeconds is the minimum number of seconds that can elapse between when image streams scheduled for background import are checked against the upstream repository. The default value is 15 minutes.",
340340
"maxScheduledImageImportsPerMinute": "MaxScheduledImageImportsPerMinute is the maximum number of scheduled image streams that will be imported in the background per minute. The default value is 60. Set to -1 for unlimited.",
341341
"allowedRegistriesForImport": "AllowedRegistriesForImport limits the docker registries that normal users may import images from. Set this list to the registries that you trust to contain valid Docker images and that you want applications to be able to import from. Users with permission to create Images or ImageStreamMappings via the API are not affected by this policy - typically only administrators or system integrations will have those permissions.",
342+
"internalRegistryHostname": "InternalRegistryHostname sets the hostname for the default internal image registry. The value must be in \"hostname[:port]\" format. For backward compatibility, users can still use OPENSHIFT_DEFAULT_REGISTRY environment variable but this setting overrides the environment variable.",
343+
"externalRegistryHostname": "ExternalRegistryHostname sets the hostname for the default external image registry. The external hostname should be set only when the image registry is exposed externally. The value is used in 'publicDockerImageRepository' field in ImageStreams. The value must be in \"hostname[:port]\" format.",
342344
}
343345

344346
func (ImagePolicyConfig) SwaggerDoc() map[string]string {

pkg/cmd/server/api/v1/types.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,16 @@ type ImagePolicyConfig struct {
372372
// this policy - typically only administrators or system integrations will have those
373373
// permissions.
374374
AllowedRegistriesForImport *AllowedRegistries `json:"allowedRegistriesForImport,omitempty"`
375+
// InternalRegistryHostname sets the hostname for the default internal image
376+
// registry. The value must be in "hostname[:port]" format.
377+
// For backward compatibility, users can still use OPENSHIFT_DEFAULT_REGISTRY
378+
// environment variable but this setting overrides the environment variable.
379+
InternalRegistryHostname string `json:"internalRegistryHostname,omitempty"`
380+
// ExternalRegistryHostname sets the hostname for the default external image
381+
// registry. The external hostname should be set only when the image registry
382+
// is exposed externally. The value is used in 'publicDockerImageRepository'
383+
// field in ImageStreams. The value must be in "hostname[:port]" format.
384+
ExternalRegistryHostname string `json:"externalRegistryHostname,omitempty"`
375385
}
376386

377387
// AllowedRegistries represents a list of registries allowed for the image import.

pkg/cmd/server/origin/master.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ func (c *MasterConfig) newOpenshiftAPIConfig(kubeAPIServerConfig apiserver.Confi
7373
RuleResolver: c.RuleResolver,
7474
SubjectLocator: c.SubjectLocator,
7575
LimitVerifier: c.LimitVerifier,
76-
RegistryNameFn: c.RegistryNameFn,
76+
RegistryHostnameRetriever: c.RegistryHostnameRetriever,
7777
AllowedRegistriesForImport: c.Options.ImagePolicyConfig.AllowedRegistriesForImport,
7878
MaxImagesBulkImportedPerRepository: c.Options.ImagePolicyConfig.MaxImagesBulkImportedPerRepository,
7979
RouteAllocator: c.RouteAllocator(),

pkg/cmd/server/origin/master_config.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,9 @@ type MasterConfig struct {
119119
// of both the origin config AND the kube config, so this spot makes more sense.
120120
KubeAdmissionControl admission.Interface
121121

122-
// RegistryNameFn retrieves the name of the integrated registry, or false if no such registry
122+
// RegistryHostnameRetriever retrieves the name of the integrated registry, or false if no such registry
123123
// is available.
124-
RegistryNameFn imageapi.DefaultRegistryFunc
124+
RegistryHostnameRetriever imageapi.RegistryHostnameRetriever
125125

126126
KubeletClientConfig *kubeletclient.KubeletClientConfig
127127

@@ -265,7 +265,7 @@ func BuildMasterConfig(options configapi.MasterConfig, informers InformerAccess)
265265
Informers: informers.GetInternalKubeInformers(),
266266
ClusterResourceQuotaInformer: informers.GetQuotaInformers().Quota().InternalVersion().ClusterResourceQuotas(),
267267
ClusterQuotaMapper: clusterQuotaMappingController.GetClusterQuotaMapper(),
268-
DefaultRegistryFn: imageapi.DefaultRegistryFunc(defaultRegistryFunc),
268+
RegistryHostnameRetriever: imageapi.DefaultRegistryHostnameRetriever(defaultRegistryFunc, options.ImagePolicyConfig.ExternalRegistryHostname, options.ImagePolicyConfig.InternalRegistryHostname),
269269
SecurityInformers: informers.GetSecurityInformers(),
270270
UserInformers: informers.GetUserInformers(),
271271
}
@@ -316,7 +316,7 @@ func BuildMasterConfig(options configapi.MasterConfig, informers InformerAccess)
316316
AdmissionControl: originAdmission,
317317
KubeAdmissionControl: kubeAdmission,
318318

319-
RegistryNameFn: imageapi.DefaultRegistryFunc(defaultRegistryFunc),
319+
RegistryHostnameRetriever: imageapi.DefaultRegistryHostnameRetriever(defaultRegistryFunc, options.ImagePolicyConfig.ExternalRegistryHostname, options.ImagePolicyConfig.InternalRegistryHostname),
320320

321321
KubeletClientConfig: kubeletClientConfig,
322322

pkg/cmd/server/origin/openshift_apiserver.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,9 @@ type OpenshiftAPIConfig struct {
8282
RuleResolver rbacregistryvalidation.AuthorizationRuleResolver
8383
SubjectLocator authorizer.SubjectLocator
8484
LimitVerifier imageadmission.LimitVerifier
85-
// RegistryNameFn retrieves the name of the integrated registry, or false if no such registry
86-
// is available.
87-
RegistryNameFn imageapi.DefaultRegistryFunc
85+
// RegistryHostnameRetriever retrieves the internal and external hostname of
86+
// the integrated registry, or false if no such registry is available.
87+
RegistryHostnameRetriever imageapi.RegistryHostnameRetriever
8888
AllowedRegistriesForImport *configapi.AllowedRegistries
8989
MaxImagesBulkImportedPerRepository int
9090

@@ -143,8 +143,8 @@ func (c *OpenshiftAPIConfig) Validate() error {
143143
if c.LimitVerifier == nil {
144144
ret = append(ret, fmt.Errorf("LimitVerifier is required"))
145145
}
146-
if c.RegistryNameFn == nil {
147-
ret = append(ret, fmt.Errorf("RegistryNameFn is required"))
146+
if c.RegistryHostnameRetriever == nil {
147+
ret = append(ret, fmt.Errorf("RegistryHostnameRetriever is required"))
148148
}
149149
if c.RouteAllocator == nil {
150150
ret = append(ret, fmt.Errorf("RouteAllocator is required"))

pkg/cmd/server/origin/storage.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -203,12 +203,12 @@ func (c OpenshiftAPIConfig) GetRestStorage() (map[schema.GroupVersion]map[string
203203
imageRegistry := image.NewRegistry(imageStorage)
204204
imageSignatureStorage := imagesignature.NewREST(c.DeprecatedOpenshiftClient.Images())
205205
imageStreamSecretsStorage := imagesecret.NewREST(c.KubeClientInternal.Core())
206-
imageStreamStorage, imageStreamStatusStorage, internalImageStreamStorage, err := imagestreametcd.NewREST(c.GenericConfig.RESTOptionsGetter, c.RegistryNameFn, subjectAccessReviewRegistry, c.LimitVerifier)
206+
imageStreamStorage, imageStreamStatusStorage, internalImageStreamStorage, err := imagestreametcd.NewREST(c.GenericConfig.RESTOptionsGetter, c.RegistryHostnameRetriever, subjectAccessReviewRegistry, c.LimitVerifier)
207207
if err != nil {
208208
return nil, fmt.Errorf("error building REST storage: %v", err)
209209
}
210210
imageStreamRegistry := imagestream.NewRegistry(imageStreamStorage, imageStreamStatusStorage, internalImageStreamStorage)
211-
imageStreamMappingStorage := imagestreammapping.NewREST(imageRegistry, imageStreamRegistry, c.RegistryNameFn)
211+
imageStreamMappingStorage := imagestreammapping.NewREST(imageRegistry, imageStreamRegistry, c.RegistryHostnameRetriever)
212212
imageStreamTagStorage := imagestreamtag.NewREST(imageRegistry, imageStreamRegistry)
213213
importerCache, err := imageimporter.NewImageStreamLayerCache(imageimporter.DefaultImageStreamLayerCacheSize)
214214
if err != nil {
@@ -230,7 +230,7 @@ func (c OpenshiftAPIConfig) GetRestStorage() (map[schema.GroupVersion]map[string
230230
insecureImportTransport,
231231
importerDockerClientFn,
232232
c.AllowedRegistriesForImport,
233-
c.RegistryNameFn,
233+
c.RegistryHostnameRetriever,
234234
c.DeprecatedOpenshiftClient.SubjectAccessReviews())
235235
imageStreamImageStorage := imagestreamimage.NewREST(imageRegistry, imageStreamRegistry)
236236

pkg/image/admission/imagepolicy/imagepolicy.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ func newImagePolicyPlugin(parsed *api.ImagePolicyConfig) (*imagePolicyPlugin, er
108108
}, nil
109109
}
110110

111-
func (a *imagePolicyPlugin) SetDefaultRegistryFunc(fn imageapi.DefaultRegistryFunc) {
111+
func (a *imagePolicyPlugin) SetDefaultRegistryFunc(fn func() (string, bool)) {
112112
a.integratedRegistryMatcher.RegistryMatcher = rules.RegistryNameMatcher(fn)
113113
}
114114

pkg/image/admission/imagepolicy/rules/rules.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ type RegistryMatcher interface {
2323
Matches(name string) bool
2424
}
2525

26-
type RegistryNameMatcher imageapi.DefaultRegistryFunc
26+
type RegistryNameMatcher func() (string, bool)
2727

2828
func (m RegistryNameMatcher) Matches(name string) bool {
29-
current, ok := imageapi.DefaultRegistryFunc(m)()
29+
current, ok := m()
3030
if !ok {
3131
return false
3232
}

pkg/image/apis/image/helper.go

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,17 +45,53 @@ var errNoRegistryURLPathAllowed = fmt.Errorf("no path after <host>[:<port>] is a
4545
var errNoRegistryURLQueryAllowed = fmt.Errorf("no query arguments are allowed after <host>[:<port>]")
4646
var errRegistryURLHostEmpty = fmt.Errorf("no host name specified")
4747

48-
// DefaultRegistry returns the default Docker registry (host or host:port), or false if it is not available.
49-
type DefaultRegistry interface {
50-
DefaultRegistry() (string, bool)
48+
// RegistryHostnameRetriever represents an interface for retrieving the hostname
49+
// of internal and external registry.
50+
type RegistryHostnameRetriever interface {
51+
InternalRegistryHostname() (string, bool)
52+
ExternalRegistryHostname() (string, bool)
5153
}
5254

53-
// DefaultRegistryFunc implements DefaultRegistry for a simple function.
54-
type DefaultRegistryFunc func() (string, bool)
55+
// DefaultRegistryHostnameRetriever is a default implementation of
56+
// RegistryHostnameRetriever.
57+
// The first argument is a function that lazy-loads the value of
58+
// OPENSHIFT_DEFAULT_REGISTRY environment variable which should be deprecated in
59+
// future.
60+
func DefaultRegistryHostnameRetriever(deprecatedDefaultRegistryEnvFn func() (string, bool), external, internal string) RegistryHostnameRetriever {
61+
return &defaultRegistryHostnameRetriever{
62+
deprecatedDefaultFn: deprecatedDefaultRegistryEnvFn,
63+
externalHostname: external,
64+
internalHostname: internal,
65+
}
66+
}
67+
68+
type defaultRegistryHostnameRetriever struct {
69+
// deprecatedDefaultFn points to a function that will lazy-load the value of
70+
// OPENSHIFT_DEFAULT_REGISTRY.
71+
deprecatedDefaultFn func() (string, bool)
72+
internalHostname string
73+
externalHostname string
74+
}
75+
76+
// InternalRegistryHostnameFn returns a function that can be used to lazy-load
77+
// the internal Docker Registry hostname. If the master configuration properly
78+
// InternalRegistryHostname is set, it will prefer that over the lazy-loaded
79+
// environment variable 'OPENSHIFT_DEFAULT_REGISTRY'.
80+
func (r *defaultRegistryHostnameRetriever) InternalRegistryHostname() (string, bool) {
81+
if len(r.internalHostname) > 0 {
82+
return r.internalHostname, true
83+
}
84+
if r.deprecatedDefaultFn != nil {
85+
return r.deprecatedDefaultFn()
86+
}
87+
return "", false
88+
}
5589

56-
// DefaultRegistry implements the DefaultRegistry interface for a function.
57-
func (fn DefaultRegistryFunc) DefaultRegistry() (string, bool) {
58-
return fn()
90+
// ExternalRegistryHostnameFn returns a function that can be used to retrieve an
91+
// external/public hostname of Docker Registry. External location can be
92+
// configured in master config using 'ExternalRegistryHostname' property.
93+
func (r *defaultRegistryHostnameRetriever) ExternalRegistryHostname() (string, bool) {
94+
return r.externalHostname, len(r.externalHostname) > 0
5995
}
6096

6197
// ParseImageStreamImageName splits a string into its name component and ID component, and returns an error

pkg/image/registry/imagestream/etcd/etcd.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ type REST struct {
2525
var _ rest.StandardStorage = &REST{}
2626

2727
// NewREST returns a new REST.
28-
func NewREST(optsGetter restoptions.Getter, defaultRegistry imageapi.DefaultRegistry, subjectAccessReviewRegistry subjectaccessreview.Registry, limitVerifier imageadmission.LimitVerifier) (*REST, *StatusREST, *InternalREST, error) {
28+
func NewREST(optsGetter restoptions.Getter, registryHostname imageapi.RegistryHostnameRetriever, subjectAccessReviewRegistry subjectaccessreview.Registry, limitVerifier imageadmission.LimitVerifier) (*REST, *StatusREST, *InternalREST, error) {
2929
store := registry.Store{
3030
Copier: kapi.Scheme,
3131
NewFunc: func() runtime.Object { return &imageapi.ImageStream{} },
@@ -39,7 +39,7 @@ func NewREST(optsGetter restoptions.Getter, defaultRegistry imageapi.DefaultRegi
3939
subjectAccessReviewRegistry: subjectAccessReviewRegistry,
4040
}
4141
// strategy must be able to load image streams across namespaces during tag verification
42-
strategy := imagestream.NewStrategy(defaultRegistry, subjectAccessReviewRegistry, limitVerifier, rest)
42+
strategy := imagestream.NewStrategy(registryHostname, subjectAccessReviewRegistry, limitVerifier, rest)
4343

4444
store.CreateStrategy = strategy
4545
store.UpdateStrategy = strategy

pkg/image/registry/imagestream/etcd/etcd_test.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ const (
2727
)
2828

2929
var (
30-
testDefaultRegistry = imageapi.DefaultRegistryFunc(func() (string, bool) { return "test", true })
31-
noDefaultRegistry = imageapi.DefaultRegistryFunc(func() (string, bool) { return "", false })
30+
testDefaultRegistry = func() (string, bool) { return "test", true }
31+
noDefaultRegistry = func() (string, bool) { return "", false }
3232
)
3333

3434
type fakeSubjectAccessReviewRegistry struct {
@@ -48,7 +48,8 @@ func (f *fakeSubjectAccessReviewRegistry) CreateSubjectAccessReview(ctx apireque
4848

4949
func newStorage(t *testing.T) (*REST, *StatusREST, *InternalREST, *etcdtesting.EtcdTestServer) {
5050
etcdStorage, server := registrytest.NewEtcdStorage(t, latest.Version.Group)
51-
imageStorage, statusStorage, internalStorage, err := NewREST(restoptions.NewSimpleGetter(etcdStorage), noDefaultRegistry, &fakeSubjectAccessReviewRegistry{}, &testutil.FakeImageStreamLimitVerifier{})
51+
registry := imageapi.DefaultRegistryHostnameRetriever(noDefaultRegistry, "", "")
52+
imageStorage, statusStorage, internalStorage, err := NewREST(restoptions.NewSimpleGetter(etcdStorage), registry, &fakeSubjectAccessReviewRegistry{}, &testutil.FakeImageStreamLimitVerifier{})
5253
if err != nil {
5354
t.Fatal(err)
5455
}

0 commit comments

Comments
 (0)