예제 #1
0
def test_quay_token_missing(get):
    """
    Test missing token in env but defined in config.
    """
    get.return_value.json.return_value = QUAY_API_DATA
    container.check_repos(CONF, {})
    get.assert_called_once_with(
        'https://quay.io/api/v1/repository/repos/testrepo/tag/?onlyActiveTags=true&limit=100&page=1',
        headers={}
    )
예제 #2
0
def test_quay_token(get):
    """
    Test that token is passed from config.
    """
    get.return_value.json.return_value = QUAY_API_DATA
    container.check_repos(CONF, {})
    get.assert_called_once_with(
        'https://quay.io/api/v1/repository/repos/testrepo/tag/?onlyActiveTags=true&limit=100&page=1',
        headers={"Authorization": "Bearer TOKEN"}
    )
예제 #3
0
def test_quay_latest(get):
    """
    Test that data for a single tag from the quay.io API is handled correctly.
    """
    get.return_value.json.return_value = QUAY_API_DATA
    result = container.check_repos(CONF, {})
    get.assert_called_once_with(
        'https://quay.io/api/v1/repository/repos/testrepo/tag/?onlyActiveTags=true&limit=100&page=1',
        headers={}
    )
    assert result == {
        'quay.io/repos/testrepo': {
            'latest': {
                'action': 'added',
                'repo': 'quay.io/repos/testrepo',
                'reponame': 'testrepo',
                'tag': 'latest',
                'digest': QUAY_API_DATA['tags'][0]['manifest_digest'],
                'old_digest': None,
                'created': format_ts(QUAY_API_DATA['tags'][0]['start_ts']),
                'labels': {},
                'os': '',
                'arch': ''
            }
        }
    }
예제 #4
0
def test_check_repos_raises(inspect_tag):
    """
    Test that an error inspecting the repo results in the correct output.
    """
    result = container.check_repos(CONF, {})
    inspect_tag.assert_called_once_with('example.com/repos/testrepo')
    assert result == {}
예제 #5
0
def test_quay_multitag_multipage(get):
    """
    Test that multiple pages of data containing multiple tags from the quay.io API are handled correctly.
    """
    get.return_value.json.side_effect = [QUAY_API_DATA_MULTITAG, QUAY_API_DATA]
    result = container.check_repos(CONF, {})
    calls = [
        call(
            'https://quay.io/api/v1/repository/repos/testrepo/tag/?onlyActiveTags=true&limit=100&page=1',
            headers={}
        ),
        call(
            'https://quay.io/api/v1/repository/repos/testrepo/tag/?onlyActiveTags=true&limit=100&page=2',
            headers={}
        )
    ]
    get.assert_has_calls(calls, any_order=True)
    assert result == {
        'quay.io/repos/testrepo': {
            'stage': {
                'action': 'added',
                'repo': 'quay.io/repos/testrepo',
                'reponame': 'testrepo',
                'tag': 'stage',
                'digest': QUAY_API_DATA_MULTITAG['tags'][0]['manifest_digest'],
                'old_digest': None,
                'created': format_ts(QUAY_API_DATA_MULTITAG['tags'][0]['start_ts']),
                'labels': {},
                'os': '',
                'arch': ''
            },
            'prod': {
                'action': 'added',
                'repo': 'quay.io/repos/testrepo',
                'reponame': 'testrepo',
                'tag': 'prod',
                'digest': QUAY_API_DATA_MULTITAG['tags'][1]['manifest_digest'],
                'old_digest': None,
                'created': format_ts(QUAY_API_DATA_MULTITAG['tags'][1]['start_ts']),
                'labels': {},
                'os': '',
                'arch': ''
            },
            'latest': {
                'action': 'added',
                'repo': 'quay.io/repos/testrepo',
                'reponame': 'testrepo',
                'tag': 'latest',
                'digest': QUAY_API_DATA['tags'][0]['manifest_digest'],
                'old_digest': None,
                'created': format_ts(QUAY_API_DATA['tags'][0]['start_ts']),
                'labels': {},
                'os': '',
                'arch': ''
            }
        }
    }
예제 #6
0
def test_check_repos_removed_previously(inspect_tag):
    """
    Test that a previously removed tag doesn't stay in the results.
    """
    old_data = {
        'example.com/repos/testrepo': {
            'latest': {
                'action': 'added',
                'repo': 'example.com/repos/testrepo',
                'reponame': 'testrepo',
                'tag': 'latest',
                'digest': INSPECT_DATA_1['Digest'],
                'old_digest': None,
                'created': format_time(INSPECT_DATA_1['Created']),
                'labels': INSPECT_DATA_1['Labels'],
                'os': INSPECT_DATA_1['Os'],
                'arch': INSPECT_DATA_1['Architecture'],
            },
            'stage': {
                'action': 'removed',
                'repo': 'example.com/repos/testrepo',
                'reponame': 'testrepo',
                'tag': 'stage',
                'digest': None,
                'old_digest': INSPECT_DATA_2['Digest'],
                'created': None,
                'labels': {},
                'os': None,
                'arch': None,
            }
        }
    }
    result = container.check_repos(CONF, old_data)
    inspect_tag.assert_called_once_with('example.com/repos/testrepo')
    assert result == {
        'example.com/repos/testrepo': {
            'latest': {
                'action': 'unchanged',
                'repo': 'example.com/repos/testrepo',
                'reponame': 'testrepo',
                'tag': 'latest',
                'digest': INSPECT_DATA_1['Digest'],
                'old_digest': None,
                'created': format_time(INSPECT_DATA_1['Created']),
                'labels': INSPECT_DATA_1['Labels'],
                'os': INSPECT_DATA_1['Os'],
                'arch': INSPECT_DATA_1['Architecture'],
            },
        }
    }
예제 #7
0
def test_check_repos_ghost(run):
    """
    Test that a tag that appeared in the RepoTags list, but no longer exists, and isn't present
    in the data from the previous run, results in the correct output.
    """
    run.side_effect = [
        Mock(returncode=0, stdout=json.dumps(INSPECT_DATA_1)),
        Mock(returncode=1, stderr='FATA[0001] Error reading manifest stage in example.com/repos/testrepo:'
             'manifest unknown: manifest unknown\n')
    ]
    old_data = {
        'example.com/repos/testrepo': {
            'latest': {
                'action': 'added',
                'repo': 'example.com/repos/testrepo',
                'reponame': 'testrepo',
                'tag': 'latest',
                'digest': INSPECT_DATA_1['Digest'],
                'old_digest': None,
                'created': format_time(INSPECT_DATA_1['Created']),
                'labels': INSPECT_DATA_1['Labels'],
                'os': INSPECT_DATA_1['Os'],
                'arch': INSPECT_DATA_1['Architecture'],
            },
        }
    }
    result = container.check_repos(CONF, old_data)
    assert run.call_count == 2
    assert result == {
        'example.com/repos/testrepo': {
            'latest': {
                'action': 'unchanged',
                'repo': 'example.com/repos/testrepo',
                'reponame': 'testrepo',
                'tag': 'latest',
                'digest': INSPECT_DATA_1['Digest'],
                'old_digest': None,
                'created': format_time(INSPECT_DATA_1['Created']),
                'labels': INSPECT_DATA_1['Labels'],
                'os': INSPECT_DATA_1['Os'],
                'arch': INSPECT_DATA_1['Architecture'],
            },
        }
    }
예제 #8
0
def test_quay_error_unchanged(get):
    """
    Test that a (temporary) error when querying the quay.io API leaves the data unchanged.
    """
    get.return_value.raise_for_status.side_effect = RuntimeError('request error')
    old_data = {
        'quay.io/repos/testrepo': {
            'latest': {
                'action': 'added',
                'repo': 'quay.io/repos/testrepo',
                'reponame': 'testrepo',
                'tag': 'latest',
                'digest': QUAY_API_DATA['tags'][0]['manifest_digest'],
                'old_digest': None,
                'created': format_ts(QUAY_API_DATA['tags'][0]['start_ts']),
                'labels': {},
                'os': '',
                'arch': ''
            }
        }
    }
    result = container.check_repos(CONF, old_data)
    get.assert_called_once_with(
        'https://quay.io/api/v1/repository/repos/testrepo/tag/?onlyActiveTags=true&limit=100&page=1',
        headers={}
    )
    assert result == {
        'quay.io/repos/testrepo': {
            'ignore': True,
            'latest': {
                'action': 'added',
                'repo': 'quay.io/repos/testrepo',
                'reponame': 'testrepo',
                'tag': 'latest',
                'digest': QUAY_API_DATA['tags'][0]['manifest_digest'],
                'old_digest': None,
                'created': format_ts(QUAY_API_DATA['tags'][0]['start_ts']),
                'labels': {},
                'os': '',
                'arch': ''
            }
        }
    }
예제 #9
0
def main():
    args = get_args()
    if args.quiet:
        logging.basicConfig(level=logging.ERROR)
    else:
        logging.basicConfig(level=logging.INFO)
    conf = utils.load_config(args.config)
    data = utils.load_data(args.data)
    new_data = container.check_repos(conf, data)
    if args.verbose:
        pprint.pprint(new_data)
    try:
        messaging.send_container_updates(conf, new_data)
    except:
        log.error(
            'Could not send all messages, container state will not be updated. '
            'May result in duplicate messages.')
        raise
    else:
        utils.save_data(args.data, new_data)
예제 #10
0
def test_check_repos_readded(inspect_tag):
    """
    Test that a repo that is readded immediately after it was removed results in
    a "added" message, and not an "updated" message.
    """
    old_data = {
        'example.com/repos/testrepo': {
            'latest': {
                'action': 'removed',
                'repo': 'example.com/repos/testrepo',
                'reponame': 'testrepo',
                'tag': 'latest',
                'digest': None,
                'old_digest': 'a1b2c3',
                'created': None,
                'labels': {},
                'os': None,
                'arch': None,
            }
        }
    }
    result = container.check_repos(CONF, old_data)
    inspect_tag.assert_called_once_with('example.com/repos/testrepo')
    assert result == {
        'example.com/repos/testrepo': {
            'latest': {
                'action': 'added',
                'repo': 'example.com/repos/testrepo',
                'reponame': 'testrepo',
                'tag': 'latest',
                'digest': INSPECT_DATA_1['Digest'],
                'old_digest': None,
                'created': format_time(INSPECT_DATA_1['Created']),
                'labels': INSPECT_DATA_1['Labels'],
                'os': INSPECT_DATA_1['Os'],
                'arch': INSPECT_DATA_1['Architecture'],
            }
        }
    }
예제 #11
0
def test_check_repos_unchanged_ignore(inspect_tag):
    """
    Test that the 'ignore' flag is correctly ignored.
    """
    old_data = {
        'example.com/repos/testrepo': {
            'ignore': True,
            'latest': {
                'action': 'added',
                'repo': 'example.com/repos/testrepo',
                'reponame': 'testrepo',
                'tag': 'latest',
                'digest': INSPECT_DATA_1['Digest'],
                'old_digest': None,
                'created': format_time(INSPECT_DATA_1['Created']),
                'labels': INSPECT_DATA_1['Labels'],
                'os': INSPECT_DATA_1['Os'],
                'arch': INSPECT_DATA_1['Architecture'],
            }
        }
    }
    result = container.check_repos(CONF, old_data)
    inspect_tag.assert_called_once_with('example.com/repos/testrepo')
    assert result == {
        'example.com/repos/testrepo': {
            'latest': {
                'action': 'unchanged',
                'repo': 'example.com/repos/testrepo',
                'reponame': 'testrepo',
                'tag': 'latest',
                'digest': INSPECT_DATA_1['Digest'],
                'old_digest': None,
                'created': format_time(INSPECT_DATA_1['Created']),
                'labels': INSPECT_DATA_1['Labels'],
                'os': INSPECT_DATA_1['Os'],
                'arch': INSPECT_DATA_1['Architecture'],
            }
        }
    }
예제 #12
0
def test_check_repos_added(inspect_tag):
    """
    Test that a new repo results in the correct output.
    """
    result = container.check_repos(CONF, {})
    inspect_tag.assert_called_once_with('example.com/repos/testrepo')
    assert result == {
        'example.com/repos/testrepo': {
            'latest': {
                'action': 'added',
                'repo': 'example.com/repos/testrepo',
                'reponame': 'testrepo',
                'tag': 'latest',
                'digest': INSPECT_DATA_1['Digest'],
                'old_digest': None,
                'created': format_time(INSPECT_DATA_1['Created']),
                'labels': INSPECT_DATA_1['Labels'],
                'os': INSPECT_DATA_1['Os'],
                'arch': INSPECT_DATA_1['Architecture'],
            }
        }
    }
예제 #13
0
def test_check_repos_removed_error(run):
    """
    Test that a tag that throws an error after initial inspection results in the correct output.
    """
    run.side_effect = [
        Mock(returncode=0, stdout=json.dumps(INSPECT_DATA_1)),
        Mock(returncode=1, stderr='FATA[0001] Error reading manifest stage in example.com/repos/testrepo:'
             'some other error\n')
    ]
    old_data = {
        'example.com/repos/testrepo': {
            'latest': {
                'action': 'added',
                'repo': 'example.com/repos/testrepo',
                'reponame': 'testrepo',
                'tag': 'latest',
                'digest': INSPECT_DATA_1['Digest'],
                'old_digest': None,
                'created': format_time(INSPECT_DATA_1['Created']),
                'labels': INSPECT_DATA_1['Labels'],
                'os': INSPECT_DATA_1['Os'],
                'arch': INSPECT_DATA_1['Architecture'],
            },
            'stage': {
                'action': 'added',
                'repo': 'example.com/repos/testrepo',
                'reponame': 'testrepo',
                'tag': 'stage',
                'digest': INSPECT_DATA_2['Digest'],
                'old_digest': None,
                'created': format_time(INSPECT_DATA_2['Created']),
                'labels': INSPECT_DATA_2['Labels'],
                'os': INSPECT_DATA_2['Os'],
                'arch': INSPECT_DATA_2['Architecture'],
            }
        }
    }
    result = container.check_repos(CONF, old_data)
    assert run.call_count == 2
    assert result == {
        'example.com/repos/testrepo': {
            'latest': {
                'action': 'unchanged',
                'repo': 'example.com/repos/testrepo',
                'reponame': 'testrepo',
                'tag': 'latest',
                'digest': INSPECT_DATA_1['Digest'],
                'old_digest': None,
                'created': format_time(INSPECT_DATA_1['Created']),
                'labels': INSPECT_DATA_1['Labels'],
                'os': INSPECT_DATA_1['Os'],
                'arch': INSPECT_DATA_1['Architecture'],
            },
            'stage': {
                'action': 'removed',
                'repo': 'example.com/repos/testrepo',
                'reponame': 'testrepo',
                'tag': 'stage',
                'digest': None,
                'old_digest': INSPECT_DATA_2['Digest'],
                'created': None,
                'labels': {},
                'os': None,
                'arch': None,
            }
        }
    }