Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/volume groups #305

Open
wants to merge 58 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
70c4f5a
volume groups module
Oct 17, 2022
500583a
black fix
alaa-bish Oct 19, 2022
6149e89
volume groups module, disks
Oct 19, 2022
5245925
volume groups module, default spec
Oct 19, 2022
f2745b3
Merge remote-tracking branch 'origin/feat/volume_groups' into feat/vo…
Oct 19, 2022
ab90fd9
sanity fix
alaa-bish Oct 19, 2022
8c93b89
volume groups module, vms, clients
Oct 19, 2022
24900eb
Merge branch 'main' into feat/volume_groups
Oct 21, 2022
efe2aec
volume groups module, clients
Oct 22, 2022
03e2cd7
sanity fix
alaa-bish Oct 23, 2022
280fdbc
volume groups delete, clients detaching
Oct 24, 2022
c07fd6f
Merge remote-tracking branch 'origin/feat/volume_groups' into feat/vo…
Oct 24, 2022
6b40e91
volume groups delete, vms detaching
Oct 25, 2022
a22a5ed
vms fixes, requirements
Oct 26, 2022
4aacccf
doc fix
alaa-bish Oct 30, 2022
6c2ac7a
attachment fixes
Oct 31, 2022
9d93ee5
Merge remote-tracking branch 'origin/feat/volume_groups' into feat/vo…
Oct 31, 2022
73e3ee6
doc fix
alaa-bish Oct 31, 2022
84a67da
Merge branch 'feat/volume_groups' of https://github.com/nutanix/nutan…
alaa-bish Oct 31, 2022
db02f43
black fix
alaa-bish Oct 31, 2022
4b4c23b
disks, requirements
Nov 1, 2022
56dc345
black fix
alaa-bish Nov 1, 2022
7dd12fc
chap auth validation
Nov 1, 2022
dd7fd23
optimizing
Nov 3, 2022
0cb8659
vg base spec idempotency
Nov 4, 2022
f2585bf
black fix
alaa-bish Nov 7, 2022
c5dba97
vg disks update
Nov 8, 2022
7671d2f
Merge remote-tracking branch 'origin/feat/volume_groups' into feat/vo…
Nov 8, 2022
e952ed6
sanity fix
alaa-bish Nov 8, 2022
cbc18a3
vg disks update, fix
Nov 8, 2022
378ff7f
Merge remote-tracking branch 'origin/feat/volume_groups' into feat/vo…
Nov 8, 2022
d0b910d
black fix
alaa-bish Nov 8, 2022
734b0dd
vg disks update, fix
Nov 8, 2022
bada3e5
Merge remote-tracking branch 'origin/feat/volume_groups' into feat/vo…
Nov 8, 2022
120bf5c
vg disks idempotency
Nov 9, 2022
fcab4eb
black fix
alaa-bish Nov 10, 2022
88453b6
vg vms and clients update
Nov 16, 2022
6442d44
sanity fix
alaa-bish Nov 16, 2022
0bf05ff
vg vms and clients update
Nov 16, 2022
760417c
response fixes
Nov 16, 2022
7e2c148
black fix
alaa-bish Nov 17, 2022
d30d293
fixes
Nov 17, 2022
cd12727
fixes
Nov 18, 2022
5185789
fixes
Nov 18, 2022
3978fb0
Merge branch 'main' into feat/volume_groups
Mar 14, 2023
91f3eb0
volume group's info module
Mar 14, 2023
4905add
volume group's info module fix
Mar 14, 2023
667d438
sanity fix
alaa-bish Mar 14, 2023
61a6498
volume group's module fix
Mar 14, 2023
ceb9cc4
volume group's module fix, clients attaching by uuid
Mar 15, 2023
465e19f
volume group's module fix, clients requirements
Mar 15, 2023
74bc2d3
volume group's module fix, clients requirements
Mar 15, 2023
4854a98
volume group's module fix, result status fix
Mar 15, 2023
68108e5
sub tusks messages
Mar 22, 2023
df88adf
black fix
alaa-bish Mar 22, 2023
df9cdf5
sub tasks messages
Mar 22, 2023
a82ef32
Merge remote-tracking branch 'origin/feat/volume_groups' into feat/vo…
Mar 22, 2023
892624e
sub tasks failing fixes
Mar 22, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions meta/runtime.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,4 @@ action_groups:
- ntnx_ndb_slas_info
- ntnx_ndb_databases
- ntnx_ndb_clusters_info
- ntnx_volume_groups
54 changes: 54 additions & 0 deletions plugins/module_utils/prism/iscsi_clients.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# This file is part of Ansible
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function

__metaclass__ = type

from copy import deepcopy


class Clients:
@classmethod
def get_spec(cls, iscsi_client, chap_auth=False):
payload = cls._get_default_spec()
spec, error = cls._build_spec_iscsi_client(payload, iscsi_client, chap_auth)
if error:
return None, error
return spec, None

@staticmethod
def _get_default_spec():
return deepcopy({"enabledAuthentications": "NONE"})

@staticmethod
def _build_spec_iscsi_client(payload, iscsi_client, chap_auth):

if iscsi_client.get("uuid"):
payload["extId"] = iscsi_client["uuid"]
elif iscsi_client.get("iscsi_iqn"):
payload["iscsiInitiatorName"] = iscsi_client["iscsi_iqn"]
elif iscsi_client.get("iscsi_ip"):
payload["iscsiInitiatorNetworkId"] = {
"$objectType": "common.v1.config.IPAddressOrFQDN",
"$reserved": {
"$fqObjectType": "common.v1.r0.a3.config.IPAddressOrFQDN"
},
"$unknownFields": {},
"ipv4": {
"$objectType": "common.v1.config.IPv4Address",
"$reserved": {
"$fqObjectType": "common.v1.r0.a3.config.IPv4Address"
},
"$unknownFields": {},
"value": iscsi_client["iscsi_ip"],
},
}
if iscsi_client.get("client_password"):
if chap_auth:
payload["clientSecret"] = iscsi_client["client_password"]

payload["enabledAuthentications"] = "CHAP"
else:
error = "parameters are required together: CHAP_auth, client_password"
return None, error
return payload, None
55 changes: 55 additions & 0 deletions plugins/module_utils/prism/vdisks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# This file is part of Ansible
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function

__metaclass__ = type

from copy import deepcopy

from .groups import get_entity_uuid


class VDisks:
@classmethod
def get_spec(cls, module, vdisk):
payload = cls._get_default_spec()
spec, error = cls._build_spec_vdisk(module, payload, vdisk)
if error:
return None, error
return spec, None

@staticmethod
def _get_default_spec():
return deepcopy(
{
"diskSizeBytes": None,
"diskDataSourceReference": {
"$objectType": "common.v1.config.EntityReference",
"$reserved": {
"$fqObjectType": "common.v1.r0.a3.config.EntityReference"
},
"$unknownFields": {},
"extId": None,
"entityType": "STORAGE_CONTAINER",
},
}
)

@staticmethod
def _build_spec_vdisk(module, payload, vdisk):

disk_size_bytes = vdisk["size_gb"] * 1024 * 1024 * 1024
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can create a convert func in utils which can be used by other modules as well


payload["diskSizeBytes"] = disk_size_bytes
uuid, error = get_entity_uuid(
vdisk["storage_container"],
module,
key="container_name",
entity_type="storage_container",
)
if error:
return None, error

payload["diskDataSourceReference"]["extId"] = uuid

return payload, None
156 changes: 156 additions & 0 deletions plugins/module_utils/prism/volume_groups.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
# This file is part of Ansible
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function

__metaclass__ = type

from copy import deepcopy

from .clusters import get_cluster_uuid
from .prism import Prism
from .vms import get_vm_uuid


class VolumeGroup(Prism):
__BASEURL__ = "/api/storage/v4.0.a2/config"

def __init__(self, module):
resource_type = "/volume-groups"
super(VolumeGroup, self).__init__(module, resource_type=resource_type)
self.build_spec_methods = {
"name": self._build_spec_name,
"desc": self._build_spec_desc,
"cluster": self._build_spec_cluster,
"target_prefix": self._build_spec_target_prefix,
"target_password": self._build_spec_target_password,
"load_balance": self._build_spec_load_balance,
"flash_mode": self._build_spec_flash_mode,
}

def create_vdisk(self, spec, volume_group_uuid, method="POST", endpoint="disks"):
Gevorg-Khachatryan-97 marked this conversation as resolved.
Show resolved Hide resolved

resp = self.update(spec, volume_group_uuid, method=method, endpoint=endpoint)
resp["task_uuid"] = resp["data"]["extId"][-36:]
return resp

def attach_vm(
self, spec, volume_group_uuid, method="POST", endpoint="$actions/attach-vm"
Gevorg-Khachatryan-97 marked this conversation as resolved.
Show resolved Hide resolved
):

resp = self.update(spec, volume_group_uuid, method=method, endpoint=endpoint)
resp["task_uuid"] = resp["data"]["extId"][-36:]
return resp

def attach_iscsi_client(
self,
spec,
volume_group_uuid,
method="POST",
endpoint="/$actions/attach-iscsi-client",
):

resp = self.update(spec, volume_group_uuid, method=method, endpoint=endpoint)
resp["task_uuid"] = resp["data"]["extId"][-36:]
return resp

def detach_vm(self, volume_group_uuid, vm, method="POST"):
vm_uuid = vm["extId"]
endpoint = "$actions/detach-vm/{0}".format(vm_uuid)
resp = self.update(uuid=volume_group_uuid, method=method, endpoint=endpoint)
resp["task_uuid"] = resp["data"]["extId"][-36:]
return resp

def detach_iscsi_client(self, volume_group_uuid, client, method="POST"):
client_uuid = client["extId"]
endpoint = "$actions/detach-iscsi-client/{0}".format(client_uuid)
resp = self.update(uuid=volume_group_uuid, method=method, endpoint=endpoint)
resp["task_uuid"] = resp["data"]["extId"][-36:]
return resp

def _get_default_spec(self):
return deepcopy(
{
"name": "",
"loadBalanceVmAttachments": False,
"sharingStatus": "SHARED",
"clusterReference": None,
"usageType": "USER",
}
)

def _build_spec_name(self, payload, value):
payload["name"] = value
return payload, None

def _build_spec_desc(self, payload, value):
payload["description"] = value
return payload, None

def _build_spec_target_prefix(self, payload, value):
payload["iscsiTargetPrefix"] = value
return payload, None

def _build_spec_target_password(self, payload, value):
payload["targetSecret"] = value
payload["enabledAuthentications"] = "CHAP"
return payload, None

def _build_spec_load_balance(self, payload, value):
payload["loadBalanceVmAttachments"] = value
return payload, None

def _build_spec_flash_mode(self, payload, value):

if value:
payload["storageFeatures"] = {
"$objectType": "storage.v4.config.StorageFeatures",
"$reserved": {
"$fqObjectType": "storage.v4.r0.a2.config.StorageFeatures"
},
"$unknownFields": {},
"flashMode": {
"$objectType": "storage.v4.config.FlashMode",
"$reserved": {"$fqObjectType": "storage.v4.r0.a2.config.FlashMode"},
"$unknownFields": {},
"isEnabled": True,
},
}
return payload, None

def _build_spec_cluster(self, payload, param):
uuid, err = get_cluster_uuid(param, self.module)
if err:
return None, err
payload["clusterReference"] = uuid
return payload, None

def get_vm_spec(self, vm):
uuid, error = get_vm_uuid(vm, self.module)
if error:
return None, error
spec = {"extId": uuid}
return spec, None

def get_client_spec(self, client):
spec = {"extId": client["uuid"]}
return spec, None


# Helper functions


def get_volume_group_uuid(config, module):
if "name" in config:
service_group = VolumeGroup(module)
name = config["name"]
uuid = service_group.get_uuid(name)
if not uuid:
error = "Volume Group {0} not found.".format(name)
return None, error
elif "uuid" in config:
uuid = config["uuid"]
else:
error = "Config {0} doesn't have name or uuid key".format(config)
return None, error

return uuid, None
Loading