diff --git a/robottelo/constants/__init__.py b/robottelo/constants/__init__.py index 4896fecec0..b01c812cbe 100644 --- a/robottelo/constants/__init__.py +++ b/robottelo/constants/__init__.py @@ -845,7 +845,10 @@ }, } FLATPAK_INDEX_SUFFIX = 'index/static?label:org.flatpak.ref:exists=1&tag=latest' -PULPCORE_FLATPAK_ENDPOINT = 'https://{}/pulpcore_registry/' + FLATPAK_INDEX_SUFFIX +FLATPAK_ENDPOINTS = { + 'pulpcore': 'https://{}/pulpcore_registry/' + FLATPAK_INDEX_SUFFIX, + 'katello': 'https://{}/' + FLATPAK_INDEX_SUFFIX, +} CONTAINER_CLIENTS = ['docker', 'podman'] CUSTOM_LOCAL_FOLDER = '/var/lib/pulp/imports/myrepo/' diff --git a/tests/foreman/api/test_capsulecontent.py b/tests/foreman/api/test_capsulecontent.py index dda6c26cbb..8a453a3515 100644 --- a/tests/foreman/api/test_capsulecontent.py +++ b/tests/foreman/api/test_capsulecontent.py @@ -36,10 +36,10 @@ FAKE_FILE_LARGE_COUNT, FAKE_FILE_LARGE_URL, FAKE_FILE_NEW_NAME, + FLATPAK_ENDPOINTS, KICKSTART_CONTENT, PRDS, PULP_ARTIFACT_DIR, - PULPCORE_FLATPAK_ENDPOINT, REPOS, REPOSET, RH_CONTAINER_REGISTRY_HUB, @@ -785,21 +785,23 @@ def test_positive_capsule_pub_url_accessible(self, module_capsule_configured): assert b'katello-server-ca.crt' in response.content @pytest.mark.upgrade - def test_flatpak_pulpcore_endpoint(self, target_sat, module_capsule_configured): - """Ensure the Capsules's flatpak pulpcore endpoint is up after install or upgrade. + @pytest.mark.parametrize('endpoint', ['pulpcore']) + def test_flatpak_endpoint(self, target_sat, module_capsule_configured, endpoint): + """Ensure the Capsules's local flatpak index endpoint is up after install or upgrade. :id: 5676fbbb-75be-4660-a09e-65cafdfb221a + :parametrized: yes + :steps: - 1. Hit Capsule's pulpcore_registry endpoint. + 1. Hit Capsule's local flatpak index endpoint per parameter. :expectedresults: 1. HTTP 200 """ - rq = requests.get( - PULPCORE_FLATPAK_ENDPOINT.format(module_capsule_configured.hostname), verify=False - ) - assert rq.ok, f'Expected 200 but got {rq.status_code} from pulpcore registry index' + ep = FLATPAK_ENDPOINTS[endpoint].format(module_capsule_configured.hostname) + rq = requests.get(ep, verify=settings.server.verify_ca) + assert rq.ok, f'Expected 200 but got {rq.status_code} from {endpoint} registry index' @pytest.mark.e2e @pytest.mark.tier4 diff --git a/tests/foreman/cli/test_capsulecontent.py b/tests/foreman/cli/test_capsulecontent.py index c4581dfebc..added45fab 100644 --- a/tests/foreman/cli/test_capsulecontent.py +++ b/tests/foreman/cli/test_capsulecontent.py @@ -883,11 +883,11 @@ def test_sync_consume_flatpak_repo_via_library( 'job-template': 'Flatpak - Set up remote on host', 'inputs': ( f'Remote Name={remote_name}, ' - f'Flatpak registry URL=https://{caps.hostname}/pulpcore_registry/, ' + f'Flatpak registry URL={settings.server.scheme}://{caps.hostname}/pulpcore_registry/, ' f'Username={settings.server.admin_username}, ' f'Password={settings.server.admin_password}' ), - 'search-query': f"name ~ {host.hostname}", + 'search-query': f"name = {host.hostname}", } ) res = module_target_sat.cli.JobInvocation.info({'id': job.id}) @@ -907,7 +907,7 @@ def test_sync_consume_flatpak_repo_via_library( 'organization': function_org.name, 'job-template': 'Flatpak - Install application on host', 'inputs': f'Flatpak remote name={remote_name}, Application name={app_name}', - 'search-query': f"name ~ {host.hostname}", + 'search-query': f"name = {host.hostname}", } ) res = module_target_sat.cli.JobInvocation.info({'id': job.id}) diff --git a/tests/foreman/cli/test_flatpak.py b/tests/foreman/cli/test_flatpak.py index 9af087f5a7..c9124330c1 100644 --- a/tests/foreman/cli/test_flatpak.py +++ b/tests/foreman/cli/test_flatpak.py @@ -16,8 +16,8 @@ import requests from robottelo.config import settings -from robottelo.constants import FLATPAK_INDEX_SUFFIX, FLATPAK_REMOTES, PULPCORE_FLATPAK_ENDPOINT -from robottelo.exceptions import CLIReturnCodeError +from robottelo.constants import FLATPAK_ENDPOINTS, FLATPAK_INDEX_SUFFIX, FLATPAK_REMOTES +from robottelo.exceptions import CLIFactoryError, CLIReturnCodeError from robottelo.utils.datafactory import gen_string @@ -44,6 +44,13 @@ def function_user(target_sat, function_role, function_org): user.delete() +@pytest.fixture +def function_host_cleanup(target_sat, module_flatpak_contenthost): + """Cleans up the flatpak contenthost so it can be re-registered with different org""" + if nh := module_flatpak_contenthost.nailgun_host: + nh.delete() + + def test_CRUD_and_sync_flatpak_remote_with_permissions( target_sat, function_user, function_role, function_org ): @@ -198,19 +205,23 @@ def test_scan_flatpak_remote(target_sat, function_org, function_flatpak_remote): @pytest.mark.upgrade -def test_flatpak_pulpcore_endpoint(target_sat): - """Ensure the Satellite's flatpak pulpcore endpoint is up after install or upgrade. +@pytest.mark.parametrize('endpoint', ['pulpcore', 'katello']) +def test_flatpak_endpoint(target_sat, endpoint): + """Ensure the Satellite's local flatpak index endpoints are up after install or upgrade. :id: 3593ac46-4e5d-495e-95eb-d9609cb46a15 + :parametrized: yes + :steps: - 1. Hit Satellite's pulpcore_registry endpoint. + 1. Hit Satellite's local flatpak index endpoint per parameter. :expectedresults: 1. HTTP 200 """ - rq = requests.get(PULPCORE_FLATPAK_ENDPOINT.format(target_sat.hostname), verify=False) - assert rq.ok, f'Expected 200 but got {rq.status_code} from pulpcore registry index' + ep = FLATPAK_ENDPOINTS[endpoint].format(target_sat.hostname) + rq = requests.get(ep, verify=settings.server.verify_ca) + assert rq.ok, f'Expected 200 but got {rq.status_code} from {endpoint} registry index' @pytest.mark.e2e @@ -220,11 +231,12 @@ def test_sync_consume_flatpak_repo_via_library( request, module_target_sat, module_flatpak_contenthost, + function_host_cleanup, function_org, function_product, function_flatpak_remote, ): - """Verify flatpak repository workflow end to end. + """Verify flatpak repository workflow end to end via library. :id: 06043b3e-be9b-4444-96b1-d3d15b7e3d8c @@ -237,7 +249,7 @@ def test_sync_consume_flatpak_repo_via_library( 1. Mirror flatpak repositories and sync them. 2. Create an AK assigned to the Library. 3. Register a content host using the AK. - 4. Configure the contenthost via REX to use Satellite's flatpak index. + 4. Configure the contenthost via REX to use Satellite's pulpcore flatpak index. 5. Install flatpak app from the repo via REX on the contenthost. 6. Ensure the app has been installed successfully. @@ -294,7 +306,7 @@ def test_sync_consume_flatpak_repo_via_library( ) assert host.subscribed - # 4. Configure the contenthost via REX to use Satellite's flatpak index. + # 4. Configure the contenthost via REX to use Satellite's pulpcore flatpak index. remote_name = f'SAT-remote-{gen_string("alpha")}' job = module_target_sat.cli_factory.job_invocation( { @@ -302,21 +314,20 @@ def test_sync_consume_flatpak_repo_via_library( 'job-template': 'Flatpak - Set up remote on host', 'inputs': ( f'Remote Name={remote_name}, ' - f'Flatpak registry URL=https://{sat.hostname}/pulpcore_registry/, ' + f'Flatpak registry URL={settings.server.scheme}://{sat.hostname}/pulpcore_registry/, ' f'Username={settings.server.admin_username}, ' f'Password={settings.server.admin_password}' ), - 'search-query': f"name ~ {host.hostname}", + 'search-query': f"name = {host.hostname}", } ) res = module_target_sat.cli.JobInvocation.info({'id': job.id}) assert 'succeeded' in res['status'] request.addfinalizer(lambda: host.execute(f'flatpak remote-delete {remote_name}')) - - # 5. Install flatpak app from the repo via REX on the contenthost. res = host.execute('flatpak remotes') assert remote_name in res.stdout + # 5. Install flatpak app from the repo via REX on the contenthost. app_name = 'Firefox' # or 'org.mozilla.Firefox' res = host.execute('flatpak remote-ls') assert app_name in res.stdout @@ -326,7 +337,7 @@ def test_sync_consume_flatpak_repo_via_library( 'organization': function_org.name, 'job-template': 'Flatpak - Install application on host', 'inputs': f'Flatpak remote name={remote_name}, Application name={app_name}', - 'search-query': f"name ~ {host.hostname}", + 'search-query': f"name = {host.hostname}", } ) res = module_target_sat.cli.JobInvocation.info({'id': job.id}) @@ -338,3 +349,154 @@ def test_sync_consume_flatpak_repo_via_library( # 6. Ensure the app has been installed successfully. res = host.execute('flatpak list') assert app_name in res.stdout + + +@pytest.mark.e2e +@pytest.mark.upgrade +@pytest.mark.parametrize('function_flatpak_remote', ['RedHat'], indirect=True) +def test_sync_consume_flatpak_repo_via_cv( + request, + module_target_sat, + module_flatpak_contenthost, + function_host_cleanup, + function_org, + function_lce, + function_product, + function_flatpak_remote, +): + """Verify flatpak repository workflow end to end via CV. + + :id: 820b59b0-20f0-472a-afab-5c480bedbfd0 + + :parametrized: yes + + :setup: + 1. Create a Product and a Lifecycle Environment. + 2. Create a flatpak remote and scan it. + + :steps: + 1. Mirror flatpak repositories and sync them. + 2. Create two CVs, put different repos inside, publish and promote them to LCE. + 3. Create an AK assigned with one content view environment only. + 4. Register a content host using the AK. + 5. Configure the content host to use Satellite's flatpak index. + 6. Ensure only the proper Apps are available. + 7. Install flatpak app from the first CV, ensure it succeeded. + 8. Try to install flatpak app from the second CV, ensure it failed. + + :expectedresults: + 1. Flatpak repos published in a CV are installable on a host via the CV. + 2. Other flatpak repos published in a different CV are isolated from the first CV. + + """ + sat, host = module_target_sat, module_flatpak_contenthost + + # 1. Mirror flatpak repositories and sync them. + repo_names = ['rhel9/firefox-flatpak', 'rhel9/inkscape-flatpak', 'rhel9/flatpak-runtime'] + remote_repos = [r for r in function_flatpak_remote.repos if r['name'] in repo_names] + for repo in remote_repos: + sat.cli.FlatpakRemote().repository_mirror( + { + 'flatpak-remote-id': function_flatpak_remote.remote['id'], + 'id': repo['id'], + 'product-id': function_product.id, + } + ) + local_repo = sat.cli.Repository.list( + {'product-id': function_product.id, 'name': repo['name']} + )[0] + sat.cli.Repository.synchronize({'id': local_repo['id']}) + + local_repos = sat.cli.Repository.list({'product-id': function_product.id}) + assert set([r['name'] for r in local_repos]) == set(repo_names), ( + 'Required repo(s) were not scanned or mirrored' + ) + + # 2. Create two CVs, put different repos inside, publish and promote them to LCE. + cv1 = sat.api.ContentView( + organization=function_org, + repository=[ + r['id'] + for r in local_repos + if r['name'] in ['rhel9/inkscape-flatpak', 'rhel9/flatpak-runtime'] + ], + ).create() + cv2 = sat.api.ContentView( + organization=function_org, + repository=[ + r['id'] + for r in local_repos + if r['name'] in ['rhel9/firefox-flatpak', 'rhel9/flatpak-runtime'] + ], + ).create() + for cv in [cv1, cv2]: + cv.publish() + cv.read().version[0].promote(data={'environment_ids': function_lce.id}) + + # 3. Create an AK assigned with one content view environment only. + ak = sat.api.ActivationKey( + organization=function_org, + content_view=cv1, + environment=function_lce, + ).create() + + # 4. Register a content host using the AK. + res = host.register(function_org, None, ak.name, sat, force=True) + assert res.status == 0, ( + f'Failed to register host: {host.hostname}\nStdOut: {res.stdout}\nStdErr: {res.stderr}' + ) + assert host.subscribed + + # 5. Configure the content host to use Satellite's flatpak index. + remote_name = f'SAT-remote-{gen_string("alpha")}' + job = module_target_sat.cli_factory.job_invocation( + { + 'organization': function_org.name, + 'job-template': 'Flatpak - Set up remote on host', + 'inputs': ( + f'Remote Name={remote_name}, ' + f'Flatpak registry URL={settings.server.scheme}://{sat.hostname}/, ' + f'Username={settings.server.admin_username}, ' + f'Password={settings.server.admin_password}' + ), + 'search-query': f"name = {host.hostname}", + } + ) + res = module_target_sat.cli.JobInvocation.info({'id': job.id}) + assert 'succeeded' in res['status'] + request.addfinalizer(lambda: host.execute(f'flatpak remote-delete {remote_name}')) + res = host.execute('flatpak remotes') + assert remote_name in res.stdout + + # 6. Ensure only the proper Apps are available. + res = host.execute('flatpak remote-ls') + assert all(app_name in res.stdout for app_name in ['Inkscape', 'Platform']) + assert 'Firefox' not in res.stdout + + # 7. Install flatpak app from the first CV, ensure it succeeded. + opts = { + 'organization': function_org.name, + 'job-template': 'Flatpak - Install application on host', + 'search-query': f"name = {host.hostname}", + } + cv1_app = 'Inkscape' + job = module_target_sat.cli_factory.job_invocation( + opts | {'inputs': f'Flatpak remote name={remote_name}, Application name={cv1_app}'} + ) + res = module_target_sat.cli.JobInvocation.info({'id': job.id}) + assert 'succeeded' in res['status'] + request.addfinalizer( + lambda: host.execute(f'flatpak uninstall {remote_name} {cv1_app} com.redhat.Platform -y') + ) + res = host.execute('flatpak list') + assert cv1_app in res.stdout + + # 8. Try to install flatpak app from the second CV, ensure it failed. + cv2_app = 'Firefox' + with pytest.raises(CLIFactoryError) as error: + sat.cli_factory.job_invocation( + opts | {'inputs': f'Flatpak remote name={remote_name}, Application name={cv2_app}'} + ) + assert 'A sub task failed' in error.value.args[0] + res = host.execute('flatpak list') + assert cv2_app not in res.stdout diff --git a/tests/foreman/cli/test_satellitesync.py b/tests/foreman/cli/test_satellitesync.py index d84d8e7784..77963f849d 100644 --- a/tests/foreman/cli/test_satellitesync.py +++ b/tests/foreman/cli/test_satellitesync.py @@ -1537,11 +1537,11 @@ def test_postive_export_import_cv_with_mixed_content_repos( 'job-template': 'Flatpak - Set up remote on host', 'inputs': ( f'Remote Name={remote_name}, ' - f'Flatpak registry URL=https://{module_import_sat.hostname}/pulpcore_registry/, ' + f'Flatpak registry URL={settings.server.scheme}://{module_import_sat.hostname}/pulpcore_registry/, ' f'Username={settings.server.admin_username}, ' f'Password={settings.server.admin_password}' ), - 'search-query': f"name ~ {module_flatpak_contenthost.hostname}", + 'search-query': f"name = {module_flatpak_contenthost.hostname}", } ) res = module_import_sat.cli.JobInvocation.info({'id': job.id}) @@ -1564,7 +1564,7 @@ def test_postive_export_import_cv_with_mixed_content_repos( 'organization': function_import_org_at_isat.name, 'job-template': 'Flatpak - Install application on host', 'inputs': f'Flatpak remote name={remote_name}, Application name={app_name}', - 'search-query': f"name ~ {module_flatpak_contenthost.hostname}", + 'search-query': f"name = {module_flatpak_contenthost.hostname}", } ) res = module_import_sat.cli.JobInvocation.info({'id': job.id})