Skip to content

Commit

Permalink
Switch config format to be easier to understand
Browse files Browse the repository at this point in the history
Use a multiple choice instead of trying to keep it to booleans

Signed-off-by: James Hewitt <james.hewitt@uk.ibm.com>
  • Loading branch information
Jamstah committed Aug 26, 2022
1 parent b6485e4 commit 60c12c7
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 61 deletions.
46 changes: 34 additions & 12 deletions configuration/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -643,6 +643,8 @@ type Validation struct {
Disabled bool `yaml:"disabled,omitempty"`
// Manifests configures manifest validation.
Manifests ValidationManifests `yaml:"manifests,omitempty"`
// ImageIndexes configures validation of image indexes
ImageIndexes ValidationImageIndexes `yaml:"imageindexes,omitempty"`
}

type ValidationManifests struct {
Expand All @@ -655,18 +657,38 @@ type ValidationManifests struct {
// that URLs in pushed manifests must not match.
Deny []string `yaml:"deny,omitempty"`
} `yaml:"urls,omitempty"`
// ImageIndex configures validation of image indexes
ImageIndex ValidationManifestsImageIndex `yaml:"imageindex,omitempty"`
}

type ValidationManifestsImageIndex struct {
Images struct {
// Exist validates that images referenced by indexes exist in the registry
// before the image index is accepted.
Exist *bool `yaml:"exist"`
// Platforms filters the set of platforms to validate for image existence.
Platforms []Platform `yaml:"platforms,omitempty"`
} `yaml:"images,omitempty"`
}

type ValidationImageIndexes struct {
// PlatformsExist configures the validation applies to the platform images included in an image index
PlatformsExist PlatformsExist `yaml:"platformsexist"`
// SelectedPlatforms filters the set of platforms to validate for image existence.
SelectedPlatforms []Platform `yaml:"selectedplatforms,omitempty"`
}

// PlatformsExist configures the validation applies to the platform images included in an image index
// This can be all, none, or selected
type PlatformsExist string

// UnmarshalYAML implements the yaml.Umarshaler interface
// Unmarshals a string into a PlatformsExist option, lowercasing the string and validating that it represents a
// valid option
func (platformsexist *PlatformsExist) UnmarshalYAML(unmarshal func(interface{}) error) error {
var platformsExistString string
err := unmarshal(&platformsExistString)
if err != nil {
return err
}

platformsExistString = strings.ToLower(platformsExistString)
switch platformsExistString {
case "all", "none", "selected":
default:
return fmt.Errorf("invalid platformsexist option %s Must be one of [all, none, selected]", platformsExistString)
}

*platformsexist = PlatformsExist(platformsExistString)
return nil
}

// Parse parses an input configuration yaml document into a Configuration struct
Expand Down
35 changes: 11 additions & 24 deletions configuration/configuration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@ import (
// Hook up gocheck into the "go test" runner
func Test(t *testing.T) { TestingT(t) }

// falseaddr is a boolean false to reference
var falseaddr = false

// configStruct is a canonical example configuration, which should map to configYamlV0_1
var configStruct = Configuration{
Version: "0.1",
Expand Down Expand Up @@ -129,15 +126,8 @@ var configStruct = Configuration{
},
},
Validation: Validation{
Manifests: ValidationManifests{
ImageIndex: ValidationManifestsImageIndex{
Images: struct {
Exist *bool `yaml:"exist"`
Platforms []Platform `yaml:"platforms,omitempty"`
}{
Exist: &falseaddr,
},
},
ImageIndexes: ValidationImageIndexes{
PlatformsExist: "none",
},
},
}
Expand Down Expand Up @@ -185,10 +175,8 @@ http:
headers:
X-Content-Type-Options: [nosniff]
validation:
manifests:
imageindex:
images:
exist: false
imageindexes:
platformsexist: none
`

// inmemoryConfigYamlV0_1 is a Version 0.1 yaml document specifying an inmemory
Expand Down Expand Up @@ -219,10 +207,8 @@ http:
headers:
X-Content-Type-Options: [nosniff]
validation:
manifests:
imageindex:
images:
exist: false
imageindexes:
platformsexist: none
`

type ConfigSuite struct {
Expand Down Expand Up @@ -281,7 +267,7 @@ func (suite *ConfigSuite) TestParseIncomplete(c *C) {
suite.expectedConfig.Reporting = Reporting{}
suite.expectedConfig.Notifications = Notifications{}
suite.expectedConfig.HTTP.Headers = nil
suite.expectedConfig.Validation.Manifests.ImageIndex.Images.Exist = nil
suite.expectedConfig.Validation.ImageIndexes.PlatformsExist = ""

// Note: this also tests that REGISTRY_STORAGE and
// REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY can be used together
Expand Down Expand Up @@ -576,9 +562,10 @@ func copyConfig(config Configuration) *Configuration {
}

configCopy.Validation = Validation{
Enabled: config.Validation.Enabled,
Disabled: config.Validation.Disabled,
Manifests: config.Validation.Manifests,
Enabled: config.Validation.Enabled,
Disabled: config.Validation.Disabled,
Manifests: config.Validation.Manifests,
ImageIndexes: config.Validation.ImageIndexes,
}

return configCopy
Expand Down
70 changes: 50 additions & 20 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -1225,16 +1225,16 @@ features. Each subsection defines such a feature with configurable behavior.

## `validation`

```none
```yaml
validation:
manifests:
urls:
allow:
- ^https?://([^/]+\.)*example\.com/
deny:
- ^https?://www\.example\.com/
disabled: false
```

Use these settings to configure what validation the registry performs on content.

Validation is performed when content is uploaded to the registry. Changing these
settings will not validate content that has already been accepting into the registry.

### `disabled`

The `disabled` flag disables the other options in the `validation`
Expand All @@ -1247,6 +1247,16 @@ Use the `manifests` subsection to configure validation of manifests. If

#### `urls`

```yaml
validation:
manifests:
urls:
allow:
- ^https?://([^/]+\.)*example\.com/
deny:
- ^https?://www\.example\.com/
```

The `allow` and `deny` options are each a list of
[regular expressions](https://pkg.go.dev/regexp/syntax) that restrict the URLs in
pushed manifests.
Expand All @@ -1260,27 +1270,47 @@ one of the `allow` regular expressions **and** one of the following holds:
2. `deny` is set but no URLs within the manifest match any of the `deny` regular
expressions.

#### `imageindex`
### `imageindexes`

validation:
imageindexes:
platformsexist: [All|None|Selected]
selectedplatforms:
- os: linux
architecture: amd64

Use these settings to configure what validation the registry performs on image
index manifests uploaded to the registry.

#### `platformsexist`

##### `images`
Set `platformexist` to `all` (the default) to validate all platform images exist.
The registry will validate that the images referenced by the index exist in the
registry before accepting the image index.

Set `exist` to false to disable validation that images exist when an image
index manifest is uploaded.
Set `platformsexist` to `none` to disable all validation that images exist when an
image index manifest is uploaded. This allows image lists to be uploaded to the
registry without their associated images.

Set `platforms` to configure the set of platforms to validate the existence of.
If a platform is included in this list and in the images contained within an index,
the registry will validate that it exists in the registry. The registry will not
validate the existence of other platform images in the index.
Set `platformsexist` to `selected` to selectively validate the existence of platforms
within image index manifests.

This parameter does not validate that the platforms are included in the index,
if an image index is missing one or more platform images from this array it may
still be accepted by the registry.
#### `selectedplatforms`

When `platformsexist` is set to `selected`, set `selectedplatforms` to an array of
platforms to validate. If a platform is included in this the array and in the images
contained within an index, the registry will validate that the platform specific image
exists in the registry before accepting the index. The registry will not validate the
existence of platform specific images in the index that do not appear in the
`selectedplatforms` array.

This parameter does not validate that the configured platforms are included in every
index. If an image index does not include one of the platform specific images configured
in the `selectedplatforms` array, it may still be accepted by the registry.

Each platform is a map with two keys, `os` and `architecture`, as defined in the
[OCI Image Index specification](https://github.com/opencontainers/image-spec/blob/main/image-index.md#image-index-property-descriptions).

If `platforms` is an empty array, all images in the index must exist.

## Example: Development configuration

You can use this simple example for local development:
Expand Down
12 changes: 7 additions & 5 deletions registry/handlers/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,13 +257,15 @@ func NewApp(ctx context.Context, config *configuration.Configuration) *App {
options = append(options, storage.ManifestURLsDenyRegexp(re))
}
}
// If unset, default to true
if config.Validation.Manifests.ImageIndex.Images.Exist == nil ||
*config.Validation.Manifests.ImageIndex.Images.Exist {
// Any option except "none" enables the validation
if config.Validation.ImageIndexes.PlatformsExist != "none" {
options = append(options, storage.EnableValidateImageIndexImagesExist)
}
for _, platform := range config.Validation.Manifests.ImageIndex.Images.Platforms {
options = append(options, storage.AddValidateImageIndexImagesExistPlatform(platform.Architecture, platform.OS))
// If we are verifying selected image platforms, add those platforms to the options
if config.Validation.ImageIndexes.PlatformsExist == "selected" {
for _, platform := range config.Validation.ImageIndexes.SelectedPlatforms {
options = append(options, storage.AddValidateImageIndexImagesExistPlatform(platform.Architecture, platform.OS))
}
}
}

Expand Down

0 comments on commit 60c12c7

Please sign in to comment.