Skip to content
This repository has been archived by the owner on May 24, 2023. It is now read-only.

Commit

Permalink
Merge f498e77 into 4313383
Browse files Browse the repository at this point in the history
  • Loading branch information
lcarva committed Jan 29, 2020
2 parents 4313383 + f498e77 commit 01ef6a5
Show file tree
Hide file tree
Showing 8 changed files with 145 additions and 19 deletions.
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,24 @@ Example configuration:
"package_name_suffix": "-suffix"
```

#### Adding annotations to ClusterServiceVersion

An organization can be configured to automatically set annotations on the ClusterServiceVersion
objects. Templating is supported to include the package name in the value.
Example configuration:
```
"csv_annotations": [
{
"name": "simple.annotation",
"value": "simple.value",
}
{
"name": "annotation.with.package_name",
"value": "value.{package_name}",
}
]
```

### Greenwave integration

This is optional. When `GREENWAVE` settings are missing in config file checks
Expand Down
52 changes: 44 additions & 8 deletions omps/api/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import logging
import os

from ruamel.yaml import YAML

from omps.errors import OMPSAuthorizationHeaderRequired


Expand Down Expand Up @@ -37,15 +39,49 @@ def replace_registries(quay_org, dir_path):
logger.info("Replacing registries URLs for organization: %s",
quay_org.organization)

for filename in _yield_yaml_files(dir_path):
with open(filename, 'r+') as f:
text = f.read()
text = quay_org.replace_registries(text)
f.seek(0)
f.write(text)
f.truncate()
f.flush()


def adjust_csv_annotations(quay_org, dir_path, context):
"""Annotates ClusterServiceVersion objects based on org config
Iterate through all the YAML files in search of the
ClusterServiceVersion objects then set the annotations
defined in the organization configuration.
"""
if not quay_org.csv_annotations:
return

yaml = YAML()
# for filename in sorted(os.listdir(dir_path)):
for filename in _yield_yaml_files(dir_path):
with open(filename, 'r+') as f:
contents = yaml.load(f.read())
if contents.get('kind') != 'ClusterServiceVersion':
continue
logger.info('Found ClusterServiceVersion in %s', filename)
csv_annotations = (
contents.setdefault('metadata', {}).setdefault('annotations', {}))
for annotation in quay_org.csv_annotations:
value = annotation['value'].format(**context)
csv_annotations[annotation['name']] = value

f.seek(0)
yaml.dump(contents, f)
f.truncate()


def _yield_yaml_files(dir_path):
"""Helper function to iterate only through yaml files"""
for root, _, files in os.walk(dir_path):
for fname in files:
fname_lower = fname.lower()
if fname_lower.endswith('.yml') or fname_lower.endswith('.yaml'):
fpath = os.path.join(root, fname)
with open(fpath, 'r') as f:
text = f.read()

text = quay_org.replace_registries(text)
with open(fpath, 'w') as f:
f.write(text)
f.flush()
yield os.path.join(root, fname)
3 changes: 2 additions & 1 deletion omps/api/v1/push.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from ruamel.yaml import YAML

from . import API
from omps.api.common import extract_auth_token, replace_registries
from omps.api.common import extract_auth_token, replace_registries, adjust_csv_annotations
from omps.constants import (
ALLOWED_EXTENSIONS,
DEFAULT_ZIPFILE_MAX_UNCOMPRESSED_SIZE,
Expand Down Expand Up @@ -246,6 +246,7 @@ def _zip_flow(*, organization, repo, version, extract_manifest_func,
logger.info("Using release version: %s", version)

replace_registries(quay_org, tmpdir)
adjust_csv_annotations(quay_org, tmpdir, {'package_name': package_name})

quay_org.push_operator_manifest(repo, version, tmpdir)

Expand Down
35 changes: 33 additions & 2 deletions omps/quay.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,28 @@ class OrgManager:
"package_name_suffix": {
"description": "suffix to append to package name",
"type": "string"
},
"csv_annotations": {
"description": ("annotations to add to each ClusterServiceVersion"
" object"),
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "name of the annotation"
},
"value": {
"type": "string",
"description": (
"value of the annotation, use python string"
" format syntax for dynamic values")

},
},
"required": ["name", "value"]
}
}
},
},
Expand Down Expand Up @@ -184,12 +206,14 @@ def initialize(self, config):
for org_name, org_conf in self._organizations.items():
logger.info(
'Organization "%s" configured: public=%s, oauth_access=%s, '
'replacing_registry_enabled=%s, package_name_suffix=%s',
'replacing_registry_enabled=%s, package_name_suffix=%s, '
'csv_annotations=%s',
org_name,
org_conf.get('public', False),
bool(org_conf.get('oauth_token')),
bool(org_conf.get('replace_registry')),
org_conf.get('package_name_suffix'),
bool(org_conf.get('csv_annotations')),
)

def get_org(self, organization, cnr_token):
Expand All @@ -202,6 +226,7 @@ def get_org(self, organization, cnr_token):
timeout=self._timeout,
replace_registry_conf=org_config.get('replace_registry'),
package_name_suffix=org_config.get('package_name_suffix'),
csv_annotations=org_config.get('csv_annotations'),
)


Expand All @@ -210,7 +235,8 @@ class QuayOrganization:

def __init__(
self, organization, cnr_token, oauth_token=None, public=False,
timeout=None, replace_registry_conf=None, package_name_suffix=None
timeout=None, replace_registry_conf=None, package_name_suffix=None,
csv_annotations=None,
):
"""
:param organization: organization name
Expand All @@ -229,6 +255,7 @@ def __init__(
self._timeout = timeout
self._replace_registry_conf = replace_registry_conf
self._package_name_suffix = package_name_suffix
self._csv_annotations = csv_annotations

@property
def public(self):
Expand All @@ -246,6 +273,10 @@ def organization(self):
def package_name_suffix(self):
return self._package_name_suffix

@property
def csv_annotations(self):
return self._csv_annotations

@property
def registry_replacing_enabled(self):
return bool(self._replace_registry_conf)
Expand Down
44 changes: 36 additions & 8 deletions tests/api/test_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,14 @@

import os

from omps.api.common import replace_registries
from ruamel.yaml import YAML

from omps.api.common import replace_registries, adjust_csv_annotations, _yield_yaml_files
from omps.quay import QuayOrganization


def test_replace_registries(datadir):
"""Test if registry is replaced in all files"""
def _yield_yaml_files(dir_path):
for root, _, files in os.walk(dir_path):
for fname in files:
fname_lower = fname.lower()
if fname_lower.endswith('.yml') or fname_lower.endswith('.yaml'):
yield os.path.join(root, fname)

dir_path = os.path.join(datadir, 'etcd_op_nested')
old = 'quay.io'
new = 'example.com'
Expand All @@ -39,3 +34,36 @@ def _yield_yaml_files(dir_path):
text = f.read()
assert new in text
assert old not in text


def test_adjust_csv_annotations(datadir):
"""Test if annotations are applied in ClusterServiceVersion"""
dir_path = os.path.join(datadir, 'etcd_op_nested')
csv_annotations = [
{'name': 'simple', 'value': 'simple-value'},
{'name': 'complex', 'value': 'value-{package_name}'},
]
expected_annotations = {
'simple': 'simple-value',
'complex': 'value-etcd',
}
quay_org = QuayOrganization(
'testorg', 'random token', csv_annotations=csv_annotations)

should_have_annotations = set()
for fpath in _yield_yaml_files(dir_path):
with open(fpath, 'r') as f:
text = f.read()
if 'ClusterServiceVersion' in text:
should_have_annotations.add(fpath)

assert should_have_annotations, 'Insufficient test data'

adjust_csv_annotations(quay_org, dir_path, {'package_name': 'etcd'})

yaml = YAML()
for fpath in should_have_annotations:
with open(fpath, 'r') as f:
contents = yaml.load(f.read())
for name, value in expected_annotations.items():
assert contents['metadata']['annotations'][name] == value
Binary file added tests/data/marketplace-op-flag.tar.gz
Binary file not shown.
Binary file added tests/data/marketplace-op-flag.zip
Binary file not shown.
12 changes: 12 additions & 0 deletions tests/test_quay.py
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,12 @@ class ConfClass:
'org_with_package_name_suffix': {
'package_name_suffix': '-suffix',
},
'org_with_csv_annotations': {
'csv_annotations': [
{'name': 'spam', 'value': 'maps'},
{'name': 'eggs', 'value': 'sgge'},
],
},
}

conf = Config(ConfClass)
Expand Down Expand Up @@ -572,6 +578,12 @@ class ConfClass:
'cnr_token')
assert org_with_package_name_suffix.package_name_suffix == '-suffix'

org_with_csv_annotations = om.get_org('org_with_csv_annotations', 'cnr_token')
assert org_with_csv_annotations.csv_annotations == [
{'name': 'spam', 'value': 'maps'},
{'name': 'eggs', 'value': 'sgge'},
]

def test_getting_unconfigured_org(self):
"""Test of getting organization instance whne org is not configured in
settings"""
Expand Down

0 comments on commit 01ef6a5

Please sign in to comment.