]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
pybind/mgr/smb: add unit tests file tests/test_smb.py
authorJohn Mulligan <jmulligan@redhat.com>
Tue, 30 Jan 2024 19:33:29 +0000 (14:33 -0500)
committerJohn Mulligan <jmulligan@redhat.com>
Thu, 25 Apr 2024 23:10:39 +0000 (19:10 -0400)
Signed-off-by: John Mulligan <jmulligan@redhat.com>
src/pybind/mgr/smb/tests/test_smb.py [new file with mode: 0644]

diff --git a/src/pybind/mgr/smb/tests/test_smb.py b/src/pybind/mgr/smb/tests/test_smb.py
new file mode 100644 (file)
index 0000000..85bf98a
--- /dev/null
@@ -0,0 +1,602 @@
+import json
+
+import pytest
+
+import smb
+
+
+@pytest.fixture
+def tmodule():
+    internal_store = smb.config_store.MemConfigStore()
+    public_store = smb.config_store.MemConfigStore()
+    priv_store = smb.config_store.MemConfigStore()
+    return smb.module.Module(
+        'smb',
+        '',
+        '',
+        internal_store=internal_store,
+        public_store=public_store,
+        priv_store=priv_store,
+        path_resolver=smb.handler._FakePathResolver(),
+        authorizer=smb.handler._FakeAuthorizer(),
+        update_orchestration=False,
+    )
+
+
+def test_cluster_ls_empty(tmodule):
+    clusters = tmodule.cluster_ls()
+    assert clusters == []
+
+
+def test_share_ls_empty(tmodule):
+    clusters = tmodule.share_ls('foo')
+    assert clusters == []
+
+
+def test_internal_apply_cluster(tmodule):
+    cluster = smb.resources.Cluster(
+        cluster_id='foo',
+        auth_mode=smb.enums.AuthMode.USER,
+        user_group_settings=[
+            smb.resources.UserGroupSource(
+                source_type=smb.resources.UserGroupSourceType.INLINE,
+                values=smb.resources.UserGroupSettings(
+                    users=[],
+                    groups=[],
+                ),
+            ),
+        ],
+    )
+    rg = tmodule._handler.apply([cluster])
+    assert rg.success, rg.to_simplified()
+    assert ('clusters', 'foo') in tmodule._internal_store.data
+
+
+def test_cluster_add_cluster_ls(tmodule):
+    cluster = smb.resources.Cluster(
+        cluster_id='foo',
+        auth_mode=smb.enums.AuthMode.USER,
+        user_group_settings=[
+            smb.resources.UserGroupSource(
+                source_type=smb.resources.UserGroupSourceType.INLINE,
+                values=smb.resources.UserGroupSettings(
+                    users=[],
+                    groups=[],
+                ),
+            ),
+        ],
+    )
+    rg = tmodule._handler.apply([cluster])
+    assert rg.success, rg.to_simplified()
+
+    clusters = tmodule.cluster_ls()
+    assert len(clusters) == 1
+    assert 'foo' in clusters
+
+
+def test_internal_apply_cluster_and_share(tmodule):
+    cluster = smb.resources.Cluster(
+        cluster_id='foo',
+        auth_mode=smb.enums.AuthMode.USER,
+        user_group_settings=[
+            smb.resources.UserGroupSource(
+                source_type=smb.resources.UserGroupSourceType.INLINE,
+                values=smb.resources.UserGroupSettings(
+                    users=[],
+                    groups=[],
+                ),
+            ),
+        ],
+    )
+    share = smb.resources.Share(
+        cluster_id='foo',
+        share_id='s1',
+        name='Ess One',
+        cephfs=smb.resources.CephFSStorage(
+            volume='cephfs',
+            path='/',
+        ),
+    )
+    rg = tmodule._handler.apply([cluster, share])
+    assert rg.success, rg.to_simplified()
+    assert ('clusters', 'foo') in tmodule._internal_store.data
+    assert ('shares', 'foo.s1') in tmodule._internal_store.data
+
+    shares = tmodule.share_ls('foo')
+    assert len(shares) == 1
+    assert 's1' in shares
+
+
+def test_internal_apply_remove_cluster(tmodule):
+    tmodule._internal_store.overwrite(
+        {
+            "clusters.foo": {
+                'resource_type': 'ceph.smb.cluster',
+                'cluster_id': 'foo',
+                'auth_mode': 'user',
+                'intent': 'present',
+                'user_group_settings': [
+                    {
+                        'source_type': 'inline',
+                        'values': {'users': [], 'groups': []},
+                    }
+                ],
+            }
+        }
+    )
+
+    clusters = tmodule.cluster_ls()
+    assert len(clusters) == 1
+    assert 'foo' in clusters
+
+    rmcluster = smb.resources.RemovedCluster(
+        cluster_id='foo',
+    )
+    rg = tmodule._handler.apply([rmcluster])
+    assert rg.success, rg.to_simplified()
+
+    clusters = tmodule.cluster_ls()
+    assert len(clusters) == 0
+
+
+def test_internal_apply_remove_shares(tmodule):
+    tmodule._internal_store.overwrite(
+        {
+            'clusters.foo': {
+                'resource_type': 'ceph.smb.cluster',
+                'cluster_id': 'foo',
+                'auth_mode': 'user',
+                'intent': 'present',
+                'user_group_settings': [
+                    {
+                        'source_type': 'inline',
+                        'values': {'users': [], 'groups': []},
+                    }
+                ],
+            },
+            'shares.foo.s1': {
+                'resource_type': 'ceph.smb.share',
+                'cluster_id': 'foo',
+                'share_id': 's1',
+                'intent': 'present',
+                'name': 'Ess One',
+                'readonly': False,
+                'browseable': True,
+                'cephfs': {
+                    'volume': 'cephfs',
+                    'path': '/',
+                    'provider': 'samba-vfs',
+                },
+            },
+            'shares.foo.stwo': {
+                'resource_type': 'ceph.smb.share',
+                'cluster_id': 'foo',
+                'share_id': 'stwo',
+                'intent': 'present',
+                'name': 'Ess Two',
+                'readonly': False,
+                'browseable': True,
+                'cephfs': {
+                    'volume': 'cephfs',
+                    'path': '/two',
+                    'provider': 'samba-vfs',
+                },
+            },
+        }
+    )
+
+    shares = tmodule.share_ls('foo')
+    assert len(shares) == 2
+    assert 's1' in shares
+    assert 'stwo' in shares
+
+    rmshare1 = smb.resources.RemovedShare(
+        cluster_id='foo',
+        share_id='s1',
+    )
+    rg = tmodule._handler.apply([rmshare1])
+    assert rg.success, rg.to_simplified()
+
+    shares = tmodule.share_ls('foo')
+    assert len(shares) == 1
+
+    rmshare2 = smb.resources.RemovedShare(
+        cluster_id='foo',
+        share_id='stwo',
+    )
+    rg = tmodule._handler.apply([rmshare1, rmshare2])
+    assert rg.success, rg.to_simplified()
+
+    shares = tmodule.share_ls('foo')
+    assert len(shares) == 0
+
+    # check the results
+    rgs = rg.to_simplified()
+    assert rgs['success']
+    assert len(rgs['results']) == 2
+    assert rgs['results'][0]['success']
+    assert rgs['results'][0]['state'] == 'not present'
+    assert rgs['results'][1]['success']
+    assert rgs['results'][1]['state'] == 'removed'
+
+
+def test_internal_apply_add_joinauth(tmodule):
+    tmodule._internal_store.overwrite(
+        {
+            "clusters.foo": {
+                'resource_type': 'ceph.smb.cluster',
+                'cluster_id': 'foo',
+                'auth_mode': 'user',
+                'intent': 'present',
+                'user_group_settings': [
+                    {
+                        'source_type': 'inline',
+                        'values': {'users': [], 'groups': []},
+                    }
+                ],
+            }
+        }
+    )
+
+    assert len(tmodule._handler.join_auth_ids()) == 0
+    ja = smb.resources.JoinAuth(
+        auth_id='join1',
+        auth=smb.resources.JoinAuthValues(
+            username='testadmin',
+            password='Passw0rd',
+        ),
+    )
+    rg = tmodule._handler.apply([ja])
+    assert rg.success, rg.to_simplified()
+
+    assert len(tmodule._handler.join_auth_ids()) == 1
+
+
+def test_internal_apply_add_usergroups(tmodule):
+    tmodule._internal_store.overwrite(
+        {
+            "clusters.foo": {
+                'resource_type': 'ceph.smb.cluster',
+                'cluster_id': 'foo',
+                'auth_mode': 'user',
+                'intent': 'present',
+                'user_group_settings': [
+                    {
+                        'source_type': 'inline',
+                        'values': {'users': [], 'groups': []},
+                    }
+                ],
+            }
+        }
+    )
+
+    assert len(tmodule._handler.user_and_group_ids()) == 0
+    ja = smb.resources.UsersAndGroups(
+        users_groups_id='ug1',
+        values=smb.resources.UserGroupSettings(
+            users=[{"username": "foo"}],
+            groups=[],
+        ),
+    )
+    rg = tmodule._handler.apply([ja])
+    assert rg.success, rg.to_simplified()
+
+    assert len(tmodule._handler.user_and_group_ids()) == 1
+
+
+def _example_cfg_1(tmodule):
+    tmodule._internal_store.overwrite(
+        {
+            'clusters.foo': {
+                'resource_type': 'ceph.smb.cluster',
+                'cluster_id': 'foo',
+                'auth_mode': 'active-directory',
+                'intent': 'present',
+                'domain_settings': {
+                    'realm': 'dom1.example.com',
+                    'join_sources': [
+                        {
+                            'source_type': 'password',
+                            'auth': {
+                                'username': 'testadmin',
+                                'password': 'Passw0rd',
+                            },
+                        }
+                    ],
+                },
+            },
+            'shares.foo.s1': {
+                'resource_type': 'ceph.smb.share',
+                'cluster_id': 'foo',
+                'share_id': 's1',
+                'intent': 'present',
+                'name': 'Ess One',
+                'readonly': False,
+                'browseable': True,
+                'cephfs': {
+                    'volume': 'cephfs',
+                    'path': '/',
+                    'provider': 'samba-vfs',
+                },
+            },
+            'shares.foo.stwo': {
+                'resource_type': 'ceph.smb.share',
+                'cluster_id': 'foo',
+                'share_id': 'stwo',
+                'intent': 'present',
+                'name': 'Ess Two',
+                'readonly': False,
+                'browseable': True,
+                'cephfs': {
+                    'volume': 'cephfs',
+                    'path': '/two',
+                    'provider': 'samba-vfs',
+                },
+            },
+        }
+    )
+
+
+def test_cmd_share_ls_json(tmodule):
+    _example_cfg_1(tmodule)
+
+    res, body, status = tmodule.share_ls.command('foo')
+    assert res == 0
+    bdata = json.loads(body)
+    assert 's1' in bdata
+    assert 'stwo' in bdata
+    assert not status
+
+
+def test_cmd_share_ls_yaml(tmodule):
+    _example_cfg_1(tmodule)
+
+    res, body, status = tmodule.share_ls.command('foo', format='yaml')
+    assert res == 0
+    assert '- s1\n' in body
+    assert '- stwo\n' in body
+    assert not status
+
+
+def test_cmd_share_rm(tmodule):
+    _example_cfg_1(tmodule)
+
+    res, body, status = tmodule.share_rm.command('foo', 'stwo')
+    assert res == 0
+    bdata = json.loads(body)
+    assert bdata['state'] == 'removed'
+
+    res, body, status = tmodule.share_rm.command('fake', 'curly')
+    assert res == 0
+    bdata = json.loads(body)
+    assert bdata['state'] == 'not present'
+
+
+def test_cmd_share_create(tmodule):
+    _example_cfg_1(tmodule)
+
+    res, body, status = tmodule.share_create.command(
+        cluster_id='foo',
+        share_id='nu1',
+        share_name='The Nu One',
+        path='/nu/one',
+        cephfs_volume='cephfs',
+    )
+    assert res == 0
+    bdata = json.loads(body)
+    assert bdata['state'] == 'created'
+
+
+def test_cmd_apply_share(tmodule):
+    _example_cfg_1(tmodule)
+
+    inbuf = json.dumps(
+        {
+            'resource_type': 'ceph.smb.share',
+            'cluster_id': 'foo',
+            'share_id': 'test1',
+            'cephfs': {
+                'volume': 'example',
+                'path': '/primrose',
+            },
+        }
+    )
+
+    res, body, status = tmodule.apply_resources.command(inbuf=inbuf)
+    assert res == 0
+    bdata = json.loads(body)
+    assert bdata["success"]
+    assert bdata["results"][0]["state"] == "created"
+
+
+def test_share_dump_config(tmodule):
+    _example_cfg_1(tmodule)
+
+    cfg = tmodule.dump_config('foo')
+    assert cfg == {
+        'samba-container-config': "v0",
+        'configs': {
+            'foo': {
+                'instance_name': 'foo',
+                'instance_features': [],
+                'shares': ['Ess One', 'Ess Two'],
+                'globals': ['default', 'foo'],
+            },
+        },
+        'shares': {
+            'Ess One': {
+                'options': {
+                    'path': '/',
+                    'read only': 'No',
+                    'browseable': 'Yes',
+                    'kernel share modes': 'no',
+                    'x:ceph:id': 'foo.s1',
+                    'vfs objects': 'ceph',
+                    'ceph:config_file': '/etc/ceph/ceph.conf',
+                    'ceph:filesystem': 'cephfs',
+                    'ceph:user_id': 'smb.fs.cluster.foo',
+                },
+            },
+            'Ess Two': {
+                'options': {
+                    'path': '/two',
+                    'read only': 'No',
+                    'browseable': 'Yes',
+                    'kernel share modes': 'no',
+                    'x:ceph:id': 'foo.stwo',
+                    'vfs objects': 'ceph',
+                    'ceph:config_file': '/etc/ceph/ceph.conf',
+                    'ceph:filesystem': 'cephfs',
+                    'ceph:user_id': 'smb.fs.cluster.foo',
+                },
+            },
+        },
+        'globals': {
+            'default': {
+                'options': {
+                    'server min protocol': 'SMB2',
+                    'load printers': 'No',
+                    'printing': 'bsd',
+                    'printcap name': '/dev/null',
+                    'disable spoolss': 'Yes',
+                },
+            },
+            'foo': {
+                'options': {
+                    'idmap config * : backend': 'autorid',
+                    'idmap config * : range': '2000-9999999',
+                    'realm': 'dom1.example.com',
+                    'security': 'ads',
+                    'workgroup': 'DOM1',
+                },
+            },
+        },
+    }
+
+
+def test_cluster_create_ad1(tmodule):
+    _example_cfg_1(tmodule)
+
+    result = tmodule.cluster_create(
+        'fizzle',
+        smb.enums.AuthMode.ACTIVE_DIRECTORY,
+        domain_realm='fizzle.example.net',
+        domain_join_user_pass=['Administrator%Passw0rd'],
+    )
+    assert result.success
+    assert result.status['state'] == 'created'
+    assert result.src.cluster_id == 'fizzle'
+    assert result.src.domain_settings.realm == 'fizzle.example.net'
+    assert len(result.src.domain_settings.join_sources) == 1
+    assert (
+        result.src.domain_settings.join_sources[0].source_type
+        == smb.enums.JoinSourceType.PASSWORD
+    )
+    assert (
+        result.src.domain_settings.join_sources[0].auth.username
+        == 'Administrator'
+    )
+    assert (
+        result.src.domain_settings.join_sources[0].auth.password == 'Passw0rd'
+    )
+
+
+def test_cluster_create_ad2(tmodule):
+    _example_cfg_1(tmodule)
+
+    ja = smb.resources.JoinAuth(
+        auth_id='jaad2',
+        auth=smb.resources.JoinAuthValues(
+            username='Administrator',
+            password='hunter2',
+        ),
+    )
+    rg = tmodule._handler.apply([ja])
+    assert rg.success, rg.to_simplified()
+
+    result = tmodule.cluster_create(
+        'sizzle',
+        smb.enums.AuthMode.ACTIVE_DIRECTORY,
+        domain_realm='sizzle.example.net',
+        domain_join_ref=['jaad2'],
+    )
+    assert result.success
+    assert result.status['state'] == 'created'
+    assert result.src.cluster_id == 'sizzle'
+    assert result.src.domain_settings.realm == 'sizzle.example.net'
+    assert len(result.src.domain_settings.join_sources) == 1
+    assert (
+        result.src.domain_settings.join_sources[0].source_type
+        == smb.enums.JoinSourceType.RESOURCE
+    )
+    assert result.src.domain_settings.join_sources[0].ref == 'jaad2'
+
+
+def test_cluster_create_user1(tmodule):
+    _example_cfg_1(tmodule)
+
+    ug = smb.resources.UsersAndGroups(
+        users_groups_id='ug1',
+        values=smb.resources.UserGroupSettings(
+            users=[{"username": "foo"}],
+            groups=[],
+        ),
+    )
+    rg = tmodule._handler.apply([ug])
+    assert rg.success, rg.to_simplified()
+
+    result = tmodule.cluster_create(
+        'dizzle',
+        smb.enums.AuthMode.USER,
+        user_group_ref=['ug1'],
+    )
+    assert result.success
+    assert result.status['state'] == 'created'
+    assert result.src.cluster_id == 'dizzle'
+    assert len(result.src.user_group_settings) == 1
+
+
+def test_cluster_create_badpass(tmodule):
+    _example_cfg_1(tmodule)
+
+    with pytest.raises(ValueError):
+        tmodule.cluster_create(
+            'fizzle',
+            smb.enums.AuthMode.ACTIVE_DIRECTORY,
+            domain_realm='fizzle.example.net',
+            domain_join_user_pass=['Administrator'],
+        )
+
+
+def test_cluster_rm(tmodule):
+    _example_cfg_1(tmodule)
+
+    result = tmodule.share_rm('foo', 'stwo')
+    assert result.success
+    result = tmodule.share_rm('foo', 's1')
+    assert result.success
+    result = tmodule.cluster_rm('foo')
+    assert result.success
+
+
+def test_dump_service_spec(tmodule):
+    _example_cfg_1(tmodule)
+    tmodule._public_store.overwrite(
+        {
+            'foo.config.smb': '',
+        }
+    )
+    tmodule._priv_store.overwrite(
+        {
+            'foo.join.2b9902c05d08bcba.json': '',
+            'foo.join.08129d4d3b8c37c7.json': '',
+        }
+    )
+
+    cfg = tmodule.dump_service_spec('foo')
+    assert cfg
+    assert cfg['service_id'] == 'foo'
+    assert cfg['spec']['cluster_id'] == 'foo'
+    assert cfg['spec']['features'] == ['domain']
+    assert cfg['spec']['config_uri'] == 'mem:foo/config.smb'
+    assert len(cfg['spec']['join_sources']) == 2