Skip to content

Commit

Permalink
Unity: supports modification of NFS/CIFS server (#373)
Browse files Browse the repository at this point in the history
Major changes:
- Supports modification of NFS/CIFS server
- Supports modification of virus checker
- Supports file uploading/downloading for NAS server
  • Loading branch information
yong-huang authored Jun 16, 2022
1 parent 3144379 commit ccfccba
Show file tree
Hide file tree
Showing 15 changed files with 213 additions and 9 deletions.
2 changes: 2 additions & 0 deletions storops/unity/parser_configs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,8 @@ UnityNfsServer:
converter: UnityNasServer
- label: fileInterfaces
converter: UnityFileInterfaceList
- label: nfsv3Enabled
key: nfs_v3_enabled
- label: nfsv4Enabled
key: nfs_v4_enabled
- label: isSecureEnabled
Expand Down
15 changes: 15 additions & 0 deletions storops/unity/resource/cifs_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,21 @@ def delete(self, skip_domain_unjoin=None, username=None,
resp.raise_if_err()
return resp

def modify(self, netbios_name=None, name=None,
domain=None, domain_username=None, domain_password=None,
workgroup=None, local_password=None):
req_body = self._cli.make_body(netbiosName=netbios_name,
name=name,
domain=domain,
domainUsername=domain_username,
domainPassword=domain_password,
workgroup=workgroup,
localAdminPassword=local_password)

resp = self.action('modify', **req_body)
resp.raise_if_err()
return resp


class UnityCifsServerList(resource.UnityResourceList):
@classmethod
Expand Down
43 changes: 38 additions & 5 deletions storops/unity/resource/nas_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,17 @@

log = logging.getLogger(__name__)

FILE_TYPES = {
"ldap_cfg": 1,
"ldap_ca": 2,
"virus_cfg": 4,
"users": 5,
"group": 6,
"hosts": 7,
"net_groups": 8,
"home_dir": 11
}


class UnityNasServer(UnityResource):
@classmethod
Expand Down Expand Up @@ -113,23 +124,28 @@ def enable_cifs_service(self, interfaces=None,
local_password=local_password)

def create_nfs_server(self, host_name=None, nfs_v4_enabled=True,
kdc_type=None, kdc_username=None, kdc_password=None):
kdc_type=None, kdc_username=None, kdc_password=None,
nfs_v3_enabled=None, credentials_cache_ttl=None):
clz = storops.unity.resource.nfs_server.UnityNfsServer
return clz.create(self._cli, self,
host_name=host_name,
nfs_v4_enabled=nfs_v4_enabled,
kdc_type=kdc_type,
kdc_username=kdc_username,
kdc_password=kdc_password)
kdc_password=kdc_password,
nfs_v3_enabled=nfs_v3_enabled,
credentials_cache_ttl=credentials_cache_ttl)

def enable_nfs_service(self, host_name=None, nfs_v4_enabled=True,
kdc_type=None, kdc_username=None,
kdc_password=None):
kdc_type=None, kdc_username=None, kdc_password=None,
nfs_v3_enabled=None, credentials_cache_ttl=None):
self.create_nfs_server(host_name=host_name,
nfs_v4_enabled=nfs_v4_enabled,
kdc_type=kdc_type,
kdc_username=kdc_username,
kdc_password=kdc_password)
kdc_password=kdc_password,
nfs_v3_enabled=nfs_v3_enabled,
credentials_cache_ttl=credentials_cache_ttl)

def create_dns_server(self, domain, *ip_list):
clz = storops.unity.resource.dns_server.UnityFileDnsServer
Expand Down Expand Up @@ -264,6 +280,23 @@ def modify(self, name=None, sp=None, is_replication_destination=None,
resp.raise_if_err()
return resp

def upload_file(self, file_type, file_name):
file_type_idx = FILE_TYPES.get(file_type)
files = {'filename': file_name}
resp = self._cli.rest_post('/upload/{}/nasServer/{}'.format(
file_type_idx, self.get_id()), files=files)
resp.raise_if_err()
return resp

def download_file(self, file_type, file_name):
file_type_idx = FILE_TYPES.get(file_type)
resp = self._cli.rest_get('/download/{}/nasServer/{}'.format(
file_type_idx, self.get_id()))
resp.raise_if_err()
with open(file_name, "w", encoding="utf-8") as f:
f.write(resp.response.text)
return resp


class UnityNasServerList(UnityResourceList):
def __init__(self, cli=None, home_sp=None, current_sp=None, **filters):
Expand Down
26 changes: 24 additions & 2 deletions storops/unity/resource/nfs_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ class UnityNfsServer(UnityResource):
@classmethod
def create(cls, cli, nas_server, host_name=None, nfs_v4_enabled=True,
is_secure_enabled=None, is_extended_credentials_enabled=None,
kdc_type=None, kdc_username=None, kdc_password=None):
kdc_type=None, kdc_username=None, kdc_password=None,
nfs_v3_enabled=None, credentials_cache_ttl=None):
clz = storops.unity.resource.nas_server.UnityNasServer
nas_server = clz.get(cli, nas_server)

Expand All @@ -43,7 +44,9 @@ def create(cls, cli, nas_server, host_name=None, nfs_v4_enabled=True,
isExtendedCredentialsEnabled=is_extended_credentials_enabled,
kdcType=kdc_type,
kdcUsername=kdc_username,
kdcPassword=kdc_password)
kdcPassword=kdc_password,
nfsv3Enabled=nfs_v3_enabled,
credentialsCacheTTL=credentials_cache_ttl)

resp.raise_if_err()
return cls(_id=resp.resource_id, cli=cli)
Expand All @@ -59,6 +62,25 @@ def delete(self, skip_kdc_unjoin=None, username=None,
resp.raise_if_err()
return resp

def modify(self, host_name=None, nfs_v4_enabled=None,
is_secure_enabled=None, is_extended_credentials_enabled=None,
kdc_type=None, kdc_username=None, kdc_password=None,
nfs_v3_enabled=None, credentials_cache_ttl=None):
req_body = self._cli.make_body(
hostName=host_name,
nfsv4Enabled=nfs_v4_enabled,
isSecureEnabled=is_secure_enabled,
isExtendedCredentialsEnabled=is_extended_credentials_enabled,
kdcType=kdc_type,
kdcUsername=kdc_username,
kdcPassword=kdc_password,
nfsv3Enabled=nfs_v3_enabled,
credentialsCacheTTL=credentials_cache_ttl)

resp = self.action('modify', **req_body)
resp.raise_if_err()
return resp


class UnityNfsServerList(UnityResourceList):
@classmethod
Expand Down
6 changes: 5 additions & 1 deletion storops/unity/resource/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -738,7 +738,11 @@ def get_resource_class(cls):


class UnityVirusChecker(UnityResource):
pass
def modify(self, is_enabled):
req_body = self._cli.make_body(isEnabled=is_enabled)
resp = self.action('modify', **req_body)
resp.raise_if_err()
return resp


class UnityVirusCheckerList(UnityResourceList):
Expand Down
19 changes: 19 additions & 0 deletions storops_test/unity/resource/test_cifs_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import logging
from unittest import TestCase

from hamcrest import assert_that, equal_to, none, instance_of, only_contains, \
raises

Expand Down Expand Up @@ -105,6 +106,24 @@ def f():

assert_that(f, raises(UnityNetBiosNameExistedError, 'already exists'))

@patch_rest
def test_modify_success(self):
server = UnityCifsServer(_id='cifs_5', cli=t_rest())
resp = server.modify(netbios_name='nas_5',
workgroup='test_wg_5')
assert_that(resp.is_ok(), equal_to(True))
server.update()
assert_that(server.netbios_name, equal_to('nas_5'))
assert_that(server.workgroup, equal_to('test_wg_5'))

@patch_rest
def test_modify_not_found(self):
def f():
server = UnityCifsServer(_id='cifs_10', cli=t_rest())
server.modify(netbios_name='nas_10', workgroup='test_wg_10')

assert_that(f, raises(UnityResourceNotFoundError))

@patch_rest
def test_delete_cifs3(self):
server = UnityCifsServer(_id='cifs_3', cli=t_rest())
Expand Down
22 changes: 22 additions & 0 deletions storops_test/unity/resource/test_nfs_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
# under the License.
from __future__ import unicode_literals

import datetime
from unittest import TestCase

from hamcrest import equal_to, assert_that, instance_of, raises
Expand Down Expand Up @@ -61,6 +62,27 @@ def f():

assert_that(f, raises(UnityNfsAlreadyEnabledError, 'already enabled'))

@patch_rest
def test_modify_success(self):
server = UnityNfsServer(_id='nfs_4', cli=t_rest())
resp = server.modify(nfs_v4_enabled=False,
nfs_v3_enabled=True,
credentials_cache_ttl="00:12:00.000")
assert_that(resp.is_ok(), equal_to(True))
server.update()
assert_that(server.nfs_v4_enabled, equal_to(False))
assert_that(server.nfs_v3_enabled, equal_to(True))
assert_that(server.credentials_cache_ttl,
equal_to(datetime.timedelta(minutes=12)))

@patch_rest
def test_modify_not_found(self):
def f():
server = UnityNfsServer(_id='nfs_5', cli=t_rest())
server.delete()

assert_that(f, raises(UnityResourceNotFoundError))

@patch_rest
def test_delete_success(self):
server = UnityNfsServer(_id='nfs_3', cli=t_rest())
Expand Down
8 changes: 8 additions & 0 deletions storops_test/unity/resource/test_system.py
Original file line number Diff line number Diff line change
Expand Up @@ -1166,6 +1166,14 @@ def test_get_all(self):
checker_list = UnityVirusCheckerList(cli=t_rest())
assert_that(len(checker_list), equal_to(1))

@patch_rest
def test_modify(self):
unity = t_unity()
resp = unity.modify_user_quota(
user_quota_id='userquota_171798692187_3_3',
hard_limit=8589934592, soft_limit=2147483648)
assert_that(resp.is_ok(), equal_to(True))


class UnityBasicSystemInfoTest(TestCase):
@patch_rest
Expand Down
29 changes: 29 additions & 0 deletions storops_test/unity/rest_data/cifsServer/cifs_5.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"content": {
"id": "cifs_5",
"instanceId": "root/emc:EMC_UEM_CIFSServerLeaf%InstanceID=cifs_5",
"netbiosName": "nas_5",
"workgroup": "test_wg_5",
"isStandalone": true,
"health": {
"value": 5,
"descriptionIds": [
"ALRT_COMPONENT_OK"
],
"descriptions": [
"The component is operating normally. No action is required."
]
},
"smbcaSupported": true,
"smbMultiChannelSupported": true,
"smbProtocolVersions": [
"1.0",
"2.0",
"2.1",
"3.0"
],
"nasServer": {
"id": "nas_5"
}
}
}
20 changes: 20 additions & 0 deletions storops_test/unity/rest_data/cifsServer/index.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
"url": "/api/instances/cifsServer/cifs_3?compact=True&fields=description,domain,fileInterfaces,health,id,instanceId,isStandalone,lastUsedOrganizationalUnit,name,nasServer,netbiosName,smbMultiChannelSupported,smbProtocolVersions,smbcaSupported,workgroup",
"response": "cifs_3.json"
},
{
"url": "/api/instances/cifsServer/cifs_5?compact=True&fields=description,domain,fileInterfaces,health,id,instanceId,isStandalone,lastUsedOrganizationalUnit,name,nasServer,netbiosName,smbMultiChannelSupported,smbProtocolVersions,smbcaSupported,workgroup",
"response": "cifs_5.json"
},
{
"url": "/api/instances/cifsServer/cifs_7?compact=True&fields=description,domain,fileInterfaces,health,id,instanceId,isStandalone,lastUsedOrganizationalUnit,name,nasServer,netbiosName,smbMultiChannelSupported,smbProtocolVersions,smbcaSupported,workgroup",
"response": "cifs_7.json"
Expand Down Expand Up @@ -113,6 +117,22 @@
{
"url": "/api/instances/cifsServer/cifs_10?compact=True",
"response": "not_found.json"
},
{
"url": "/api/instances/cifsServer/cifs_5/action/modify?compact=True",
"body": {
"netbiosName": "nas_5",
"workgroup": "test_wg_5"
},
"response": "success.json"
},
{
"url": "/api/instances/cifsServer/cifs_10/action/modify?compact=True",
"body": {
"netbiosName": "nas_10",
"workgroup": "test_wg_10"
},
"response": "not_found.json"
}
]
}
Empty file.
13 changes: 13 additions & 0 deletions storops_test/unity/rest_data/nfsServer/index.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
"url": "/api/instances/nfsServer/nfs_3?compact=True&fields=credentialsCacheTTL,fileInterfaces,hostName,id,instanceId,isExtendedCredentialsEnabled,isSecureEnabled,kdcType,nasServer,nfsv4Enabled,servicePrincipalName",
"response": "nfs_3.json"
},
{
"url": "/api/instances/nfsServer/nfs_4?compact=True&fields=credentialsCacheTTL,fileInterfaces,hostName,id,instanceId,isExtendedCredentialsEnabled,isSecureEnabled,kdcType,nasServer,nfsv4Enabled,servicePrincipalName",
"response": "nfs_4.json"
},
{
"url": "/api/types/nfsServer/instances?compact=True&fields=credentialsCacheTTL,fileInterfaces,hostName,id,instanceId,isExtendedCredentialsEnabled,isSecureEnabled,kdcType,nasServer,nfsv4Enabled,servicePrincipalName",
"response": "all.json"
Expand Down Expand Up @@ -43,6 +47,15 @@
{
"url": "/api/instances/nfsServer/nfs_5?compact=True",
"response": "not_found.json"
},
{
"url": "/api/instances/nfsServer/nfs_4/action/modify?compact=True",
"body": {
"nfsv4Enabled": false,
"nfsv3Enabled": true,
"credentialsCacheTTL": "00:12:00.000"
},
"response": "success.json"
}
]
}
14 changes: 14 additions & 0 deletions storops_test/unity/rest_data/nfsServer/nfs_4.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"content": {
"id": "nfs_4",
"instanceId": "root/emc:EMC_UEM_NFSServerLeaf%InstanceID=nfs_4",
"nfsv4Enabled": false,
"nfsv3Enabled": true,
"isSecureEnabled": false,
"isExtendedCredentialsEnabled": false,
"credentialsCacheTTL": "00:12:00.000",
"nasServer": {
"id": "nas_5"
}
}
}
Empty file.
5 changes: 4 additions & 1 deletion storops_test/unity/rest_mock.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,14 @@
import json
import logging
import os
import sys

from mock import patch

import storops.unity.resource.system
from storops.exception import MockFileNotFoundError
from storops.lib.common import cache, allow_omit_parentheses
from storops.unity.client import UnityClient
import storops.unity.resource.system
from storops_test.utils import ConnectorMock, read_test_file

__author__ = 'Cedric Zhuang'
Expand Down Expand Up @@ -103,6 +104,8 @@ def get_filename(cls, inputs):
@cache
def read_index(folder):
string_indices = read_test_file(folder, 'index.json')
if sys.version_info.major > 2:
return json.loads(string_indices)
return json.loads(string_indices, encoding='utf-8')

def _get_mock_output(self, url, kwargs):
Expand Down

0 comments on commit ccfccba

Please sign in to comment.