diff --git a/.zuul.yaml b/.zuul.yaml index ab212200..f4a395fd 100644 --- a/.zuul.yaml +++ b/.zuul.yaml @@ -104,6 +104,8 @@ CLONE_ARMADA: false MAKE_ARMADA_IMAGES: true USE_ARMADA_GO: false + DISTRO: ubuntu_jammy + DOCKER_REGISTRY: localhost:5000 gate_scripts_relative_path: ../../airship/treasuremap - job: diff --git a/armada/api/server.py b/armada/api/server.py index d11f4aaf..deb6de60 100644 --- a/armada/api/server.py +++ b/armada/api/server.py @@ -33,16 +33,17 @@ from armada.api.controller.validation import Validate from armada.api.controller.versions import Versions from armada.exceptions import base_exception as exceptions -conf.set_app_default_configs() CONF = cfg.CONF -def create(enable_middleware=CONF.middleware): +def create(enable_middleware=None): """Entry point for initializing Armada server. :param enable_middleware: Whether to enable middleware. :type enable_middleware: bool """ + if enable_middleware is None: + enable_middleware = getattr(CONF, "middleware", True) if enable_middleware: api = falcon.App( @@ -76,9 +77,6 @@ def create(enable_middleware=CONF.middleware): api.add_route("/api/v1.0/{}".format(route), service) api.add_route('/versions', Versions()) - # Initialize policy config options. - policy.Enforcer(CONF) - # Error handlers (FILO handling) api.add_error_handler(Exception, exceptions.default_exception_handler) api.add_error_handler( @@ -90,11 +88,29 @@ def create(enable_middleware=CONF.middleware): return api -def paste_start_armada(global_conf, **kwargs): - # At this time just ignore everything in the paste configuration - # and rely on olso_config +def paste_start_armada(global_conf, **local_conf): + # Initialize configuration + conf.set_app_default_configs() + # Ensure CONF is initialized before using it + if not CONF.config_file: + raise RuntimeError( + "Configuration files are not loaded. " + " Ensure 'armada.conf' is accessible.") + + # Create and return the API + api = create() return api -api = create() +if __name__ == "__main__": + conf.set_app_default_configs() + + # Ensure CONF is initialized before using it + if not CONF.config_file: + raise RuntimeError( + "Configuration files are not loaded. " + "Ensure 'armada.conf' is accessible.") + + enforcer = policy.Enforcer(CONF) + api = create() diff --git a/armada/tests/unit/api/base.py b/armada/tests/unit/api/base.py index 56400972..37f8149d 100644 --- a/armada/tests/unit/api/base.py +++ b/armada/tests/unit/api/base.py @@ -16,6 +16,7 @@ import os from falcon import testing as falcon_testing import mock +from oslo_config import cfg from armada.api import server import armada.conf @@ -27,6 +28,8 @@ class BaseControllerTest(test_base.ArmadaTestCase): """Base class for unit testing falcon controllers.""" def setUp(self): super(BaseControllerTest, self).setUp() + # Initialize oslo_config parser + cfg.CONF([], project='armada', default_config_files=[]) # Override the default configuration file lookup with references to # the sample configuration files to avoid oslo.conf errors when # creating the server below. diff --git a/etc/armada/armada.conf.sample b/etc/armada/armada.conf.sample index fc983069..1516c0f8 100644 --- a/etc/armada/armada.conf.sample +++ b/etc/armada/armada.conf.sample @@ -95,11 +95,15 @@ # Deprecated group/name - [DEFAULT]/logdir #log_dir = -# Uses logging handler designed to watch file system. When log file is moved or -# removed this handler will open a new log file with specified path +# DEPRECATED: Uses logging handler designed to watch file system. When log file +# is moved or removed this handler will open a new log file with specified path # instantaneously. It makes sense only if log_file option is specified and # Linux platform is used. This option is ignored if log_config_append is set. # (boolean value) +# This option is deprecated for removal. +# Its value may be silently ignored in the future. +# Reason: This function is known to have bene broken for long time, and depends +# on the unmaintained library #watch_log_file = false # Use syslog for logging. Existing syslog format is DEPRECATED and will be @@ -125,8 +129,10 @@ # set. (boolean value) #use_stderr = false -# Log output to Windows Event Log. (boolean value) -#use_eventlog = false +# (Optional) Set the 'color' key according to log levels. This option takes +# effect only when logging to stderr or stdout is used. This option is ignored +# if log_config_append is set. (boolean value) +#log_color = false # The amount of time before the log files are rotated. This option is ignored # unless log_rotation_type is set to "interval". (integer value) @@ -200,10 +206,16 @@ # Maximum number of logged messages per rate_limit_interval. (integer value) #rate_limit_burst = 0 -# Log level name used by rate limiting: CRITICAL, ERROR, INFO, WARNING, DEBUG -# or empty string. Logs with level greater or equal to rate_limit_except_level -# are not filtered. An empty string means that all levels are filtered. (string -# value) +# Log level name used by rate limiting. Logs with level greater or equal to +# rate_limit_except_level are not filtered. An empty string means that all +# levels are filtered. (string value) +# Possible values: +# CRITICAL - +# ERROR - +# INFO - +# WARNING - +# DEBUG - +# '' - #rate_limit_except_level = CRITICAL # Enables or disables fatal status of deprecations. (boolean value) @@ -260,6 +272,14 @@ # information back as part of a request. (list value) #backends = +# A list of network addresses to limit source ip allowed to access healthcheck +# information. Any request from ip outside of these network addresses are +# ignored. (list value) +#allowed_source_ranges = + +# Ignore requests with proxy headers. (boolean value) +#ignore_proxied_requests = false + # Check the presence of a file to determine if an application is running on a # port. Used by DisableByFileHealthcheck plugin. (string value) #disable_by_file_path = @@ -269,6 +289,10 @@ # DisableByFilesPortsHealthcheck plugin. (list value) #disable_by_file_paths = +# Check the presence of files. Used by EnableByFilesHealthcheck plugin. (list +# value) +#enable_by_file_paths = + [keystone_authtoken] @@ -342,14 +366,14 @@ # (string value) #default_domain_name = -# User ID (string value) +# User's user ID (string value) #user_id = -# Username (string value) +# User's username (string value) # Deprecated group/name - [keystone_authtoken]/user_name #username = -# User's domain id (string value) +# User's domain ID (string value) #user_domain_id = # User's domain name (string value) @@ -510,6 +534,16 @@ # used to validate tokens that have restricted access rules. (string value) #service_type = +# Enable the SASL(Simple Authentication and Security Layer) if the SASL_enable +# is true, else disable. (boolean value) +#memcache_sasl_enabled = false + +# the user name for the SASL (string value) +#memcache_username = + +# the username password for SASL (string value) +#memcache_password = + # Authentication type to load (string value) # Deprecated group/name - [keystone_authtoken]/auth_plugin #auth_type = @@ -529,13 +563,6 @@ # Deprecated group/name - [DEFAULT]/max_request_body_size #max_request_body_size = 114688 -# DEPRECATED: The HTTP Header that will be used to determine what the original -# request protocol scheme was, even if it was hidden by a SSL termination -# proxy. (string value) -# This option is deprecated for removal. -# Its value may be silently ignored in the future. -#secure_proxy_ssl_header = X-Forwarded-Proto - # Whether the application is behind a proxy or not. This determines if the # middleware should parse the headers or not. (boolean value) #enable_proxy_headers_parsing = false @@ -550,13 +577,18 @@ # From oslo.policy # -# This option controls whether or not to enforce scope when evaluating -# policies. If ``True``, the scope of the token used in the request is compared -# to the ``scope_types`` of the policy being enforced. If the scopes do not -# match, an ``InvalidScope`` exception will be raised. If ``False``, a message -# will be logged informing operators that policies are being invoked with -# mismatching scope. (boolean value) -#enforce_scope = false +# DEPRECATED: This option controls whether or not to enforce scope when +# evaluating policies. If ``True``, the scope of the token used in the request +# is compared to the ``scope_types`` of the policy being enforced. If the +# scopes do not match, an ``InvalidScope`` exception will be raised. If +# ``False``, a message will be logged informing operators that policies are +# being invoked with mismatching scope. (boolean value) +# This option is deprecated for removal. +# Its value may be silently ignored in the future. +# Reason: This configuration was added temporarily to facilitate a smooth +# transition to the new RBAC. OpenStack will always enforce scope checks. This +# configuration option is deprecated and will be removed in the 2025.2 cycle. +#enforce_scope = true # This option controls whether or not to use old deprecated defaults when # evaluating policies. If ``True``, the old deprecated defaults are not going @@ -567,12 +599,12 @@ # deprecated policy check string is logically OR'd with the new policy check # string, allowing for a graceful upgrade experience between releases with new # policies, which is the default behavior. (boolean value) -#enforce_new_defaults = false +#enforce_new_defaults = true # The relative or absolute path of a file that maps roles to permissions for a # given service. Relative paths must be specified in relation to the # configuration file setting this option. (string value) -#policy_file = policy.json +#policy_file = policy.yaml # Default rule. Enforced when a requested rule is not found. (string value) #policy_default_rule = default @@ -602,3 +634,7 @@ # Absolute path client key file REST based policy check (string value) #remote_ssl_client_key_file = + +# Timeout in seconds for REST based policy check (floating point value) +# Minimum value: 0 +#remote_timeout = 60 diff --git a/images/armada/Dockerfile.ubuntu_jammy b/images/armada/Dockerfile.ubuntu_jammy index 082d199b..b34a40ff 100644 --- a/images/armada/Dockerfile.ubuntu_jammy +++ b/images/armada/Dockerfile.ubuntu_jammy @@ -89,7 +89,7 @@ COPY . ./ COPY --from=armada_go /usr/local/bin/armada /usr/local/bin/armada-go # Setting the version explicitly for PBR -ENV PBR_VERSION=0.8.0 +ENV PBR_VERSION=6.1.1 RUN \ chown -R armada:users . && \ diff --git a/requirements-direct.txt b/requirements-direct.txt index 13ea0a5c..99de34a9 100644 --- a/requirements-direct.txt +++ b/requirements-direct.txt @@ -21,29 +21,29 @@ testtools urllib3 uWSGI -# Openstack Caracal 2024.1 -# https://releases.openstack.org/caracal/index.html -barbican==18.0.0 +# Openstack Epoxy 2025.1 +# https://releases.openstack.org/epoxy/index.html +barbican==20.0.0 -python-barbicanclient==5.7.0 -python-keystoneclient==5.4.0 +python-barbicanclient==7.1.0 +python-keystoneclient==5.6.0 -keystoneauth1==5.6.0 -keystonemiddleware==10.6.0 +keystoneauth1==5.10.0 +keystonemiddleware==10.9.0 -oslo.cache==3.7.0 -oslo.concurrency==6.0.0 -oslo.config==9.4.0 -oslo.context==5.5.0 -oslo.db==15.0.0 -oslo.i18n==6.3.0 -oslo.log==5.5.1 -oslo.messaging==14.7.2 -oslo.metrics==0.8.0 -oslo.middleware==6.1.0 -oslo.policy==4.3.0 -oslo.serialization==5.4.1 -oslo.service==3.4.1 -oslo.upgradecheck==2.3.0 -oslo.utils==7.1.0 -oslo.versionedobjects==3.3.0 \ No newline at end of file +oslo.cache==3.10.2 +oslo.concurrency==7.1.0 +oslo.config==9.7.1 +oslo.context==5.7.1 +oslo.db==17.2.1 +oslo.i18n==6.5.1 +oslo.log==7.1.0 +oslo.messaging==16.1.0 +oslo.metrics==0.11.0 +oslo.middleware==6.3.1 +oslo.policy==4.5.1 +oslo.serialization==5.7.0 +oslo.service==4.1.1 +oslo.upgradecheck==2.5.0 +oslo.utils==8.2.0 +oslo.versionedobjects==3.6.0 \ No newline at end of file diff --git a/requirements-frozen.txt b/requirements-frozen.txt index 80aa371c..eaa386f2 100644 --- a/requirements-frozen.txt +++ b/requirements-frozen.txt @@ -2,27 +2,27 @@ alembic==1.16.1 amqp==5.3.1 attrs==25.3.0 autopage==0.5.2 -barbican==18.0.0 +barbican==20.0.0 bcrypt==4.3.0 cachetools==5.5.2 -castellan==5.3.0 +castellan==5.4.1 certifi==2025.4.26 cffi==1.17.1 charset-normalizer==3.4.2 click==8.2.1 -cliff==4.10.0 -cmd2==2.6.1 +cliff==4.11.0 +cmd2==2.7.0 cryptography==42.0.8 debtcollector==3.0.0 decorator==5.2.1 -deepdiff==8.5.0 +deepdiff==8.6.1 dnspython==2.7.0 -dogpile.cache==1.4.0 +dogpile.cache==1.4.1 durationpy==0.10 eventlet==0.40.0 -falcon==4.0.2 +falcon==4.1.0 fasteners==0.19 -futurist==3.1.1 +futurist==3.2.1 gitdb==4.0.12 GitPython==3.1.44 google-auth==2.40.2 @@ -32,58 +32,60 @@ iso8601==2.1.0 Jinja2==3.1.6 jsonschema==4.24.0 jsonschema-specifications==2025.4.1 -keystoneauth1==5.6.0 -keystonemiddleware==10.6.0 +keystoneauth1==5.10.0 +keystonemiddleware==10.9.0 kombu==5.5.4 kubernetes==31.0.0 ldap3==2.9.1 Mako==1.3.10 +markdown-it-py==3.0.0 MarkupSafe==3.0.2 +mdurl==0.1.2 microversion-parse==2.0.0 mock==5.2.0 msgpack==1.1.0 netaddr==1.3.0 -netifaces==0.11.0 oauthlib==3.2.2 -orderly-set==5.4.1 -os-service-types==1.7.0 -oslo.cache==3.7.0 -oslo.concurrency==6.0.0 -oslo.config==9.4.0 -oslo.context==5.5.0 -oslo.db==15.0.0 -oslo.i18n==6.3.0 -oslo.log==5.5.1 -oslo.messaging==14.7.2 -oslo.metrics==0.8.0 -oslo.middleware==6.1.0 -oslo.policy==4.3.0 -oslo.serialization==5.4.1 -oslo.service==3.4.1 -oslo.upgradecheck==2.3.0 -oslo.utils==7.1.0 -oslo.versionedobjects==3.3.0 +orderly-set==5.5.0 +os-service-types==1.8.0 +oslo.cache==3.10.2 +oslo.concurrency==7.1.0 +oslo.config==9.7.1 +oslo.context==5.7.1 +oslo.db==17.2.1 +oslo.i18n==6.5.1 +oslo.log==7.1.0 +oslo.messaging==16.1.0 +oslo.metrics==0.11.0 +oslo.middleware==6.3.1 +oslo.policy==4.5.1 +oslo.serialization==5.7.0 +oslo.service==4.1.1 +oslo.upgradecheck==2.5.0 +oslo.utils==8.2.0 +oslo.versionedobjects==3.6.0 packaging==25.0 Paste==3.10.1 PasteDeploy==3.1.0 pbr==6.1.1 -pecan==1.6.0 +pecan==1.7.0 pip==24.3.1 prettytable==3.16.0 prometheus_client==0.22.1 +psutil==7.0.0 py==1.11.0 pyasn1==0.6.1 pyasn1_modules==0.4.1 pycadf==4.0.1 pycparser==2.22 +Pygments==2.19.1 PyJWT==2.10.1 pylibyaml==0.1.0 -pyOpenSSL==25.1.0 pyparsing==3.2.3 -pyperclip==1.9.0 -python-barbicanclient==5.7.0 +pyperclip==1.10.0 +python-barbicanclient==7.1.0 python-dateutil==2.9.0.post0 -python-keystoneclient==5.4.0 +python-keystoneclient==5.6.0 python-memcached==1.62 PyYAML==6.0.2 referencing==0.36.2 @@ -93,6 +95,8 @@ requests-oauthlib==2.0.0 responses==0.25.7 retry==0.9.2 rfc3986==2.0.0 +rich==13.9.4 +rich-argparse==1.7.1 Routes==2.5.1 rpds-py==0.25.1 rsa==4.9.1 @@ -101,7 +105,7 @@ six==1.17.0 smmap==5.0.2 SQLAlchemy==1.4.54 statsd==4.0.1 -stevedore==5.4.1 +stevedore==5.5.0 testresources==2.0.2 testscenarios==0.5.0 testtools==2.7.2 diff --git a/setup.cfg b/setup.cfg index dfecd2e6..5b4f4f0a 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,5 +1,5 @@ [metadata] -name = Armada +name = armada version = 1.1 summary = Tool for managing multiple Helm charts with dependencies by centralizing all configurations in a single Armada YAML and providing life-cycle hooks for all Helm releases. description_file = README.rst diff --git a/tools/armada_image_run.sh b/tools/armada_image_run.sh index 1e28cf3b..11d59fee 100755 --- a/tools/armada_image_run.sh +++ b/tools/armada_image_run.sh @@ -23,6 +23,7 @@ function generate_conf { tox -e genpolicy > /dev/null ETCDIR=$(mktemp -d)/armada mkdir -p ${ETCDIR} > /dev/null + cp etc/armada/armada.conf.sample ${ETCDIR}/armada.conf cp etc/armada/api-paste.ini ${ETCDIR}/api-paste.ini cp etc/armada/policy.yaml.sample ${ETCDIR}/policy.yaml echo ${ETCDIR} @@ -30,6 +31,9 @@ function generate_conf { function test_armada { TMPETC=$1 + # Remove all containers with names starting with armada_test + docker ps -a --filter "name=^/armada_test" --format "{{.ID}}" | xargs -r docker rm -f + docker run \ -d --name "${ARMADA_CONTAINER_NAME}" --net host \ -v ${TMPETC}:/etc/armada \ @@ -37,7 +41,7 @@ function test_armada { sleep 10 - RESULT=$(curl --noproxy '*' -i 'http://127.0.0.1:8000/api/v1.0/health' | tr '\r' '\n' | head -1) + RESULT=$(curl --noproxy '*' -i 'http://127.0.0.1:8000/api/v1.0/health' 2>/dev/null | tr '\r' '\n' | head -1) GOOD="HTTP/1.1 204 No Content" if [[ "${RESULT}" != "${GOOD}" ]]; then if docker exec -t ${CONTAINER_NAME} /bin/bash -c "curl -i 'http://127.0.0.1:8000/api/v1.0/health' --noproxy '*' | tr '\r' '\n' | head -1 "; then