From 3ccdae4238f412447ae447889a1ee1baf49266bc Mon Sep 17 00:00:00 2001 From: Pedro Brochado Date: Wed, 17 Sep 2025 15:17:33 -0300 Subject: [PATCH 1/3] Test upgrading to 7.14 --- gen-client.sh | 2 +- templates/ruby/v7.14.0/api_client.mustache | 247 +++++++++++++++++++++ templates/ruby/v7.14.0/gemspec.mustache | 42 ++++ 3 files changed, 290 insertions(+), 1 deletion(-) create mode 100644 templates/ruby/v7.14.0/api_client.mustache create mode 100644 templates/ruby/v7.14.0/gemspec.mustache diff --git a/gen-client.sh b/gen-client.sh index 6ff3c87..0183f0a 100755 --- a/gen-client.sh +++ b/gen-client.sh @@ -68,7 +68,7 @@ if language.lower() == "python": print("v4.3.1") elif language.lower() == "ruby": if core_version >= Version("3.70.dev"): - print("v7.10.0") + print("v7.14.0") else: print("v4.3.1") elif language.lower() == "typescript": diff --git a/templates/ruby/v7.14.0/api_client.mustache b/templates/ruby/v7.14.0/api_client.mustache new file mode 100644 index 0000000..ac21747 --- /dev/null +++ b/templates/ruby/v7.14.0/api_client.mustache @@ -0,0 +1,247 @@ +=begin +{{> api_info}} +=end + +require 'date' +require 'json' +require 'logger' +require 'tempfile' +require 'time' +{{#isTyphoeus}} +require 'typhoeus' +{{/isTyphoeus}} +{{#isFaraday}} +require 'faraday' +require 'faraday/multipart' if Gem::Version.new(Faraday::VERSION) >= Gem::Version.new('2.0') +require 'marcel' +{{/isFaraday}} +{{#isHttpx}} +require 'httpx' +require 'net/http/status' +{{/isHttpx}} +require 'pathname' + + +module {{moduleName}} + class ApiClient + # The Configuration object holding settings to be used in the API client. + attr_accessor :config + + # Defines the headers to be used in HTTP requests of all API calls by default. + # + # @return [Hash] + attr_accessor :default_headers + + # Initializes the ApiClient + # @option config [Configuration] Configuration for initializing the object, default to Configuration.default + def initialize(config = Configuration.default) + @config = config + @user_agent = "{{{httpUserAgent}}}{{^httpUserAgent}}OpenAPI-Generator/#{VERSION}/ruby{{/httpUserAgent}}" + @default_headers = { + 'Content-Type' => 'application/json', + 'User-Agent' => @user_agent + } + end + + def self.default + @@default ||= ApiClient.new + end + +{{#isTyphoeus}} +{{> api_client_typhoeus_partial}} +{{/isTyphoeus}} +{{#isFaraday}} +{{> api_client_faraday_partial}} +{{/isFaraday}} +{{#isHttpx}} +{{> api_client_httpx_partial}} +{{/isHttpx}} + # Check if the given MIME is a JSON MIME. + # JSON MIME examples: + # application/json + # application/json; charset=UTF8 + # APPLICATION/JSON + # */* + # @param [String] mime MIME + # @return [Boolean] True if the MIME is application/json + def json_mime?(mime) + (mime == '*/*') || !(mime =~ /^Application\/.*json(?!p)(;.*)?/i).nil? + end + + # Deserialize the response to the given return type. + # + # @param [Response] response HTTP response + # @param [String] return_type some examples: "User", "Array", "Hash" + def deserialize(response, return_type) + body = response.body + return nil if body.nil? || body.empty? + + # return response body directly for String return type + return body.to_s if return_type == 'String' + + # ensuring a default content type + content_type = response.headers['Content-Type'] || 'application/json' + + fail "Content-Type is not supported: #{content_type}" unless json_mime?(content_type) + + begin + data = JSON.parse("[#{body}]", :symbolize_names => true)[0] + rescue JSON::ParserError => e + if %w(String Date Time).include?(return_type) + data = body + else + raise e + end + end + + convert_to_type data, return_type + end + + # Convert data to the given return type. + # @param [Object] data Data to be converted + # @param [String] return_type Return type + # @return [Mixed] Data in a particular type + def convert_to_type(data, return_type) + return nil if data.nil? + case return_type + when 'String' + data.to_s + when 'Integer' + data.to_i + when 'Float' + data.to_f + when 'Boolean' + data == true + when 'Time' + # parse date time (expecting ISO 8601 format) + Time.parse data + when 'Date' + # parse date time (expecting ISO 8601 format) + Date.parse data + when 'Object' + # generic object (usually a Hash), return directly + data + when /\AArray<(.+)>\z/ + # e.g. Array + sub_type = $1 + data.map { |item| convert_to_type(item, sub_type) } + when /\AHash\\z/ + # e.g. Hash + sub_type = $1 + {}.tap do |hash| + data.each { |k, v| hash[k] = convert_to_type(v, sub_type) } + end + else + # models (e.g. Pet) or oneOf + klass = {{moduleName}}.const_get(return_type) + klass.respond_to?(:openapi_one_of) ? klass.build(data) : klass.build_from_hash(data) + end + end + + # Sanitize filename by removing path. + # e.g. ../../sun.gif becomes sun.gif + # + # @param [String] filename the filename to be sanitized + # @return [String] the sanitized filename + def sanitize_filename(filename) + filename.split(/[\/\\]/).last + end + + def build_request_url(path, opts = {}) + # Add leading and trailing slashes to path + path = "/#{path}".gsub(/\/+/, '/') + @config.base_url(opts[:operation]) + path + end + + # Update header and query params based on authentication settings. + # + # @param [Hash] header_params Header parameters + # @param [Hash] query_params Query parameters + # @param [String] auth_names Authentication scheme name + def update_params_for_auth!(header_params, query_params, auth_names) + Array(auth_names).each do |auth_name| + auth_setting = @config.auth_settings[auth_name] + next unless auth_setting + case auth_setting[:in] + when 'header' then header_params[auth_setting[:key]] = auth_setting[:value] + when 'query' then query_params[auth_setting[:key]] = auth_setting[:value] + else fail ArgumentError, 'Authentication token must be in `query` or `header`' + end + end + end + + # Sets user agent in HTTP header + # + # @param [String] user_agent User agent (e.g. openapi-generator/ruby/1.0.0) + def user_agent=(user_agent) + @user_agent = user_agent + @default_headers['User-Agent'] = @user_agent + end + + # Return Accept header based on an array of accepts provided. + # @param [Array] accepts array for Accept + # @return [String] the Accept header (e.g. application/json) + def select_header_accept(accepts) + return nil if accepts.nil? || accepts.empty? + # use JSON when present, otherwise use all of the provided + json_accept = accepts.find { |s| json_mime?(s) } + json_accept || accepts.join(',') + end + + # Return Content-Type header based on an array of content types provided. + # @param [Array] content_types array for Content-Type + # @return [String] the Content-Type header (e.g. application/json) + def select_header_content_type(content_types) + # return nil by default + return if content_types.nil? || content_types.empty? + # use JSON when present, otherwise use the first one + json_content_type = content_types.find { |s| json_mime?(s) } + json_content_type || content_types.first + end + + # Convert object (array, hash, object, etc) to JSON string. + # @param [Object] model object to be converted into JSON string + # @return [String] JSON string representation of the object + def object_to_http_body(model) + return model if model.nil? || model.is_a?(String) + local_body = nil + if model.is_a?(Array) + local_body = model.map { |m| object_to_hash(m) } + else + local_body = object_to_hash(model) + end + local_body.to_json + end + + # Convert object(non-array) to hash. + # @param [Object] obj object to be converted into JSON string + # @return [String] JSON string representation of the object + def object_to_hash(obj) + if obj.respond_to?(:to_hash) + obj.to_hash + else + obj + end + end + + # Build parameter value according to the given collection format. + # @param [String] collection_format one of :csv, :ssv, :tsv, :pipes and :multi + def build_collection_param(param, collection_format) + case collection_format + when :csv + param.join(',') + when :ssv + param.join(' ') + when :tsv + param.join("\t") + when :pipes + param.join('|') + when :multi + # return the array directly as typhoeus will handle it as expected + param + else + fail "unknown collection format: #{collection_format.inspect}" + end + end + end +end diff --git a/templates/ruby/v7.14.0/gemspec.mustache b/templates/ruby/v7.14.0/gemspec.mustache new file mode 100644 index 0000000..61b36a0 --- /dev/null +++ b/templates/ruby/v7.14.0/gemspec.mustache @@ -0,0 +1,42 @@ +# -*- encoding: utf-8 -*- + +=begin +{{> api_info}} + +=end + +$:.push File.expand_path("../lib", __FILE__) +require "{{gemName}}/version" + +Gem::Specification.new do |s| + s.name = "{{gemName}}{{^gemName}}{{{appName}}}{{/gemName}}" + s.version = {{moduleName}}::VERSION + s.platform = Gem::Platform::RUBY + s.authors = ["{{gemAuthor}}{{^gemAuthor}}OpenAPI-Generator{{/gemAuthor}}"] + s.email = ["{{gemAuthorEmail}}{{^gemAuthorEmail}}{{infoEmail}}{{/gemAuthorEmail}}"] + s.homepage = "{{gemHomepage}}{{^gemHomepage}}https://openapi-generator.tech{{/gemHomepage}}" + s.summary = "{{gemSummary}}{{^gemSummary}}{{{appName}}} Ruby Gem{{/gemSummary}}" + s.description = "{{gemDescription}}{{^gemDescription}}{{{appDescription}}}{{^appDescription}}{{{appName}}} Ruby Gem{{/appDescription}}{{/gemDescription}}" + s.license = "{{{gemLicense}}}{{^gemLicense}}Unlicense{{/gemLicense}}" + s.required_ruby_version = "{{{gemRequiredRubyVersion}}}{{^gemRequiredRubyVersion}}>= 2.7{{/gemRequiredRubyVersion}}" + s.metadata = {{{gemMetadata}}}{{^gemMetadata}}{}{{/gemMetadata}} + + {{#isFaraday}} + s.add_runtime_dependency 'faraday', '>= 1.0.1', '< 2.9' + s.add_runtime_dependency 'faraday-multipart' + s.add_runtime_dependency 'marcel' + {{/isFaraday}} + {{#isTyphoeus}} + s.add_runtime_dependency 'typhoeus', '~> 1.0', '>= 1.0.1' + {{/isTyphoeus}} + {{#isHttpx}} + s.add_runtime_dependency 'httpx', '~> 1.0', '>= 1.0.0' + {{/isHttpx}} + + s.add_development_dependency 'rspec', '~> 3.6', '>= 3.6.0' + + s.files = `find *`.split("\n").uniq.sort.select { |f| !f.empty? } + s.test_files = `find spec/*`.split("\n") + s.executables = [] + s.require_paths = ["lib"] +end From 120cfc5458f1123b6bf65aaf2dbec949df2c5ca0 Mon Sep 17 00:00:00 2001 From: Pedro Brochado Date: Wed, 17 Sep 2025 15:30:27 -0300 Subject: [PATCH 2/3] Revert "Test upgrading to 7.14" This reverts commit ee5f95edbf30c62f7431b7f0ebd8b93bc6e47461. --- gen-client.sh | 2 +- templates/ruby/v7.14.0/api_client.mustache | 247 --------------------- templates/ruby/v7.14.0/gemspec.mustache | 42 ---- 3 files changed, 1 insertion(+), 290 deletions(-) delete mode 100644 templates/ruby/v7.14.0/api_client.mustache delete mode 100644 templates/ruby/v7.14.0/gemspec.mustache diff --git a/gen-client.sh b/gen-client.sh index 0183f0a..6ff3c87 100755 --- a/gen-client.sh +++ b/gen-client.sh @@ -68,7 +68,7 @@ if language.lower() == "python": print("v4.3.1") elif language.lower() == "ruby": if core_version >= Version("3.70.dev"): - print("v7.14.0") + print("v7.10.0") else: print("v4.3.1") elif language.lower() == "typescript": diff --git a/templates/ruby/v7.14.0/api_client.mustache b/templates/ruby/v7.14.0/api_client.mustache deleted file mode 100644 index ac21747..0000000 --- a/templates/ruby/v7.14.0/api_client.mustache +++ /dev/null @@ -1,247 +0,0 @@ -=begin -{{> api_info}} -=end - -require 'date' -require 'json' -require 'logger' -require 'tempfile' -require 'time' -{{#isTyphoeus}} -require 'typhoeus' -{{/isTyphoeus}} -{{#isFaraday}} -require 'faraday' -require 'faraday/multipart' if Gem::Version.new(Faraday::VERSION) >= Gem::Version.new('2.0') -require 'marcel' -{{/isFaraday}} -{{#isHttpx}} -require 'httpx' -require 'net/http/status' -{{/isHttpx}} -require 'pathname' - - -module {{moduleName}} - class ApiClient - # The Configuration object holding settings to be used in the API client. - attr_accessor :config - - # Defines the headers to be used in HTTP requests of all API calls by default. - # - # @return [Hash] - attr_accessor :default_headers - - # Initializes the ApiClient - # @option config [Configuration] Configuration for initializing the object, default to Configuration.default - def initialize(config = Configuration.default) - @config = config - @user_agent = "{{{httpUserAgent}}}{{^httpUserAgent}}OpenAPI-Generator/#{VERSION}/ruby{{/httpUserAgent}}" - @default_headers = { - 'Content-Type' => 'application/json', - 'User-Agent' => @user_agent - } - end - - def self.default - @@default ||= ApiClient.new - end - -{{#isTyphoeus}} -{{> api_client_typhoeus_partial}} -{{/isTyphoeus}} -{{#isFaraday}} -{{> api_client_faraday_partial}} -{{/isFaraday}} -{{#isHttpx}} -{{> api_client_httpx_partial}} -{{/isHttpx}} - # Check if the given MIME is a JSON MIME. - # JSON MIME examples: - # application/json - # application/json; charset=UTF8 - # APPLICATION/JSON - # */* - # @param [String] mime MIME - # @return [Boolean] True if the MIME is application/json - def json_mime?(mime) - (mime == '*/*') || !(mime =~ /^Application\/.*json(?!p)(;.*)?/i).nil? - end - - # Deserialize the response to the given return type. - # - # @param [Response] response HTTP response - # @param [String] return_type some examples: "User", "Array", "Hash" - def deserialize(response, return_type) - body = response.body - return nil if body.nil? || body.empty? - - # return response body directly for String return type - return body.to_s if return_type == 'String' - - # ensuring a default content type - content_type = response.headers['Content-Type'] || 'application/json' - - fail "Content-Type is not supported: #{content_type}" unless json_mime?(content_type) - - begin - data = JSON.parse("[#{body}]", :symbolize_names => true)[0] - rescue JSON::ParserError => e - if %w(String Date Time).include?(return_type) - data = body - else - raise e - end - end - - convert_to_type data, return_type - end - - # Convert data to the given return type. - # @param [Object] data Data to be converted - # @param [String] return_type Return type - # @return [Mixed] Data in a particular type - def convert_to_type(data, return_type) - return nil if data.nil? - case return_type - when 'String' - data.to_s - when 'Integer' - data.to_i - when 'Float' - data.to_f - when 'Boolean' - data == true - when 'Time' - # parse date time (expecting ISO 8601 format) - Time.parse data - when 'Date' - # parse date time (expecting ISO 8601 format) - Date.parse data - when 'Object' - # generic object (usually a Hash), return directly - data - when /\AArray<(.+)>\z/ - # e.g. Array - sub_type = $1 - data.map { |item| convert_to_type(item, sub_type) } - when /\AHash\\z/ - # e.g. Hash - sub_type = $1 - {}.tap do |hash| - data.each { |k, v| hash[k] = convert_to_type(v, sub_type) } - end - else - # models (e.g. Pet) or oneOf - klass = {{moduleName}}.const_get(return_type) - klass.respond_to?(:openapi_one_of) ? klass.build(data) : klass.build_from_hash(data) - end - end - - # Sanitize filename by removing path. - # e.g. ../../sun.gif becomes sun.gif - # - # @param [String] filename the filename to be sanitized - # @return [String] the sanitized filename - def sanitize_filename(filename) - filename.split(/[\/\\]/).last - end - - def build_request_url(path, opts = {}) - # Add leading and trailing slashes to path - path = "/#{path}".gsub(/\/+/, '/') - @config.base_url(opts[:operation]) + path - end - - # Update header and query params based on authentication settings. - # - # @param [Hash] header_params Header parameters - # @param [Hash] query_params Query parameters - # @param [String] auth_names Authentication scheme name - def update_params_for_auth!(header_params, query_params, auth_names) - Array(auth_names).each do |auth_name| - auth_setting = @config.auth_settings[auth_name] - next unless auth_setting - case auth_setting[:in] - when 'header' then header_params[auth_setting[:key]] = auth_setting[:value] - when 'query' then query_params[auth_setting[:key]] = auth_setting[:value] - else fail ArgumentError, 'Authentication token must be in `query` or `header`' - end - end - end - - # Sets user agent in HTTP header - # - # @param [String] user_agent User agent (e.g. openapi-generator/ruby/1.0.0) - def user_agent=(user_agent) - @user_agent = user_agent - @default_headers['User-Agent'] = @user_agent - end - - # Return Accept header based on an array of accepts provided. - # @param [Array] accepts array for Accept - # @return [String] the Accept header (e.g. application/json) - def select_header_accept(accepts) - return nil if accepts.nil? || accepts.empty? - # use JSON when present, otherwise use all of the provided - json_accept = accepts.find { |s| json_mime?(s) } - json_accept || accepts.join(',') - end - - # Return Content-Type header based on an array of content types provided. - # @param [Array] content_types array for Content-Type - # @return [String] the Content-Type header (e.g. application/json) - def select_header_content_type(content_types) - # return nil by default - return if content_types.nil? || content_types.empty? - # use JSON when present, otherwise use the first one - json_content_type = content_types.find { |s| json_mime?(s) } - json_content_type || content_types.first - end - - # Convert object (array, hash, object, etc) to JSON string. - # @param [Object] model object to be converted into JSON string - # @return [String] JSON string representation of the object - def object_to_http_body(model) - return model if model.nil? || model.is_a?(String) - local_body = nil - if model.is_a?(Array) - local_body = model.map { |m| object_to_hash(m) } - else - local_body = object_to_hash(model) - end - local_body.to_json - end - - # Convert object(non-array) to hash. - # @param [Object] obj object to be converted into JSON string - # @return [String] JSON string representation of the object - def object_to_hash(obj) - if obj.respond_to?(:to_hash) - obj.to_hash - else - obj - end - end - - # Build parameter value according to the given collection format. - # @param [String] collection_format one of :csv, :ssv, :tsv, :pipes and :multi - def build_collection_param(param, collection_format) - case collection_format - when :csv - param.join(',') - when :ssv - param.join(' ') - when :tsv - param.join("\t") - when :pipes - param.join('|') - when :multi - # return the array directly as typhoeus will handle it as expected - param - else - fail "unknown collection format: #{collection_format.inspect}" - end - end - end -end diff --git a/templates/ruby/v7.14.0/gemspec.mustache b/templates/ruby/v7.14.0/gemspec.mustache deleted file mode 100644 index 61b36a0..0000000 --- a/templates/ruby/v7.14.0/gemspec.mustache +++ /dev/null @@ -1,42 +0,0 @@ -# -*- encoding: utf-8 -*- - -=begin -{{> api_info}} - -=end - -$:.push File.expand_path("../lib", __FILE__) -require "{{gemName}}/version" - -Gem::Specification.new do |s| - s.name = "{{gemName}}{{^gemName}}{{{appName}}}{{/gemName}}" - s.version = {{moduleName}}::VERSION - s.platform = Gem::Platform::RUBY - s.authors = ["{{gemAuthor}}{{^gemAuthor}}OpenAPI-Generator{{/gemAuthor}}"] - s.email = ["{{gemAuthorEmail}}{{^gemAuthorEmail}}{{infoEmail}}{{/gemAuthorEmail}}"] - s.homepage = "{{gemHomepage}}{{^gemHomepage}}https://openapi-generator.tech{{/gemHomepage}}" - s.summary = "{{gemSummary}}{{^gemSummary}}{{{appName}}} Ruby Gem{{/gemSummary}}" - s.description = "{{gemDescription}}{{^gemDescription}}{{{appDescription}}}{{^appDescription}}{{{appName}}} Ruby Gem{{/appDescription}}{{/gemDescription}}" - s.license = "{{{gemLicense}}}{{^gemLicense}}Unlicense{{/gemLicense}}" - s.required_ruby_version = "{{{gemRequiredRubyVersion}}}{{^gemRequiredRubyVersion}}>= 2.7{{/gemRequiredRubyVersion}}" - s.metadata = {{{gemMetadata}}}{{^gemMetadata}}{}{{/gemMetadata}} - - {{#isFaraday}} - s.add_runtime_dependency 'faraday', '>= 1.0.1', '< 2.9' - s.add_runtime_dependency 'faraday-multipart' - s.add_runtime_dependency 'marcel' - {{/isFaraday}} - {{#isTyphoeus}} - s.add_runtime_dependency 'typhoeus', '~> 1.0', '>= 1.0.1' - {{/isTyphoeus}} - {{#isHttpx}} - s.add_runtime_dependency 'httpx', '~> 1.0', '>= 1.0.0' - {{/isHttpx}} - - s.add_development_dependency 'rspec', '~> 3.6', '>= 3.6.0' - - s.files = `find *`.split("\n").uniq.sort.select { |f| !f.empty? } - s.test_files = `find spec/*`.split("\n") - s.executables = [] - s.require_paths = ["lib"] -end From 6663305de3bd47298f6d325d35871b5121c3b449 Mon Sep 17 00:00:00 2001 From: Pedro Brochado Date: Wed, 17 Sep 2025 16:47:12 -0300 Subject: [PATCH 3/3] Add ruby tests for unitiliazed OneOf --- tests/ruby-runner.sh | 2 +- tests/test_ruby.rb | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/tests/ruby-runner.sh b/tests/ruby-runner.sh index 0e067b5..a0865c4 100755 --- a/tests/ruby-runner.sh +++ b/tests/ruby-runner.sh @@ -10,7 +10,7 @@ GIT_PROJECT_ROOT="$(git rev-parse --show-toplevel)" cd "$GIT_PROJECT_ROOT" export PULP_URL="${PULP_URL:-http://localhost:5001}" -COMPONENTS=(pulpcore pulp_file) +COMPONENTS=(pulpcore pulp_file pulp_rpm) function setup-ruby(){ # Configure "isolated" ruby on host machine diff --git a/tests/test_ruby.rb b/tests/test_ruby.rb index 5424b78..531c948 100644 --- a/tests/test_ruby.rb +++ b/tests/test_ruby.rb @@ -1,5 +1,6 @@ require 'pulpcore_client' require 'pulp_file_client' +require 'pulp_rpm_client' require 'tempfile' require 'digest' @@ -20,6 +21,13 @@ config.debugging=true end +PulpRpmClient.configure do |config| + config.host= ENV['PULP_URL'] + config.username= 'admin' + config.password= 'password' + config.debugging=true +end + @artifacts_api = PulpcoreClient::ArtifactsApi.new @filerepositories_api = PulpFileClient::RepositoriesFileApi.new @@ -30,6 +38,9 @@ @fileremotes_api = PulpFileClient::RemotesFileApi.new @tasks_api = PulpcoreClient::TasksApi.new @uploads_api = PulpcoreClient::UploadsApi.new +@content_modulemds_api = PulpRpmClient::ContentModulemdsApi.new +@rpmrepositories_api = PulpRpmClient::RepositoriesRpmApi.new +@rpmremotes_api = PulpRpmClient::RemotesRpmApi.new def monitor_task(task_href) # Polls the Task API until the task is in a completed state. @@ -147,3 +158,15 @@ def upload_file_in_chunks(file_path) distribution_data = PulpFileClient::FileFileDistribution.new({name: 'baz38', base_path: 'foo38', publication: publication_href}) distribution = @filedistributions_api.create(distribution_data) + +# Exercise modular endpoint +# https://github.com/pulp/pulp_rpm/issues/4125 +MODULAR_URL = 'https://fixtures.pulpproject.org/rpm-with-modules/' +rpm_remote_data = PulpRpmClient::RpmRpmRemote.new({name: 'rpm_modules_remote', url: MODULAR_URL}) +rpm_remote = @rpmremotes_api.create(rpm_remote_data) +rpm_repository_data = PulpRpmClient::RpmRpmRepository.new({name: 'rpm_modules_repo', remote: rpm_remote.pulp_href}) +rpm_repository = @rpmrepositories_api.create(rpm_repository_data) +repository_sync_data = PulpRpmClient::RpmRepositorySyncURL.new({}) +sync_response = @rpmrepositories_api.sync(rpm_repository.pulp_href, repository_sync_data) +created_resources = monitor_task(sync_response.task) +@content_modulemds_api.list({})