Skip to content

Commit

Permalink
Feature/csi 1451 create flashcopy (#7)
Browse files Browse the repository at this point in the history
* add first attempt for create flashcopy method
add flashcopy creation options to types.py

* flashcopy -> flashcopies

* add cs to url

* return all post command

* return all post command

* adding log for url

* adding log for url

* delete log

* try to debug

* try to debug

* try to debug

* try going against the wiki

* try going against the wiki

* try going against the wiki
add posta to flashcopy

* try going against the wiki

* testing

* testing without rebuild

* testing with rebuild

* testing cs/flashcopy

* testing v1/flashcopeis

* testing v1/flashcopy

* testing v1/flashcopy

* testing global url

* testing global url

* testing global url

* testing global url

* testing global url

* testing global url

* testing global url

* testing set_base_url method

* remove posta from volumes.py

* add flashcopies.py

* edit flashcopies.py

* disable pprcs.py

* disable volumemixin

* disable pprcs.py

* able pprcs.py

* flashcopies.py to flashcopy

* flashcopies.py to flashcopy

* flashcopies.py to flashcopy

* testing manager

* pdb

* create_flashcopy to sc_client.py

* edit flashcopies.py

* edit init

* add posta to flashcopies.py

* remove pdb and global params

* add delete and unit test for create

* testing

* add __init__.py

* write in __init__.py files

* delete content in __init__.py files
and add __init__.py

* add __init__.py

* add __init__.py

* remove __init__.py

* try change import relations

* changed create_flashcopy input
add unit tests - pass

* trying options

* testing

* flashcopy to flashcopies

* //

* get and list for flashcopies.py

* pdb add

* test
change response from flashcopies get

* add if to _add_details

* test get_flashcopies_by_volume

* revert get_flashcopies_by_volume method

* test options

* options - list and singular

* options - list and singular fix

* options - list and singular

* no singular option is allowed

* options - list and singular

* cleanup fo PR

* check tests

* check tests

* check tests
fix route

* //

* added flashcopies.py ALL ONE

* get rid of bug

* flake8 fixes

* flake8 fixes

* flake8 fixes

* get rid of unnecessary code

* PR fixes

* fix

* get rid of unnecessary imports

* all flashcopy stay as it was, only cs_flashcopies change (added)

* change if statement, PR

* related_resource change

* fix lines

* get rid of unnecessary code

Co-authored-by: ArbelNathan <[email protected]>
  • Loading branch information
ArbelNathan and ArbelNathan authored May 25, 2020
1 parent 1992d71 commit 99e6e28
Show file tree
Hide file tree
Showing 15 changed files with 506 additions and 105 deletions.
4 changes: 4 additions & 0 deletions pyds8k/client/ds8k/v1/sc_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ def list_extentpool_virtualpool(self, pool_id):
def list_flashcopies(self):
return self.client.get_flashcopies()

@dictionarize
def list_cs_flashcopies(self):
return self.client.get_cs_flashcopies()

@dictionarize
def list_volume_flashcopies(self, volume_id):
# two requests
Expand Down
Empty file added pyds8k/resources/__init__.py
Empty file.
3 changes: 2 additions & 1 deletion pyds8k/resources/ds8k/v1/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@
from . import ioports, flashcopy, events, mappings, pprc, eserep, \
users, systems, nodes, marrays, encryption_groups, io_enclosures, \
pools, tserep, lss, volumes, host_ports, hosts
from .cs import pprcs
from .cs import pprcs, flashcopies

__all__ = (
'ioports',
'flashcopy',
'flashcopies',
'events',
'mappings',
'pprc',
Expand Down
83 changes: 69 additions & 14 deletions pyds8k/resources/ds8k/v1/common/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
class RootBaseMixin(object):
pass


# Note: the format of all the get list methods should be:
# get_{right type in types}
# the format of all the get single methods should be:
Expand Down Expand Up @@ -134,35 +135,35 @@ def update_tserep_cap_by_pool(self, pool_id, cap, captype=''):
pool_id,
rebuild_url=True
).all(
types.DS8K_TSEREP
).update({'cap': cap, 'captype': captype})
types.DS8K_TSEREP
).update({'cap': cap, 'captype': captype})
return res

def update_eserep_cap_by_pool(self, pool_id, cap, captype=''):
_, res = self.one(types.DS8K_POOL,
pool_id,
rebuild_url=True
).all(
types.DS8K_ESEREP
).update({'cap': cap, 'captype': captype})
types.DS8K_ESEREP
).update({'cap': cap, 'captype': captype})
return res

def update_tserep_threshold_by_pool(self, pool_id, threshold):
_, res = self.one(types.DS8K_POOL,
pool_id,
rebuild_url=True
).all(
types.DS8K_TSEREP
).update({'threshold': threshold})
types.DS8K_TSEREP
).update({'threshold': threshold})
return res

def update_eserep_threshold_by_pool(self, pool_id, threshold):
_, res = self.one(types.DS8K_POOL,
pool_id,
rebuild_url=True
).all(
types.DS8K_ESEREP
).update({'threshold': threshold})
types.DS8K_ESEREP
).update({'threshold': threshold})
return res

def get_volumes_by_pool(self, pool_id):
Expand Down Expand Up @@ -272,8 +273,8 @@ def update_volume_extend(self, volume_id, new_size, captype=''):
_, res = self.one(types.DS8K_VOLUME,
volume_id,
rebuild_url=True).update(
{'cap': new_size, 'captype': captype}
)
{'cap': new_size, 'captype': captype}
)
return res

def update_volume_move(self, volume_id, new_pool):
Expand Down Expand Up @@ -392,8 +393,8 @@ def map_volume_to_host(self, host_name, volume_id, lunid=''):
host_name,
rebuild_url=True
).all(types.DS8K_VOLMAP).posta(
post_data
)
post_data
)
return res

def unmap_volume_from_host(self, host_name, lunid):
Expand All @@ -414,8 +415,8 @@ def get_lss(self, lss_id=None, lss_type=''):
raise ValueError(
INVALID_TYPE.format(
', '.join(types.DS8K_VOLUME_TYPES)
)
)
)
return self.all(types.DS8K_LSS, rebuild_url=True).list(
params={'type': lss_type}
)
Expand Down Expand Up @@ -444,6 +445,42 @@ def get_flashcopies_by_volume(self, volume_id):
volume_id,
rebuild_url=True).all(types.DS8K_FLASHCOPY).list()

def get_cs_flashcopies(self, fcid=None):
return self.get_cs_flashcopy(fcid)

def get_cs_flashcopy(self, fcid=None):
if fcid:
return self.one('{}.{}'.format(
types.DS8K_COPY_SERVICE_PREFIX,
types.DS8K_CS_FLASHCOPY), fcid, rebuild_url=True).get()
return self.all('{}.{}'.format(
types.DS8K_COPY_SERVICE_PREFIX,
types.DS8K_CS_FLASHCOPY), rebuild_url=True).list()

def create_cs_flashcopy(self, volume_pairs, options=[]):
"""
:param volume_pairs: [{"source_volume": 0000,"target_volume": 1100},..]
:param options:
:return:
"""
for option in options:
self._verify_type(option, types.DS8K_FC_OPTIONS)
_, res = self.all('{}.{}'.format(
types.DS8K_COPY_SERVICE_PREFIX,
types.DS8K_CS_FLASHCOPY),
rebuild_url=True).posta({"volume_pairs": volume_pairs,
"options": options
})
return res

def delete_cs_flashcopy(self, flashcopy_id):
_, res = self.one('{}.{}'.format(
types.DS8K_COPY_SERVICE_PREFIX,
types.DS8K_CS_FLASHCOPY),
flashcopy_id,
rebuild_url=True).delete()
return res


class RootPPRCMixin(object):
def get_pprc(self, pprc_id=None):
Expand Down Expand Up @@ -505,7 +542,7 @@ def get_events_by_filter(self,
if not isinstance(v, datetime):
raise InvalidArgumentError(
'before/after must be an datetime instance.'
)
)
dttz = datetime(year=v.year,
month=v.month,
day=v.day,
Expand Down Expand Up @@ -607,6 +644,24 @@ def get_flashcopy(self, fcid=None):
self._stop_updating()
return flashcopies

def get_cs_flashcopies(self, fcid=None):
return self.get_cs_flashcopy(fcid)

def get_cs_flashcopy(self, fcid=None):
if not self.id:
raise IDMissingError()
if fcid:
return self.one('{}.{}'.format(
types.DS8K_COPY_SERVICE_PREFIX,
types.DS8K_CS_FLASHCOPY), fcid).get()
flashcopies = self.all('{}.{}'.format(
types.DS8K_COPY_SERVICE_PREFIX,
types.DS8K_CS_FLASHCOPY)).list()
self._start_updating()
setattr(self, types.DS8K_CS_FLASHCOPY, flashcopies)
self._stop_updating()
return flashcopies


class PPRCMixin(object):
def get_pprc(self, pprc_id=None):
Expand Down
23 changes: 23 additions & 0 deletions pyds8k/resources/ds8k/v1/common/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,26 @@

DS8K_COPY_SERVICE_PREFIX = 'cs'
DS8K_CS_PPRC = 'pprcs'
DS8K_CS_FLASHCOPY = 'flashcopies'

DS8K_OPTION_FRCO = "freeze_consistency"
DS8K_OPTION_ITW = "inhibit_target_writes"
DS8K_OPTION_RECH = "record_changes"
DS8K_OPTION_NBC = "no_background_copy"
DS8K_OPTION_PER = "persistent"
DS8K_OPTION_APTP = "allow_pprc_target_primary"
DS8K_OPTION_RERE = "reverse_restore"
DS8K_OPTION_FRR = "fast_reverse_restore"
DS8K_OPTION_PSET = "permit_space_efficient_target"
DS8K_OPTION_FSETOOS = "fail_space_efficient_target_out_of_space"

DS8K_FC_OPTIONS = (DS8K_OPTION_FRCO,
DS8K_OPTION_ITW,
DS8K_OPTION_RECH,
DS8K_OPTION_NBC,
DS8K_OPTION_PER,
DS8K_OPTION_APTP,
DS8K_OPTION_RERE,
DS8K_OPTION_FRR,
DS8K_OPTION_PSET,
DS8K_OPTION_FSETOOS)
70 changes: 70 additions & 0 deletions pyds8k/resources/ds8k/v1/cs/flashcopies.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
##############################################################################
# Copyright 2019 IBM Corp.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
##############################################################################

"""
advanced FlashCopies interface.
"""
from pyds8k.base import ManagerMeta, ResourceMeta
from ..common.base import Base, BaseManager
from ..common.types import DS8K_CS_FLASHCOPY, DS8K_FLASHCOPY
from ..volumes import Volume, VolumeManager


class FlashCopy(Base, metaclass=ResourceMeta):
resource_type = DS8K_CS_FLASHCOPY
_template = {'id': None,
'persistent': None,
'recording': None,
'backgroundcopy': None,
'state': None,
'options': [],
'volume_pairs': []
}

related_resource = {'_volume_pairs': [{
'source_volume': (Volume, VolumeManager),
'target_volume': (Volume, VolumeManager)
}]
}

def __repr__(self):
return "<FlashCopy: {0}>".format(self._get_id())

def _add_details(self, info, force=False):
super(FlashCopy, self)._add_details(info, force=force)
if DS8K_FLASHCOPY in info:
self._id = info[DS8K_FLASHCOPY][0]['id']


class FlashCopyManager(BaseManager, metaclass=ManagerMeta):
"""
Manage advanced FlashCopies resources.
"""
resource_class = FlashCopy
resource_type = DS8K_CS_FLASHCOPY

def get(self, resource_id='', url='', obj_class=None, **kwargs):
return self._get(resource_id=resource_id, url=url,
obj_class=obj_class, **kwargs)

def list(self, url='', obj_class=None, body=None, **kwargs):
return self._list(url=url, obj_class=obj_class, body=body, **kwargs)

def posta(self, url='', body=None):
return self._posta(url=url, body=body)

def delete(self, url=''):
return self._delete(url=url)
Empty file added pyds8k/test/__init__.py
Empty file.
Loading

0 comments on commit 99e6e28

Please sign in to comment.