コード例 #1
0
def test_update_cluster_set_lifespan_forbidden(client, mocker):
    mocker.patch(
        'rhub.api.lab.cluster._user_can_set_lifespan').return_value = False

    region = _create_test_region()
    region.lifespan_length = 30
    product = _create_test_product()
    cluster = model.Cluster(
        id=1,
        name='testcluster',
        description='test cluster',
        user_id='00000000-0000-0000-0000-000000000000',
        group_id=None,
        created=datetime.datetime(2021, 1, 1, 1, 0, 0, tzinfo=tzutc()),
        region_id=region.id,
        region=region,
        reservation_expiration=None,
        lifespan_expiration=None,
        status=model.ClusterStatus.ACTIVE,
        product_id=1,
        product_params={},
        product=product,
    )
    model.Cluster.query.get.return_value = cluster

    rv = client.patch(
        f'{API_BASE}/lab/cluster/1',
        headers={'Authorization': 'Bearer foobar'},
        json={
            'lifespan_expiration': '2100-01-01T00:00:00Z',
        },
    )

    assert rv.status_code == 403
コード例 #2
0
def test_update_cluster_ro_field(client, cluster_data):
    region = _create_test_region()
    product = _create_test_product()
    cluster = model.Cluster(
        id=1,
        name='testcluster',
        description='test cluster',
        user_id='00000000-0000-0000-0000-000000000000',
        group_id=None,
        created=datetime.datetime(2021, 1, 1, 1, 0, 0, tzinfo=tzutc()),
        region_id=region.id,
        region=region,
        reservation_expiration=None,
        lifespan_expiration=None,
        status=model.ClusterStatus.ACTIVE,
        product_id=1,
        product_params={},
        product=product,
    )
    model.Cluster.query.get.return_value = cluster

    rv = client.patch(
        f'{API_BASE}/lab/cluster/1',
        headers={'Authorization': 'Bearer foobar'},
        json=cluster_data,
    )

    assert rv.status_code == 400
コード例 #3
0
def test_update_cluster_exceeded_reservation(client):
    region = _create_test_region()
    region.reservation_expiration_max = 1
    product = _create_test_product()
    cluster = model.Cluster(
        id=1,
        name='testcluster',
        description='test cluster',
        user_id='00000000-0000-0000-0000-000000000000',
        group_id=None,
        created=datetime.datetime(2021, 1, 1, 1, 0, 0, tzinfo=tzutc()),
        region_id=region.id,
        region=region,
        reservation_expiration=None,
        lifespan_expiration=None,
        status=model.ClusterStatus.ACTIVE,
        product_id=1,
        product_params={},
        product=product,
    )
    model.Cluster.query.get.return_value = cluster

    new_expiration = datetime.datetime(2100, 1, 1, 0, 0, tzinfo=tzutc())

    rv = client.patch(
        f'{API_BASE}/lab/cluster/1',
        headers={'Authorization': 'Bearer foobar'},
        json={
            'reservation_expiration': new_expiration,
        },
    )

    assert rv.status_code == 403
    assert rv.json['detail'] == 'Exceeded maximal reservation time.'
コード例 #4
0
def test_create_cluster_hosts(client, db_session_mock):
    model.Cluster.query.get.return_value = model.Cluster(
        id=1,
        name='testcluster',
        description='test cluster',
        user_id='00000000-0000-0000-0000-000000000000',
        group_id=None,
        created=datetime.datetime(2021, 1, 1, 1, 0, 0, tzinfo=tzutc()),
        region_id=1,
        reservation_expiration=None,
        lifespan_expiration=None,
        status=model.ClusterStatus.ACTIVE,
    )
    hosts_data = [
        {
            'fqdn': 'host0.example.com',
            'ipaddr': ['1.2.3.4'],
            'num_vcpus': 2,
            'ram_mb': 2048,
            'num_volumes': 3,
            'volumes_gb': 30,
        },
        {
            'fqdn': 'host1.example.com',
            'ipaddr': ['1:2::3:4'],
            'num_vcpus': 2,
            'ram_mb': 2048,
            'num_volumes': 3,
            'volumes_gb': 30,
        },
    ]

    rv = client.post(
        f'{API_BASE}/lab/cluster/1/hosts',
        headers={'Authorization': 'Bearer foobar'},
        json=hosts_data,
    )

    assert rv.status_code == 200

    db_session_mock.add_all.assert_called()
    db_session_mock.commit.assert_called()

    hosts = db_session_mock.add_all.call_args.args[0]
    for host_data, host_row in zip(hosts_data, hosts):
        for k, v in host_data.items():
            assert getattr(host_row, k) == v
コード例 #5
0
def test_update_cluster_reservation(client, keycloak_mock, db_session_mock):
    user_id = '00000000-0000-0000-0000-000000000000'
    keycloak_mock.user_get.return_value = {
        'id': user_id,
        'username': '******'
    }
    region = _create_test_region()
    product = _create_test_product()

    old_expiration = datetime.datetime(2100, 1, 1, 0, 0, tzinfo=tzutc())
    new_expiration = datetime.datetime(2100, 1, 2, 0, 0, tzinfo=tzutc())

    cluster = model.Cluster(
        id=1,
        name='testcluster',
        description='test cluster',
        user_id='00000000-0000-0000-0000-000000000000',
        group_id=None,
        created=datetime.datetime(2021, 1, 1, 1, 0, 0, tzinfo=tzutc()),
        region_id=region.id,
        region=region,
        reservation_expiration=old_expiration,
        lifespan_expiration=None,
        status=model.ClusterStatus.ACTIVE,
        product_id=1,
        product_params={},
        product=product,
    )
    model.Cluster.query.get.return_value = cluster

    rv = client.patch(
        f'{API_BASE}/lab/cluster/1',
        headers={'Authorization': 'Bearer foobar'},
        json={
            'reservation_expiration': new_expiration,
        },
    )

    assert rv.status_code == 200
    assert cluster.reservation_expiration == new_expiration

    event = db_session_mock.add.call_args_list[0].args[0]
    assert event.type == model.ClusterEventType.RESERVATION_CHANGE
    assert event.old_value == old_expiration
    assert event.new_value == new_expiration
コード例 #6
0
def test_update_cluster(client, keycloak_mock, db_session_mock):
    region = _create_test_region()
    product = _create_test_product()
    user_id = '00000000-0000-0000-0000-000000000000'
    keycloak_mock.user_get.return_value = {
        'id': user_id,
        'username': '******'
    }
    keycloak_mock.group_get.return_value = {'id': None, 'name': 'None'}
    cluster = model.Cluster(
        id=1,
        name='testcluster',
        description='test cluster',
        user_id='00000000-0000-0000-0000-000000000000',
        group_id=None,
        created=datetime.datetime(2021, 1, 1, 1, 0, 0, tzinfo=tzutc()),
        region_id=region.id,
        region=region,
        reservation_expiration=None,
        lifespan_expiration=None,
        status=model.ClusterStatus.ACTIVE,
        product_id=1,
        product_params={},
        product=product,
    )
    model.Cluster.query.get.return_value = cluster

    rv = client.patch(
        f'{API_BASE}/lab/cluster/1',
        headers={'Authorization': 'Bearer foobar'},
        json={
            'description': 'test change',
            'group_id': '00000001-0002-0003-0004-000000000000',
        },
    )

    assert rv.status_code == 200

    db_session_mock.commit.assert_called()

    assert cluster.description == 'test change'
    assert cluster.group_id == '00000001-0002-0003-0004-000000000000'
コード例 #7
0
def test_delete_cluster_hosts(client, db_session_mock):
    hosts = [
        model.ClusterHost(
            id=1,
            cluster_id=1,
            fqdn='host0.example.com',
            ipaddr=['1.2.3.4'],
        ),
        model.ClusterHost(
            id=2,
            cluster_id=1,
            fqdn='host1.example.com',
            ipaddr=['1:2::3:4'],
        ),
    ]
    cluster = model.Cluster(
        id=1,
        name='testcluster',
        description='test cluster',
        user_id='00000000-0000-0000-0000-000000000000',
        group_id=None,
        created=datetime.datetime(2021, 1, 1, 1, 0, 0, tzinfo=tzutc()),
        region_id=1,
        reservation_expiration=None,
        lifespan_expiration=None,
        status=model.ClusterStatus.ACTIVE,
        hosts=hosts,
    )
    model.Cluster.query.get.return_value = cluster

    rv = client.delete(
        f'{API_BASE}/lab/cluster/1/hosts',
        headers={'Authorization': 'Bearer foobar'},
    )

    assert rv.status_code == 204

    for host in hosts:
        db_session_mock.delete.assert_any_call(host)
    db_session_mock.commit.assert_called()
コード例 #8
0
def test_get_cluster_events(client):
    events = [
        model.ClusterTowerJobEvent(
            id=1,
            date=datetime.datetime(2021, 1, 1, 1, 0, 0, tzinfo=tzutc()),
            user_id='00000000-0000-0000-0000-000000000000',
            cluster_id=1,
            tower_id=1,
            tower=tower_model.Server(id=1),
            tower_job_id=1,
            status=model.ClusterStatus.POST_PROVISIONING,
        ),
        model.ClusterReservationChangeEvent(
            id=2,
            date=datetime.datetime(2021, 1, 1, 2, 0, 0, tzinfo=tzutc()),
            user_id='00000000-0000-0000-0000-000000000000',
            cluster_id=1,
            old_value=None,
            new_value=datetime.datetime(2021, 2, 1, 0, 0, 0, tzinfo=tzutc()),
        ),
    ]
    cluster = model.Cluster(
        id=1,
        name='testcluster',
        description='test cluster',
        user_id='00000000-0000-0000-0000-000000000000',
        group_id=None,
        created=datetime.datetime(2021, 1, 1, 1, 0, 0, tzinfo=tzutc()),
        region_id=1,
        reservation_expiration=None,
        lifespan_expiration=None,
        status=model.ClusterStatus.ACTIVE,
        events=events,
    )
    model.Cluster.query.get.return_value = cluster

    rv = client.get(
        f'{API_BASE}/lab/cluster/1/events',
        headers={'Authorization': 'Bearer foobar'},
    )

    assert rv.status_code == 200

    model.Cluster.query.get.assert_called_with(1)

    assert rv.json == [
        {
            'id': 1,
            'type': model.ClusterEventType.TOWER_JOB.value,
            'cluster_id': 1,
            'date': '2021-01-01T01:00:00+00:00',
            'user_id': '00000000-0000-0000-0000-000000000000',
            'user_name': 'test-user',
            'tower_id': 1,
            'tower_job_id': 1,
            'status': model.ClusterStatus.POST_PROVISIONING.value,
            '_href': ANY,
        },
        {
            'id': 2,
            'type': model.ClusterEventType.RESERVATION_CHANGE.value,
            'cluster_id': 1,
            'date': '2021-01-01T02:00:00+00:00',
            'user_id': '00000000-0000-0000-0000-000000000000',
            'user_name': 'test-user',
            'old_value': None,
            'new_value': '2021-02-01T00:00:00+00:00',
            '_href': ANY,
        },
    ]
コード例 #9
0
def test_delete_cluster(client, db_session_mock, keycloak_mock, mocker):
    region = _create_test_region()
    product = _create_test_product()
    cluster = model.Cluster(
        id=1,
        name='testcluster',
        description='test cluster',
        user_id='00000000-0000-0000-0000-000000000000',
        group_id=None,
        created=datetime.datetime(2021, 1, 1, 1, 0, 0, tzinfo=tzutc()),
        region_id=region.id,
        region=region,
        reservation_expiration=None,
        lifespan_expiration=None,
        status=model.ClusterStatus.ACTIVE,
        product_id=product.id,
        product_params={},
        product=product,
    )
    model.Cluster.query.get.return_value = cluster

    keycloak_mock.user_get.return_value = {'username': '******'}

    mocker.patch.object(cluster.region, 'tower')
    mocker.patch.object(cluster.region.tower, 'create_tower_client')
    cluster.region.tower.create_tower_client.return_value = (tower_client_mock
                                                             := mocker.Mock(
                                                                 name='foo'))

    tower_client_mock.template_get.return_value = {
        'id': 123,
        'name': 'dummy-delete'
    }
    tower_client_mock.template_launch.return_value = {'id': 321}

    rv = client.delete(
        f'{API_BASE}/lab/cluster/1',
        headers={'Authorization': 'Bearer foobar'},
    )

    assert rv.status_code == 204

    region.tower.create_tower_client.assert_called()
    tower_client_mock.template_get.assert_called_with(
        template_name='dummy-delete')
    tower_client_mock.template_launch.assert_called_with(
        123, {
            'extra_vars': {
                'rhub_cluster_id': 1,
                'rhub_cluster_name': 'testcluster',
                'rhub_product_id': product.id,
                'rhub_product_name': product.name,
                'rhub_region_id': region.id,
                'rhub_region_name': region.name,
                'rhub_user_id': cluster.user_id,
                'rhub_user_name': 'test-user',
            },
        })

    db_session_mock.delete.assert_called_with(cluster)
    db_session_mock.commit.assert_called()
コード例 #10
0
def test_list_clusters(client, keycloak_mock, mocker):
    user_id = '00000000-0000-0000-0000-000000000000'
    sample_region = _create_test_region()
    sample_product = _create_test_product()
    keycloak_mock.user_get.return_value = {
        'id': user_id,
        'username': '******'
    }
    model.Cluster.query.limit.return_value.offset.return_value = [
        model.Cluster(
            id=1,
            name='testcluster',
            description='test cluster',
            user_id='00000000-0000-0000-0000-000000000000',
            group_id=None,
            created=datetime.datetime(2021, 1, 1, 1, 0, 0, tzinfo=tzutc()),
            region_id=1,
            region=sample_region,
            reservation_expiration=None,
            lifespan_expiration=None,
            status=model.ClusterStatus.ACTIVE,
            product_id=1,
            product_params={},
            product=sample_product,
        ),
    ]
    mocker.patch.object(model.Cluster, 'hosts', [])
    mocker.patch.object(model.Cluster, 'quota', None)
    model.Cluster.query.count.return_value = 1

    rv = client.get(
        f'{API_BASE}/lab/cluster',
        headers={'Authorization': 'Bearer foobar'},
    )
    keycloak_mock.user_get.assert_called_with(user_id)

    assert rv.status_code == 200
    assert rv.json == {
        'data': [
            {
                'id': 1,
                'name': 'testcluster',
                'description': 'test cluster',
                'user_id': '00000000-0000-0000-0000-000000000000',
                'group_id': None,
                'created': '2021-01-01T01:00:00+00:00',
                'region_id': 1,
                'reservation_expiration': None,
                'lifespan_expiration': None,
                'status': model.ClusterStatus.ACTIVE.value,
                'region_name': 'test',
                'user_name': 'test-user',
                'group_name': None,
                'hosts': [],
                'quota': None,
                'quota_usage': None,
                'product_id': 1,
                'product_name': 'dummy',
                'product_params': {},
                'shared': False,
                '_href': ANY,
            },
        ],
        'total':
        1,
    }
コード例 #11
0
def test_get_cluster(client, keycloak_mock, mocker):
    user_id = '00000000-0000-0000-0000-000000000000'
    sample_region = _create_test_region()
    sample_product = _create_test_product()
    keycloak_mock.user_get.return_value = {
        'id': user_id,
        'username': '******'
    }

    model.Cluster.query.get.return_value = model.Cluster(
        id=1,
        name='testcluster',
        description='test cluster',
        user_id='00000000-0000-0000-0000-000000000000',
        group_id=None,
        created=datetime.datetime(2021, 1, 1, 1, 0, 0, tzinfo=tzutc()),
        region_id=1,
        region=sample_region,
        reservation_expiration=None,
        lifespan_expiration=None,
        status=model.ClusterStatus.ACTIVE,
        product_id=1,
        product_params={},
        product=sample_product,
    )
    mocker.patch.object(model.Cluster, 'hosts', [
        model.ClusterHost(
            id=1,
            cluster_id=1,
            fqdn='test0.localhost',
            ipaddr=['127.0.0.1', '::1'],
            num_vcpus=2,
            ram_mb=4096,
            num_volumes=1,
            volumes_gb=20,
        ),
        model.ClusterHost(
            id=2,
            cluster_id=1,
            fqdn='test1.localhost',
            ipaddr=['127.0.0.1', '::1'],
            num_vcpus=2,
            ram_mb=4096,
            num_volumes=1,
            volumes_gb=20,
        ),
    ])
    mocker.patch.object(
        model.Cluster, 'quota',
        model.Quota(
            id=1,
            num_vcpus=20,
            ram_mb=20000,
            num_volumes=2,
            volumes_gb=200,
        ))

    rv = client.get(
        f'{API_BASE}/lab/cluster/1',
        headers={'Authorization': 'Bearer foobar'},
    )

    assert rv.status_code == 200

    model.Cluster.query.get.assert_called_with(1)
    keycloak_mock.user_get.assert_called_with(user_id)

    assert rv.json == {
        'id':
        1,
        'name':
        'testcluster',
        'description':
        'test cluster',
        'user_id':
        '00000000-0000-0000-0000-000000000000',
        'group_id':
        None,
        'created':
        '2021-01-01T01:00:00+00:00',
        'region_id':
        1,
        'reservation_expiration':
        None,
        'lifespan_expiration':
        None,
        'status':
        model.ClusterStatus.ACTIVE.value,
        'region_name':
        'test',
        'user_name':
        'test-user',
        'group_name':
        None,
        'hosts': [{
            'id': 1,
            'cluster_id': 1,
            'fqdn': 'test0.localhost',
            'ipaddr': ['127.0.0.1', '::1'],
            'num_vcpus': 2,
            'ram_mb': 4096,
            'num_volumes': 1,
            'volumes_gb': 20,
        }, {
            'id': 2,
            'cluster_id': 1,
            'fqdn': 'test1.localhost',
            'ipaddr': ['127.0.0.1', '::1'],
            'num_vcpus': 2,
            'ram_mb': 4096,
            'num_volumes': 1,
            'volumes_gb': 20,
        }],
        'quota': {
            'num_vcpus': 20,
            'ram_mb': 20000,
            'num_volumes': 2,
            'volumes_gb': 200,
        },
        'quota_usage': {
            'num_vcpus': 4,
            'ram_mb': 8192,
            'num_volumes': 2,
            'volumes_gb': 40,
        },
        'product_id':
        1,
        'product_name':
        'dummy',
        'product_params': {},
        'shared':
        False,
        '_href':
        ANY,
    }
コード例 #12
0
def test_get_cluster_hosts(client):
    model.Cluster.query.get.return_value = model.Cluster(
        id=1,
        name='testcluster',
        description='test cluster',
        user_id='00000000-0000-0000-0000-000000000000',
        group_id=None,
        created=datetime.datetime(2021, 1, 1, 1, 0, 0, tzinfo=tzutc()),
        region_id=1,
        reservation_expiration=None,
        lifespan_expiration=None,
        status=model.ClusterStatus.ACTIVE,
        hosts=[
            model.ClusterHost(
                id=1,
                cluster_id=1,
                fqdn='host0.example.com',
                ipaddr=['1.2.3.4'],
                num_vcpus=2,
                ram_mb=2048,
                num_volumes=3,
                volumes_gb=30,
            ),
            model.ClusterHost(
                id=2,
                cluster_id=1,
                fqdn='host1.example.com',
                ipaddr=['1:2::3:4'],
                num_vcpus=2,
                ram_mb=2048,
                num_volumes=3,
                volumes_gb=30,
            ),
        ],
    )

    rv = client.get(
        f'{API_BASE}/lab/cluster/1/hosts',
        headers={'Authorization': 'Bearer foobar'},
    )

    assert rv.status_code == 200

    model.Cluster.query.get.assert_called_with(1)

    assert rv.json == [
        {
            'id': 1,
            'cluster_id': 1,
            'fqdn': 'host0.example.com',
            'ipaddr': ['1.2.3.4'],
            'num_vcpus': 2,
            'ram_mb': 2048,
            'num_volumes': 3,
            'volumes_gb': 30,
            '_href': ANY,
        },
        {
            'id': 2,
            'cluster_id': 1,
            'fqdn': 'host1.example.com',
            'ipaddr': ['1:2::3:4'],
            'num_vcpus': 2,
            'ram_mb': 2048,
            'num_volumes': 3,
            'volumes_gb': 30,
            '_href': ANY,
        },
    ]