diff --git a/core/app/services/uffizzi_core/compose_file/config_option_service.rb b/core/app/services/uffizzi_core/compose_file/config_option_service.rb index a18f62fa..39b46002 100644 --- a/core/app/services/uffizzi_core/compose_file/config_option_service.rb +++ b/core/app/services/uffizzi_core/compose_file/config_option_service.rb @@ -12,6 +12,10 @@ def valid_option_format?(option) def config_options(compose_data) compose_data.each_with_object([]) do |(key, value), keys| + if compose_data.equal?(value) + raise UffizziCore::ComposeFile::ParseError, I18n.t('compose.infinite_recursion', key: key) + end + keys << key keys.concat(config_options(value)) if value.is_a?(Hash) end diff --git a/core/app/services/uffizzi_core/compose_file_service.rb b/core/app/services/uffizzi_core/compose_file_service.rb index 41db77f5..6dee6c1b 100644 --- a/core/app/services/uffizzi_core/compose_file_service.rb +++ b/core/app/services/uffizzi_core/compose_file_service.rb @@ -158,7 +158,7 @@ def persist!(compose_file_form, cli_form) def load_compose_data(compose_content) begin - compose_data = YAML.safe_load(compose_content) + compose_data = YAML.safe_load(compose_content, aliases: true) rescue Psych::SyntaxError raise UffizziCore::ComposeFile::ParseError, 'Invalid compose file' end diff --git a/core/config/locales/en.yml b/core/config/locales/en.yml index 0430a74e..6074f4c0 100644 --- a/core/config/locales/en.yml +++ b/core/config/locales/en.yml @@ -59,6 +59,7 @@ en: invalid_healthcheck_command: "Service '%{name}' defines an invalid healthcheck: when 'test' is a list the first item must be either NONE, CMD or CMD-SHELL" string_or_array_error: "'%{option}' contains an invalid type, it should be a string, or an array" not_implemented: "'%{option}' option is not implemented" + infinite_recursion: "Found infinite recursion for key '%{key}'" secrets: duplicates_exists: Secret with key %{secrets} already exist. invalid_key_length: A secret key must be no longer than 256 characters. diff --git a/core/test/controllers/uffizzi_core/api/cli/v1/projects/compose_files_controller_test.rb b/core/test/controllers/uffizzi_core/api/cli/v1/projects/compose_files_controller_test.rb index cdc78c0d..c4ef9a30 100644 --- a/core/test/controllers/uffizzi_core/api/cli/v1/projects/compose_files_controller_test.rb +++ b/core/test/controllers/uffizzi_core/api/cli/v1/projects/compose_files_controller_test.rb @@ -175,4 +175,37 @@ class UffizziCore::Api::Cli::V1::Projects::ComposeFilesControllerTest < ActionCo assert_response :not_found end + + test '#create - with yaml aliases' do + sign_in @admin + + @compose_file.destroy! + create(:credential, :docker_hub, :active, account: @account) + base_attributes = attributes_for(:compose_file).slice(:source, :path) + file_content = File.read('test/fixtures/files/uffizzi-compose-with_alias.yml') + encoded_content = Base64.encode64(file_content) + compose_file_attributes = base_attributes.merge(content: encoded_content, repository_id: nil) + dependency = { + path: 'configs/vote.conf', + source: 'vote.conf', + content: json_fixture('files/compose_dependencies/configs/vote_conf.json')[:content], + } + + params = { + project_slug: @project.slug, + compose_file: compose_file_attributes, + dependencies: [dependency], + } + + differences = { + -> { UffizziCore::ComposeFile.main.count } => 1, + -> { UffizziCore::Template.with_creation_source(UffizziCore::Template.creation_source.compose_file).count } => 1, + } + + assert_difference differences do + post :create, params: params, format: :json + end + + assert_response :success + end end diff --git a/core/test/fixtures/files/uffizzi-compose-with_alias.yml b/core/test/fixtures/files/uffizzi-compose-with_alias.yml new file mode 100644 index 00000000..673711cf --- /dev/null +++ b/core/test/fixtures/files/uffizzi-compose-with_alias.yml @@ -0,0 +1,25 @@ +x-nginx-configs: &nginx-configs + - source: vote_conf + target: /etc/nginx/conf.d + +x-srv-nginx: &srv-nginx + nginx: + image: nginx:latest + configs: *nginx-configs + entrypoint: /usr/sbin/nginx-debug + command: + - "-g" + - "daemon off;" + +services: + <<: *srv-nginx + +x-uffizzi-ingress: + service: nginx + port: 8080 + +configs: + vote_conf: + file: configs/vote.conf + defaulf_conf: + file: config_files/config_file.conf