Skip to content

Commit

Permalink
feat: adds types, unit tests, and loading functionality for RegistryC…
Browse files Browse the repository at this point in the history
…onfig

Closes ortelius#96
  • Loading branch information
jpower432 committed Nov 7, 2022
1 parent 51515a7 commit f92f3b3
Show file tree
Hide file tree
Showing 16 changed files with 524 additions and 86 deletions.
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,22 @@ uor-client-go version
4. Use the `uor-client-go pull` command to pull the artifact back to a local workspace.
5. Use the `uor-client-go inspect` command to inspect the build cache to list information about references.

### Registry Config

This registry config can be stored to individually configure each registry. It should be named `registry-config.yaml`.
The locations this can be stored in are the current working directory and at `$HOME/.uor/registry-config.yaml`.
As a special case, the prefix field can be missing; if so, it defaults to the value of the location field.

Example:
```bash
registries:
- prefix: "localhost:5001/test"
location: localhost:5001
skipTLS: false
plainHTTP: true
```


### Build a schema into an artifact

A schema can be optionally created prior to building a collection. Collections can then reference an already built schema or no schema at all.
Expand Down
5 changes: 5 additions & 0 deletions cmd/client/commands/build_collection.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ func (o *BuildCollectionOptions) Validate() error {
}

func (o *BuildCollectionOptions) Run(ctx context.Context) error {
if err := o.Remote.LoadRegistryConfig(); err != nil {
return err
}

space, err := workspace.NewLocalWorkspace(o.RootDir)
if err != nil {
return err
Expand All @@ -106,6 +110,7 @@ func (o *BuildCollectionOptions) Run(ctx context.Context) error {
orasclient.SkipTLSVerify(o.Insecure),
orasclient.WithAuthConfigs(o.Configs),
orasclient.WithPlainHTTP(o.PlainHTTP),
orasclient.WithRegistryConfig(o.RegistryConfig),
}

if !o.NoVerify {
Expand Down
2 changes: 1 addition & 1 deletion cmd/client/commands/options/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func (o *Common) BindFlags(fs *pflag.FlagSet) {
"Log level (debug, info, warn, error, fatal)")
}

// Init initializes default values for Common options.
// Init initializes default values for Common options at runtime.
func (o *Common) Init() error {
logger, err := log.NewLogrusLogger(o.IOStreams.Out, o.LogLevel)
if err != nil {
Expand Down
32 changes: 29 additions & 3 deletions cmd/client/commands/options/remote.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
package options

import "github.com/spf13/pflag"
import (
"errors"

"github.com/spf13/pflag"
"github.com/spf13/viper"

"github.com/uor-framework/uor-client-go/registryclient"
)

// Remote describes remote configuration options that can be set.
type Remote struct {
Insecure bool
PlainHTTP bool
Insecure bool
PlainHTTP bool
RegistryConfig registryclient.RegistryConfig
}

// BindFlags binds options from a flag set to Remote options.
Expand All @@ -14,6 +22,24 @@ func (o *Remote) BindFlags(fs *pflag.FlagSet) {
fs.BoolVarP(&o.PlainHTTP, "plain-http", "", o.PlainHTTP, "use plain http and not https when contacting registries")
}

// LoadRegistryConfig loads the registry config from disk.
func (o *Remote) LoadRegistryConfig() error {
viper.SetConfigName("registry-config")
viper.SetConfigType("yaml")
viper.AddConfigPath(".")
viper.AddConfigPath("$HOME/.uor")
err := viper.ReadInConfig()
if err != nil {
var configNotFound viper.ConfigFileNotFoundError
if errors.As(err, &configNotFound) {
return nil
}
return err
}

return viper.Unmarshal(&o.RegistryConfig)
}

// RemoteAuth describes remote authentication configuration options that can be set.
type RemoteAuth struct {
Configs []string
Expand Down
5 changes: 5 additions & 0 deletions cmd/client/commands/pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ func (o *PullOptions) Validate() error {
}

func (o *PullOptions) Run(ctx context.Context) error {
if err := o.Remote.LoadRegistryConfig(); err != nil {
return err
}

matcher := matchers.PartialAttributeMatcher{}
if o.AttributeQuery != "" {
Expand All @@ -132,8 +135,10 @@ func (o *PullOptions) Run(ctx context.Context) error {
orasclient.WithPlainHTTP(o.PlainHTTP),
orasclient.WithCache(cache),
orasclient.WithPullableAttributes(matcher),
orasclient.WithRegistryConfig(o.RegistryConfig),
}


if !o.NoVerify {
verificationFn := func(ctx context.Context, reference string) error {
o.Logger.Debugf("Checking signature of %s", reference)
Expand Down
5 changes: 5 additions & 0 deletions cmd/client/commands/push.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,15 @@ func (o *PushOptions) Run(ctx context.Context) error {
return err
}

if err := o.Remote.LoadRegistryConfig(); err != nil {
return err
}

client, err := orasclient.NewClient(
orasclient.SkipTLSVerify(o.Insecure),
orasclient.WithAuthConfigs(o.Configs),
orasclient.WithPlainHTTP(o.PlainHTTP),
orasclient.WithRegistryConfig(o.RegistryConfig),
)

if err != nil {
Expand Down
16 changes: 12 additions & 4 deletions cmd/client/commands/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ func (o *ServeOptions) Validate() error {
}

func (o *ServeOptions) Run(ctx context.Context) error {
if err := o.Remote.LoadRegistryConfig(); err != nil {
return err
}

ctx, cancel := context.WithCancel(ctx)
defer cancel()

Expand All @@ -86,11 +90,15 @@ func (o *ServeOptions) Run(ctx context.Context) error {
manager := defaultmanager.New(cache, o.Logger)

opts := collectionmanager.ServiceOptions{
Insecure: o.Insecure,
PlainHTTP: o.PlainHTTP,
PullCache: cache,
Insecure: o.Insecure,
PlainHTTP: o.PlainHTTP,
PullCache: cache,
RegistryConfig: o.RegistryConfig,
}
service, err := collectionmanager.FromManager(manager, opts)
if err != nil {
return err
}
service := collectionmanager.FromManager(manager, opts)

// Register the service with the gRPC server
managerapi.RegisterCollectionManagerServer(rpc, service)
Expand Down
6 changes: 4 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ require (
sigs.k8s.io/yaml v1.3.0
)

require github.com/sigstore/cosign v1.12.1
require (
github.com/sigstore/cosign v1.12.1
github.com/spf13/viper v1.13.0
)

require (
bitbucket.org/creachadair/shell v0.0.7 // indirect
Expand Down Expand Up @@ -213,7 +216,6 @@ require (
github.com/soheilhy/cmux v0.1.5 // indirect
github.com/spf13/cast v1.5.0 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/viper v1.13.0 // indirect
github.com/spiffe/go-spiffe/v2 v2.1.1 // indirect
github.com/subosito/gotenv v1.4.1 // indirect
github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect
Expand Down
12 changes: 12 additions & 0 deletions registryclient/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package registryclient

import "fmt"

// ErrNoAvailableMirrors denotes that all registry mirrors are not accessible.
type ErrNoAvailableMirrors struct {
Registry string
}

func (e *ErrNoAvailableMirrors) Error() string {
return fmt.Sprintf("registry %q: no avaialble mirrors", e.Registry)
}
59 changes: 30 additions & 29 deletions registryclient/orasclient/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ package orasclient

import (
"context"
"crypto/tls"
"net/http"
"sync"

ocispec "github.com/opencontainers/image-spec/specs-go/v1"
Expand All @@ -24,14 +22,16 @@ type ClientOption func(o *ClientConfig) error

// ClientConfig contains configuration data for the registry client.
type ClientConfig struct {
configs []string
credFn func(context.Context, string) (auth.Credential, error)
outputDir string
configs []string
credFn func(context.Context, string) (auth.Credential, error)
plainHTTP bool
insecure bool
cache content.Store
copyOpts oras.CopyOptions
attributes model.Matcher
registryConfig registryclient.RegistryConfig
prePullFn func(context.Context, string) error
plainHTTP bool
insecure bool
cache content.Store
copyOpts oras.CopyOptions
attributes model.Matcher
}

func (c *ClientConfig) apply(options []ClientOption) error {
Expand Down Expand Up @@ -62,35 +62,26 @@ func NewClient(options ...ClientOption) (registryclient.Client, error) {
return
}

// Setup auth client based on config inputs
authClient := &auth.Client{
Client: &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: config.insecure,
},
},
},
Cache: auth.NewCache(),
}
client.authCache = auth.NewCache()
client.plainHTTP = config.plainHTTP
client.insecure = config.insecure
client.copyOpts = config.copyOpts
client.destroy = destroy
client.cache = config.cache
client.attributes = config.attributes
client.registryConf = config.registryConfig
client.prePullFn = config.prePullFn

if config.credFn != nil {
authClient.Credential = config.credFn
client.credFn = config.credFn
} else {
store, err := NewAuthStore(config.configs...)
if err != nil {
return nil, err
}
authClient.Credential = store.Credential
client.credFn = store.Credential
}

client.authClient = authClient
client.plainHTTP = config.plainHTTP
client.copyOpts = config.copyOpts
client.destroy = destroy
client.cache = config.cache
client.attributes = config.attributes
client.prePullFn = config.prePullFn

// We are not allowing this to be configurable since
// oras file stores turn artifacts into descriptors in
Expand Down Expand Up @@ -118,6 +109,16 @@ func WithAuthConfigs(configs []string) ClientOption {
}
}

// WithRegistryConfig defines the configuration for specific registry
// endpoints. If specified, the configuration for a found registry
// will override WithSkipTLSVerify and WithPlainHTTP.
func WithRegistryConfig(registryConf registryclient.RegistryConfig) ClientOption {
return func(config *ClientConfig) error {
config.registryConfig = registryConf
return nil
}
}

// SkipTLSVerify disables TLS certificate checking.
func SkipTLSVerify(insecure bool) ClientOption {
return func(config *ClientConfig) error {
Expand Down
Loading

0 comments on commit f92f3b3

Please sign in to comment.