From 9ea856640af398309b79cd9f1ebe8c4f025e2c62 Mon Sep 17 00:00:00 2001 From: Christian Breunig Date: Fri, 10 Mar 2023 20:41:18 +0100 Subject: schema: T5079: extension to support defaultValues on tagNodes (cherry picked from commit b4af532dd531c23bc1ad84cca290916be55357bf) --- schema/interface_definition.rnc | 2 +- schema/interface_definition.rng | 15 +++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/schema/interface_definition.rnc b/schema/interface_definition.rnc index 192a70024..dd9c6abcf 100644 --- a/schema/interface_definition.rnc +++ b/schema/interface_definition.rnc @@ -43,7 +43,7 @@ node = element node tagNode = element tagNode { (ownerAttr? & nodeNameAttr), - (properties? & children ) + (defaultValue? & properties? & children ) } # Leaf nodes are terminal configuration nodes that can't have children, diff --git a/schema/interface_definition.rng b/schema/interface_definition.rng index 1ed18f456..282664ce8 100644 --- a/schema/interface_definition.rng +++ b/schema/interface_definition.rng @@ -2,19 +2,19 @@ -- cgit v1.2.3 From df58e083979a40df8c1a1391b82b2e4d856225dd Mon Sep 17 00:00:00 2001 From: Christian Breunig Date: Sat, 1 Apr 2023 15:43:11 +0200 Subject: container: T4959: add registry authentication option Container registry CLI node changed from leafNode to tagNode with the same defaults. In addition we can now configure an authentication option per registry. (cherry picked from commit fe82d86d3e87cb8d92ebc9d0652c08e3dd79a12c) --- data/templates/container/registries.conf.j2 | 6 +++- interface-definitions/container.xml.in | 11 ++++--- .../include/generic-password.xml.i | 15 +++++++++ .../include/generic-username.xml.i | 15 +++++++++ src/conf_mode/container.py | 38 +++++++++++++++++++++- 5 files changed, 79 insertions(+), 6 deletions(-) create mode 100644 interface-definitions/include/generic-password.xml.i create mode 100644 interface-definitions/include/generic-username.xml.i diff --git a/data/templates/container/registries.conf.j2 b/data/templates/container/registries.conf.j2 index c583e0ad5..0e3ad6ba6 100644 --- a/data/templates/container/registries.conf.j2 +++ b/data/templates/container/registries.conf.j2 @@ -23,5 +23,9 @@ # unqualified-search-registries = ["example.com"] {% if registry is defined and registry is not none %} -unqualified-search-registries = {{ registry }} +{% set registry_list = [] %} +{% for r, r_options in registry.items() if r_options.disable is not defined %} +{% set _ = registry_list.append(r) %} +{% endfor %} +unqualified-search-registries = {{ registry_list }} {% endif %} diff --git a/interface-definitions/container.xml.in b/interface-definitions/container.xml.in index 91fb4dba0..f092ad9bb 100644 --- a/interface-definitions/container.xml.in +++ b/interface-definitions/container.xml.in @@ -368,13 +368,16 @@ - + - Registry Name (default: docker.io, quay.io) - + Registry Name docker.io quay.io - + + #include + #include + + diff --git a/interface-definitions/include/generic-password.xml.i b/interface-definitions/include/generic-password.xml.i new file mode 100644 index 000000000..76d5f12d8 --- /dev/null +++ b/interface-definitions/include/generic-password.xml.i @@ -0,0 +1,15 @@ + + + + Password used for authentication + + txt + Password + + + [[:ascii:]]{1,128} + + Password is limited to ASCII characters only, with a total length of 128 + + + diff --git a/interface-definitions/include/generic-username.xml.i b/interface-definitions/include/generic-username.xml.i new file mode 100644 index 000000000..678f30ddf --- /dev/null +++ b/interface-definitions/include/generic-username.xml.i @@ -0,0 +1,15 @@ + + + + Username used for authentication + + txt + Username + + + [[:ascii:]]{1,128} + + Username is limited to ASCII characters only, with a total length of 128 + + + diff --git a/src/conf_mode/container.py b/src/conf_mode/container.py index 50c3424d2..2d7f03e7f 100755 --- a/src/conf_mode/container.py +++ b/src/conf_mode/container.py @@ -18,7 +18,6 @@ import os from ipaddress import ip_address from ipaddress import ip_network -from time import sleep from json import dumps as json_write from vyos.base import Warning @@ -30,6 +29,7 @@ from vyos.util import call from vyos.util import cmd from vyos.util import dict_search from vyos.util import run +from vyos.util import rc_cmd from vyos.util import write_file from vyos.template import inc_ip from vyos.template import is_ipv4 @@ -70,6 +70,9 @@ def get_config(config=None): # container base default values can not be merged here - remove and add them later if 'name' in default_values: del default_values['name'] + # registry will be handled below + if 'registry' in default_values: + del default_values['registry'] container = dict_merge(default_values, container) # Merge per-container default values @@ -106,6 +109,15 @@ def get_config(config=None): container['name'][name]['volume'][volume] = dict_merge( default_values_volume, container['name'][name]['volume'][volume]) + # registry is a tagNode with default values - merge the list from + # default_values['registry'] into the tagNode variables + if 'registry' not in container: + container.update({'registry' : {}}) + default_values = defaults(base) + for registry in default_values['registry'].split(): + tmp = {registry : {}} + container['registry'] = dict_merge(tmp, container['registry']) + # Delete container network, delete containers tmp = node_changed(conf, base + ['network']) if tmp: container.update({'network_remove' : tmp}) @@ -237,6 +249,13 @@ def verify(container): if 'network' in container_config and network in container_config['network']: raise ConfigError(f'Can not remove network "{network}", used by container "{container}"!') + if 'registry' in container: + for registry, registry_config in container['registry'].items(): + if 'authentication' in registry_config: + if ('user' not in registry_config and 'password' in registry_config) or \ + ('user' in registry_config and 'password' not in registry_config): + raise ConfigError('If registry username or password is defined, so must be the other!') + return None def generate_run_arguments(name, container_config): @@ -366,6 +385,23 @@ def generate(container): write_file(f'/etc/cni/net.d/{network}.conflist', json_write(tmp, indent=2)) + if 'registry' in container: + cmd = f'podman logout --all' + rc, out = rc_cmd(cmd) + if rc != 0: + raise ConfigError(out) + + for registry, registry_config in container['registry'].items(): + if 'disable' in registry_config: + continue + if 'authentication' in registry_config: + username = registry_config['authentication']['user'] + password = registry_config['authentication']['password'] + cmd = f'podman login --username {username} --password {password} {registry}' + rc, out = rc_cmd(cmd) + if rc != 0: + raise ConfigError(out) + render(config_containers_registry, 'container/registries.conf.j2', container) render(config_containers_storage, 'container/storage.conf.j2', container) -- cgit v1.2.3