class JoinSourceType(_StrEnum):
- PASSWORD = 'password'
- HTTP_URI = 'http_uri'
RESOURCE = 'resource'
class UserGroupSourceType(_StrEnum):
- INLINE = 'inline'
- HTTP_URI = 'http_uri'
RESOURCE = 'resource'
+ EMPTY = 'empty'
class ConfigNS(_StrEnum):
for idx, src in enumerate(checked(cluster.domain_settings).join_sources):
if src.source_type == JoinSourceType.RESOURCE:
javalues = checked(arefs[src.ref].auth)
- elif src.source_type == JoinSourceType.PASSWORD:
- javalues = checked(src.auth)
else:
raise ValueError(
f'unsupported join source type: {src.source_type}'
if ugsv.source_type == UserGroupSourceType.RESOURCE:
ugvalues = augs[ugsv.ref].values
assert ugvalues
- elif ugsv.source_type == UserGroupSourceType.INLINE:
- ugvalues = ugsv.values
- assert ugvalues
+ elif ugsv.source_type == UserGroupSourceType.EMPTY:
+ continue
else:
raise ValueError(
f'unsupported users/groups source type: {ugsv.source_type}'
class JoinSource(_RBase):
"""Represents data that can be used to join a system to Active Directory."""
- source_type: JoinSourceType
- auth: Optional[JoinAuthValues] = None
- uri: str = ''
+ source_type: JoinSourceType = JoinSourceType.RESOURCE
ref: str = ''
def validate(self) -> None:
- if self.ref:
+ if not self.ref:
+ raise ValueError('reference value must be specified')
+ else:
validation.check_id(self.ref)
@resourcelib.customize
def _customize_resource(rc: resourcelib.Resource) -> resourcelib.Resource:
- rc.uri.quiet = True
rc.ref.quiet = True
return rc
class UserGroupSource(_RBase):
"""Represents data used to set up user/group settings for an instance."""
- source_type: UserGroupSourceType
- values: Optional[UserGroupSettings] = None
- uri: str = ''
+ source_type: UserGroupSourceType = UserGroupSourceType.RESOURCE
ref: str = ''
def validate(self) -> None:
- if self.source_type == UserGroupSourceType.INLINE:
- pfx = 'inline User/Group configuration'
- if self.values is None:
- raise ValueError(pfx + ' requires values')
- if self.uri:
- raise ValueError(pfx + ' does not take a uri')
- if self.ref:
- raise ValueError(pfx + ' does not take a ref value')
- if self.source_type == UserGroupSourceType.HTTP_URI:
- pfx = 'http User/Group configuration'
- if not self.uri:
- raise ValueError(pfx + ' requires a uri')
- if self.values:
- raise ValueError(pfx + ' does not take inline values')
- if self.ref:
- raise ValueError(pfx + ' does not take a ref value')
if self.source_type == UserGroupSourceType.RESOURCE:
- pfx = 'resource reference User/Group configuration'
if not self.ref:
- raise ValueError(pfx + ' requires a ref value')
- if self.uri:
- raise ValueError(pfx + ' does not take a uri')
- if self.values:
- raise ValueError(pfx + ' does not take inline values')
+ raise ValueError('reference value must be specified')
+ else:
+ validation.check_id(self.ref)
+ else:
+ if self.ref:
+ raise ValueError('ref may not be specified')
@resourcelib.customize
def _customize_resource(rc: resourcelib.Resource) -> resourcelib.Resource:
- rc.uri.quiet = True
rc.ref.quiet = True
return rc
(smb.enums.State.UPDATED, "updated"),
(smb.enums.AuthMode.USER, "user"),
(smb.enums.AuthMode.ACTIVE_DIRECTORY, "active-directory"),
- (smb.enums.JoinSourceType.PASSWORD, "password"),
- (smb.enums.UserGroupSourceType.INLINE, "inline"),
],
)
def test_stringified(value, strval):
auth_mode=smb.enums.AuthMode.USER,
user_group_settings=[
smb.resources.UserGroupSource(
- source_type=smb.resources.UserGroupSourceType.INLINE,
- values=smb.resources.UserGroupSettings(
- users=[],
- groups=[],
- ),
+ source_type=smb.resources.UserGroupSourceType.EMPTY,
),
],
)
auth_mode=smb.enums.AuthMode.USER,
user_group_settings=[
smb.resources.UserGroupSource(
- source_type=smb.resources.UserGroupSourceType.INLINE,
- values=smb.resources.UserGroupSettings(
- users=[],
- groups=[],
- ),
+ source_type=smb.resources.UserGroupSourceType.EMPTY,
),
],
)
auth_mode=smb.enums.AuthMode.USER,
user_group_settings=[
smb.resources.UserGroupSource(
- source_type=smb.resources.UserGroupSourceType.INLINE,
- values=smb.resources.UserGroupSettings(
- users=[],
- groups=[],
- ),
+ source_type=smb.resources.UserGroupSourceType.EMPTY,
),
],
)
'intent': 'present',
'user_group_settings': [
{
- 'source_type': 'inline',
- 'values': {'users': [], 'groups': []},
+ 'source_type': 'empty',
}
],
}
'intent': 'present',
'user_group_settings': [
{
- 'source_type': 'inline',
- 'values': {'users': [], 'groups': []},
+ 'source_type': 'empty',
}
],
},
'intent': 'present',
'user_group_settings': [
{
- 'source_type': 'inline',
- 'values': {'users': [], 'groups': []},
+ 'source_type': 'empty',
}
],
}
'intent': 'present',
'user_group_settings': [
{
- 'source_type': 'inline',
- 'values': {'users': [], 'groups': []},
+ 'source_type': 'empty',
}
],
}
'intent': 'present',
'user_group_settings': [
{
- 'source_type': 'inline',
- 'values': {'users': [], 'groups': []},
+ 'source_type': 'empty',
}
],
},
'realm': 'dom1.example.com',
'join_sources': [
{
- 'source_type': 'password',
- 'auth': {
- 'username': 'testadmin',
- 'password': 'Passw0rd',
- },
+ 'source_type': 'resource',
+ 'ref': 'foo1',
}
],
},
},
+ 'join_auths.foo1': {
+ 'resource_type': 'ceph.smb.join.auth',
+ 'auth_id': 'foo1',
+ 'intent': 'present',
+ 'auth': {
+ 'username': 'testadmin',
+ 'password': 'Passw0rd',
+ },
+ },
'shares.foo.s1': {
'resource_type': 'ceph.smb.share',
'cluster_id': 'foo',
assert jdata == {'username': 'testadmin', 'password': 'Zm9vYmFyCg'}
-def test_apply_update_cluster_inline_pw(thandler):
- test_apply_full_cluster_create(thandler)
- to_apply = [
- smb.resources.Cluster(
- cluster_id='mycluster1',
- auth_mode=smb.enums.AuthMode.ACTIVE_DIRECTORY,
- domain_settings=smb.resources.DomainSettings(
- realm='MYDOMAIN.EXAMPLE.ORG',
- join_sources=[
- smb.resources.JoinSource(
- source_type=smb.enums.JoinSourceType.RESOURCE,
- ref='join1',
- ),
- smb.resources.JoinSource(
- source_type=smb.enums.JoinSourceType.PASSWORD,
- auth=smb.resources.JoinAuthValues(
- username='Jimmy',
- password='j4mb0ree!',
- ),
- ),
- ],
- ),
- ),
- ]
-
- results = thandler.apply(to_apply)
- assert results.success, results.to_simplified()
- assert len(list(results)) == 1
-
- assert 'mycluster1' in thandler.public_store.namespaces()
- ekeys = list(thandler.public_store.contents('mycluster1'))
- assert len(ekeys) == 5
- assert 'cluster-info' in ekeys
- assert 'config.smb' in ekeys
- assert 'spec.smb' in ekeys
- assert 'join.0.json' in ekeys
- assert 'join.1.json' in ekeys
-
- # we changed the password value. the store should reflect that
- jdata = thandler.public_store['mycluster1', 'join.0.json'].get()
- assert jdata == {'username': 'testadmin', 'password': 'Passw0rd'}
- # we changed the password value. the store should reflect that
- jdata2 = thandler.public_store['mycluster1', 'join.1.json'].get()
- assert jdata2 == {'username': 'Jimmy', 'password': 'j4mb0ree!'}
-
-
def test_apply_add_second_cluster(thandler):
test_apply_full_cluster_create(thandler)
to_apply = [
realm='YOURDOMAIN.EXAMPLE.ORG',
join_sources=[
smb.resources.JoinSource(
- source_type=smb.enums.JoinSourceType.PASSWORD,
- auth=smb.resources.JoinAuthValues(
- username='Jimmy',
- password='j4mb0ree!',
- ),
+ source_type=smb.enums.JoinSourceType.RESOURCE,
+ ref='coolcluster',
),
],
),
),
+ smb.resources.JoinAuth(
+ auth_id='coolcluster',
+ auth=smb.resources.JoinAuthValues(
+ username='Jimmy',
+ password='j4mb0ree!',
+ ),
+ linked_to_cluster='coolcluster',
+ ),
smb.resources.Share(
cluster_id='coolcluster',
share_id='images',
results = thandler.apply(to_apply)
assert results.success, results.to_simplified()
- assert len(list(results)) == 2
+ assert len(list(results)) == 3
assert 'mycluster1' in thandler.public_store.namespaces()
ekeys = list(thandler.public_store.contents('mycluster1'))
def test_all_resources(thandler):
test_apply_add_second_cluster(thandler)
rall = thandler.all_resources()
- assert len(rall) == 6
+ assert len(rall) == 7
assert rall[0].resource_type == 'ceph.smb.cluster'
assert rall[1].resource_type == 'ceph.smb.share'
assert rall[2].resource_type == 'ceph.smb.share'
assert rall[3].resource_type == 'ceph.smb.cluster'
assert rall[4].resource_type == 'ceph.smb.share'
assert rall[5].resource_type == 'ceph.smb.join.auth'
+ assert rall[6].resource_type == 'ceph.smb.join.auth'
@pytest.mark.parametrize(
'resource_type': 'ceph.smb.join.auth',
'auth_id': 'join1',
},
+ {
+ 'resource_type': 'ceph.smb.join.auth',
+ 'auth_id': 'coolcluster',
+ },
],
),
# cluster with id
join_sources:
- source_type: resource
ref: bob
- - source_type: password
- auth:
- username: Administrator
- password: fallb4kP4ssw0rd
---
resource_type: ceph.smb.share
cluster_id: chacha
assert cluster.intent == enums.Intent.PRESENT
assert cluster.auth_mode == enums.AuthMode.ACTIVE_DIRECTORY
assert cluster.domain_settings.realm == 'CEPH.SINK.TEST'
- assert len(cluster.domain_settings.join_sources) == 2
+ assert len(cluster.domain_settings.join_sources) == 1
jsrc = cluster.domain_settings.join_sources
assert jsrc[0].source_type == enums.JoinSourceType.RESOURCE
assert jsrc[0].ref == 'bob'
- assert jsrc[1].source_type == enums.JoinSourceType.PASSWORD
- assert jsrc[1].auth.username == 'Administrator'
- assert jsrc[1].auth.password == 'fallb4kP4ssw0rd'
assert isinstance(loaded[1], smb.resources.Share)
assert isinstance(loaded[2], smb.resources.Share)
"exc_type": ValueError,
"error": "not supported",
},
- # u/g inline missing
+ # u/g empty with extra ref
{
"yaml": """
resource_type: ceph.smb.cluster
intent: present
auth_mode: user
user_group_settings:
- - source_type: inline
-""",
- "exc_type": ValueError,
- "error": "requires values",
- },
- # u/g inline extra uri
- {
- "yaml": """
-resource_type: ceph.smb.cluster
-cluster_id: randolph
-intent: present
-auth_mode: user
-user_group_settings:
- - source_type: inline
- values:
- users: []
- groups: []
- uri: http://foo.bar.example.com/baz.txt
-""",
- "exc_type": ValueError,
- "error": "does not take",
- },
- # u/g inline extra ref
- {
- "yaml": """
-resource_type: ceph.smb.cluster
-cluster_id: randolph
-intent: present
-auth_mode: user
-user_group_settings:
- - source_type: inline
- values:
- users: []
- groups: []
+ - source_type: empty
ref: xyz
""",
"exc_type": ValueError,
- "error": "does not take",
- },
- # u/g uri missing
- {
- "yaml": """
-resource_type: ceph.smb.cluster
-cluster_id: randolph
-intent: present
-auth_mode: user
-user_group_settings:
- - source_type: http_uri
-""",
- "exc_type": ValueError,
- "error": "requires",
- },
- # u/g uri extra values
- {
- "yaml": """
-resource_type: ceph.smb.cluster
-cluster_id: randolph
-intent: present
-auth_mode: user
-user_group_settings:
- - source_type: http_uri
- values:
- users: []
- groups: []
- uri: http://foo.bar.example.com/baz.txt
-""",
- "exc_type": ValueError,
- "error": "does not take",
- },
- # u/g uri extra ref
- {
- "yaml": """
-resource_type: ceph.smb.cluster
-cluster_id: randolph
-intent: present
-auth_mode: user
-user_group_settings:
- - source_type: http_uri
- uri: http://boop.example.net
- ref: xyz
-""",
- "exc_type": ValueError,
- "error": "does not take",
+ "error": "ref may not be",
},
# u/g resource missing
{
- source_type: resource
""",
"exc_type": ValueError,
- "error": "requires",
- },
- # u/g resource extra values
- {
- "yaml": """
-resource_type: ceph.smb.cluster
-cluster_id: randolph
-intent: present
-auth_mode: user
-user_group_settings:
- - source_type: resource
- ref: xyz
- uri: http://example.net/foo
-""",
- "exc_type": ValueError,
- "error": "does not take",
- },
- # u/g resource extra resource
- {
- "yaml": """
-resource_type: ceph.smb.cluster
-cluster_id: randolph
-intent: present
-auth_mode: user
-user_group_settings:
- - source_type: resource
- ref: xyz
- values:
- users: []
- groups: []
-""",
- "exc_type": ValueError,
- "error": "does not take",
+ "error": "reference value must be",
},
],
)
auth_mode=smb.enums.AuthMode.USER,
user_group_settings=[
smb.resources.UserGroupSource(
- source_type=smb.resources.UserGroupSourceType.INLINE,
- values=smb.resources.UserGroupSettings(
- users=[],
- groups=[],
- ),
+ source_type=smb.resources.UserGroupSourceType.EMPTY,
),
],
)
auth_mode=smb.enums.AuthMode.USER,
user_group_settings=[
smb.resources.UserGroupSource(
- source_type=smb.resources.UserGroupSourceType.INLINE,
- values=smb.resources.UserGroupSettings(
- users=[],
- groups=[],
- ),
+ source_type=smb.resources.UserGroupSourceType.EMPTY,
),
],
)
auth_mode=smb.enums.AuthMode.USER,
user_group_settings=[
smb.resources.UserGroupSource(
- source_type=smb.resources.UserGroupSourceType.INLINE,
- values=smb.resources.UserGroupSettings(
- users=[],
- groups=[],
- ),
+ source_type=smb.resources.UserGroupSourceType.EMPTY,
),
],
)
'intent': 'present',
'user_group_settings': [
{
- 'source_type': 'inline',
- 'values': {'users': [], 'groups': []},
+ 'source_type': 'empty',
}
],
}
'intent': 'present',
'user_group_settings': [
{
- 'source_type': 'inline',
- 'values': {'users': [], 'groups': []},
+ 'source_type': 'empty',
}
],
},
'intent': 'present',
'user_group_settings': [
{
- 'source_type': 'inline',
- 'values': {'users': [], 'groups': []},
+ 'source_type': 'empty',
}
],
}
'intent': 'present',
'user_group_settings': [
{
- 'source_type': 'inline',
- 'values': {'users': [], 'groups': []},
+ 'source_type': 'empty',
}
],
}
'realm': 'dom1.example.com',
'join_sources': [
{
- 'source_type': 'password',
- 'auth': {
- 'username': 'testadmin',
- 'password': 'Passw0rd',
- },
+ 'source_type': 'resource',
+ 'ref': 'foo',
}
],
},
},
+ 'join_auths.foo': {
+ 'resource_type': 'ceph.smb.join.auth',
+ 'auth_id': 'foo',
+ 'intent': 'present',
+ 'auth': {
+ 'username': 'testadmin',
+ 'password': 'Passw0rd',
+ },
+ },
'shares.foo.s1': {
'resource_type': 'ceph.smb.share',
'cluster_id': 'foo',