From 0ac8297dec58ab9d4ecd9843504e68cdc8ada410 Mon Sep 17 00:00:00 2001 From: zebox Date: Sun, 13 Aug 2023 11:47:56 +0300 Subject: [PATCH] added TokenTTL option for registry auth token #22 In case when a pushing image has big size, pushing time can overhead default token expiry time. It can interrupt push process with token expire error. User can override default token expire time with TokenTTL option. --- Readme.md | 1 + app/cmd/cmd.go | 1 + app/cmd/cmd_test.go | 6 +++--- app/cmd/options.go | 7 ++++--- app/registry/registry.go | 10 ++++++++-- 5 files changed, 17 insertions(+), 8 deletions(-) diff --git a/Readme.md b/Readme.md index 7778b6b..88a0c16 100644 --- a/Readme.md +++ b/Readme.md @@ -381,6 +381,7 @@ registry: --registry.https-insecure Set https connection to registry insecure [$RA_REGISTRY_HTTPS_INSECURE] --registry.service: A service name which defined in registry settings [$RA_REGISTRY_SERVICE] --registry.issuer: A token issuer name which defined in registry settings [$RA_REGISTRY_ISSUER] + --registry.token-ttl: Define registry auth token TTL (in seconds). Default value 60 seconds. [$RA_REGISTRY_TOKEN_TTL] --registry.gc-interval: Use for define custom time interval for garbage collector execute (minutes), default 1 hours [$RA_REGISTRY_GC_INTERVAL] certs: diff --git a/app/cmd/cmd.go b/app/cmd/cmd.go index 4fcc22d..0ce5f14 100644 --- a/app/cmd/cmd.go +++ b/app/cmd/cmd.go @@ -201,6 +201,7 @@ func createRegistryConnection(opts RegistryGroup) (*registry.Registry, error) { registrySettings.Service = opts.Service registrySettings.Issuer = opts.Issuer registrySettings.AuthType = registry.SelfToken + registrySettings.TokenTTL = opts.TokenTTL default: return nil, errors.Errorf("registry auth type '%s' not support", opts.AuthType) } diff --git a/app/cmd/cmd_test.go b/app/cmd/cmd_test.go index 05caabe..f8fa174 100644 --- a/app/cmd/cmd_test.go +++ b/app/cmd/cmd_test.go @@ -150,11 +150,11 @@ func Test_createRegistryConnection(t *testing.T) { Htpasswd: ".test_htpasswd", Certs: struct { Path string `long:"path" env:"CERT_PATH" description:"A path to directory where will be stored new self-signed cert,keys and CA files, when 'token' auth type is used" json:"path" yaml:"path"` - Key string `long:"key" env:"KEY_PATH" description:"A path where will be stored new self-signed private key file, when 'token' auth type is used" json:"key"` + Key string `long:"key" env:"KEY_PATH" description:"A path where will be stored new self-signed private key file, when 'token' auth type is used" json:"key" yaml:"key"` PublicKey string `long:"public-key" env:"PUBLIC_KEY_PATH" description:"A path where will be stored new self-signed public key file, when 'token' auth type is used" json:"public_key" yaml:"public_key"` CARoot string `long:"ca-root" env:"CA_ROOT_PATH" description:"A path where will be stored new CA bundles file, when 'token' auth type is used" json:"ca_root" yaml:"ca_root"` FQDNs []string `long:"fqdn" env:"FQDN" env-delim:"," description:"FQDN(s) for registry certificates" json:"fqdns" yaml:"fqdns"` - IP string `long:"ip" env:"IP" description:"Address which appends to certificate SAN (Subject Alternative Name)" json:"ip"` + IP string `long:"ip" env:"IP" description:"Address which appends to certificate SAN (Subject Alternative Name)" json:"ip" yaml:"ip"` HTTPSCert string `long:"https-cert" env:"CERT_HTTPS" description:"A path to HTTPS certificate used for TLS access to registry instance" json:"https_cert" yaml:"https_cert"` }(struct { Path string @@ -162,7 +162,7 @@ func Test_createRegistryConnection(t *testing.T) { PublicKey string CARoot string FQDNs []string `long:"fqdn" env:"FQDN" env-delim:"," description:"FQDN(s) for registry certificates" json:"fqdns" yaml:"fqdns"` - IP string `long:"ip" env:"IP" description:"Address which appends to certificate SAN (Subject Alternative Name)" json:"ip"` + IP string `long:"ip" env:"IP" description:"Address which appends to certificate SAN (Subject Alternative Name)" json:"ip" yaml:"ip"` HTTPSCert string `long:"https-cert" env:"CERT_HTTPS" description:"A path to HTTPS certificate used for TLS access to registry instance" json:"https_cert" yaml:"https_cert"` }{Path: tmpDir + "/", Key: tmpDir + "/test.key", PublicKey: tmpDir + "/test.pub", CARoot: tmpDir + "/test.crt"}), }, diff --git a/app/cmd/options.go b/app/cmd/options.go index 5b9e993..fb2fdb3 100644 --- a/app/cmd/options.go +++ b/app/cmd/options.go @@ -53,7 +53,7 @@ type Options struct { ACMELocation string `long:"acme-location" env:"ACME_LOCATION" description:"dir where certificates will be stored by autocert manager" default:"./acme" json:"acme_location" yaml:"acme_location"` ACMEEmail string `long:"acme-email" env:"ACME_EMAIL" description:"admin email for certificate notifications" json:"acme_email" yaml:"acme_email"` Port int `long:"port" env:"PORT" description:"Main web-service secure SSL port. Default:443" default:"443" json:"port" yaml:"port"` - RedirHTTPPort int `long:"http-port" env:"ACME_HTTP_PORT" description:"http port for redirect to https and acme challenge test (default: 80)" json:"redir_http_port" yaml:"redir_http_port" yaml:"redir_http_port"` + RedirHTTPPort int `long:"http-port" env:"ACME_HTTP_PORT" description:"http port for redirect to https and acme challenge test (default: 80)" json:"redir_http_port" yaml:"redir_http_port"` FQDNs []string `long:"fqdn" env:"ACME_FQDN" env-delim:"," description:"FQDN(s) for ACME certificates" json:"acme_fqdns" yaml:"acme_fqdns"` } `group:"ssl" namespace:"ssl" env-namespace:"RA_SSL" json:"ssl" yaml:"ssl"` @@ -68,7 +68,7 @@ type Options struct { // Type implement as options for add support for different storage type StoreGroup struct { Type string `long:"type" env:"DB_TYPE" description:"type of storage" choice:"embed" default:"embed" json:"type" yaml:"type"` // nolint - AdminPassword string `long:"admin-password" env:"ADMIN_PASSWORD" description:"Define password for default admin user when storage create first" default:"admin" json:"admin_password" yaml:"admin_password" yaml:"admin_password"` + AdminPassword string `long:"admin-password" env:"ADMIN_PASSWORD" description:"Define password for default admin user when storage create first" default:"admin" json:"admin_password" yaml:"admin_password"` Embed struct { Path string `long:"path" env:"DB_PATH" default:"./data.db" description:"Parent directory for the sqlite files" json:"path" yaml:"path"` } `group:"embed" namespace:"embed" env-namespace:"EMBED" json:"embed" yaml:"embed"` @@ -85,6 +85,7 @@ type RegistryGroup struct { InsecureConnection bool `long:"https-insecure" env:"HTTPS_INSECURE" description:"Set https connection to registry insecure" json:"https_insecure" yaml:"https_insecure"` Service string `long:"service" env:"SERVICE" description:"A service name which defined in registry settings" json:"service" yaml:"service"` Issuer string `long:"issuer" env:"ISSUER" description:"A token issuer name which defined in registry settings" json:"issuer" yaml:"issuer"` + TokenTTL int64 `long:"token-ttl" env:"TOKEN_TTL" description:"Define registry auth token TTL (in second). Default value 60 seconds." json:"token_ttl" yaml:"token_ttl"` GarbageCollectorInterval int64 `long:"gc-interval" env:"GC_INTERVAL" description:"Use for define custom time interval for garbage collector execute (minutes), default 1 hours" json:"gc_interval" yaml:"gc_interval"` Certs struct { Path string `long:"path" env:"CERT_PATH" description:"A path to directory where will be stored new self-signed cert,keys and CA files, when 'token' auth type is used" json:"path" yaml:"path"` @@ -94,7 +95,7 @@ type RegistryGroup struct { FQDNs []string `long:"fqdn" env:"FQDN" env-delim:"," description:"FQDN(s) for registry certificates" json:"fqdns" yaml:"fqdns"` IP string `long:"ip" env:"IP" description:"Address which appends to certificate SAN (Subject Alternative Name)" json:"ip" yaml:"ip"` HTTPSCert string `long:"https-cert" env:"CERT_HTTPS" description:"A path to HTTPS certificate used for TLS access to registry instance" json:"https_cert" yaml:"https_cert"` - } `group:"certs" namespace:"certs" env-namespace:"CERTS" json:"certs"` + } `group:"certs" namespace:"certs" env-namespace:"CERTS" json:"certs" yaml:"certs"` } // ParseArgs calls flag parser for passing set of extra options defined for all commands diff --git a/app/registry/registry.go b/app/registry/registry.go index f97465c..8ec6f8f 100644 --- a/app/registry/registry.go +++ b/app/registry/registry.go @@ -79,6 +79,9 @@ type Settings struct { // The name of the token issuer which hosts the resource. Issuer string + // Override default token expiration time (in seconds), default 60 seconds + TokenTTL int64 + // CertificatesPaths define a path to private, public keys and CA certificate. // If CertificatesPaths has all fields are empty, AccessToken will create keys by default, with default path. // If CertificatesPaths has all fields are empty, but certificates files exist AccessToken try to load existed keys and CA file. @@ -202,14 +205,17 @@ func NewRegistry(login, password string, settings Settings) (*Registry, error) { if r.settings.AuthType == SelfToken { + if settings.TokenTTL == 0 { + settings.TokenTTL = defaultTokenExpiration + } r.htpasswd = nil // not needed for token auth var err error if certsPathIsFilled { - if r.registryToken, err = NewRegistryToken(TokenIssuer(settings.Issuer), CertsName(settings.CertificatesPaths)); err != nil { + if r.registryToken, err = NewRegistryToken(TokenIssuer(settings.Issuer), CertsName(settings.CertificatesPaths), TokenExpiration(settings.TokenTTL)); err != nil { return nil, err } } else { - r.registryToken, err = NewRegistryToken(TokenIssuer(settings.Issuer)) + r.registryToken, err = NewRegistryToken(TokenIssuer(settings.Issuer), TokenExpiration(settings.TokenTTL)) if err != nil { return nil, err }