Skip to content

Commit

Permalink
Merge pull request #222 from nutanix/topic/dsl-changes-3.4.0
Browse files Browse the repository at this point in the history
Calm-DSL changes for Calm v3.4.0
  • Loading branch information
abhijeetkaurav1st authored Mar 22, 2022
2 parents 0c12474 + 3e34390 commit c1a3a6b
Show file tree
Hide file tree
Showing 97 changed files with 4,505 additions and 54 deletions.
2 changes: 1 addition & 1 deletion CalmVersion
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.3.2
3.4.0
1 change: 1 addition & 0 deletions calm/dsl/api/blueprint.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ def upload_with_secrets(
"package_definition_list",
"substrate_definition_list",
"app_profile_list",
"credential_definition_list",
]
strip_secrets(
bp_resources, secret_map, secret_variables, object_lists=object_lists
Expand Down
8 changes: 6 additions & 2 deletions calm/dsl/api/handle.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from .application import ApplicationAPI
from .project import ProjectAPI
from .environment import EnvironmentAPI
from .setting import SettingAPI
from .setting import AccountsAPI
from .marketplace import MarketPlaceAPI
from .app_icons import AppIconAPI
from .version import VersionAPI
Expand All @@ -26,6 +26,8 @@
from .app_protection_policy import AppProtectionPolicyAPI
from .vm_recovery_point import VmRecoveryPointAPI
from .nutanix_task import TaskAPI
from .job import JobAPI
from .resource_type import ResourceTypeAPI


class ClientHandle:
Expand All @@ -44,7 +46,7 @@ def _connect(self):
self.runbook = RunbookAPI(self.connection)
self.task = TaskLibraryApi(self.connection)
self.application = ApplicationAPI(self.connection)
self.account = SettingAPI(self.connection)
self.account = AccountsAPI(self.connection)
self.market_place = MarketPlaceAPI(self.connection)
self.app_icon = AppIconAPI(self.connection)
self.version = VersionAPI(self.connection)
Expand All @@ -58,6 +60,8 @@ def _connect(self):
self.app_protection_policy = AppProtectionPolicyAPI(self.connection)
self.vm_recovery_point = VmRecoveryPointAPI(self.connection)
self.nutanix_task = TaskAPI(self.connection)
self.job = JobAPI(self.connection)
self.resource_types = ResourceTypeAPI(self.connection)


def get_client_handle_obj(
Expand Down
17 changes: 17 additions & 0 deletions calm/dsl/api/job.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from .resource import ResourceAPI
from .connection import REQUEST


class JobAPI(ResourceAPI):
def __init__(self, connection):
super().__init__(connection, resource_type="jobs")
self.INSTANCES = self.ITEM + "/instances"

def instances(self, uuid, params={}, ignore_error=False):
return self.connection._call(
self.INSTANCES.format(uuid),
verify=False,
request_json=params,
method=REQUEST.METHOD.POST,
ignore_error=ignore_error,
)
6 changes: 6 additions & 0 deletions calm/dsl/api/provider.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from .resource import ResourceAPI


class ProviderAPI(ResourceAPI):
def __init__(self, connection):
super().__init__(connection, resource_type="providers", calm_api=True)
16 changes: 16 additions & 0 deletions calm/dsl/api/resource_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from .resource import ResourceAPI
from .connection import REQUEST


class ResourceTypeAPI(ResourceAPI):
def __init__(self, connection):
super().__init__(connection, resource_type="resource_types", calm_api=True)
self.TEST_RUNBOOK = self.PREFIX + "/{}/test_runbook/{}/run"

def run_test_runbook(self, resource_type_id, action_id, payload):
return self.connection._call(
self.TEST_RUNBOOK.format(resource_type_id, action_id),
request_json=payload,
verify=False,
method=REQUEST.METHOD.POST,
)
5 changes: 4 additions & 1 deletion calm/dsl/api/setting.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@
from .connection import REQUEST


class SettingAPI(ResourceAPI):
class AccountsAPI(ResourceAPI):
def __init__(self, connection):
super().__init__(connection, resource_type="accounts")
self.VERIFY = self.PREFIX + "/{}/verify"
self.VMS_LIST = self.ITEM + "/vms/list"
self.RESOURCE_TYPES_LIST_BASED_ON_ACCOUNT = (
self.PREFIX + "/{}/resource_types/list"
)

def verify(self, id):
return self.connection._call(
Expand Down
6 changes: 5 additions & 1 deletion calm/dsl/builtins/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
from .models.ref import ref, RefType
from .models.calm_ref import Ref
from .models.metadata import Metadata, MetadataType
from .models.credential import basic_cred, secret_cred, CredentialType
from .models.variable import Variable, setvar, CalmVariable, VariableType
from .models.action import action, parallel, ActionType, get_runbook_action
from .models.credential import basic_cred, secret_cred, dynamic_cred, CredentialType

from .models.task import Task, CalmTask, TaskType

Expand Down Expand Up @@ -93,13 +93,15 @@

from .models.vm_profile import VmProfile
from .models.vm_blueprint import VmBlueprint
from .models.job import Job, JobScheduler

__all__ = [
"Ref",
"ref",
"RefType",
"basic_cred",
"secret_cred",
"dynamic_cred",
"CredentialType",
"Variable",
"setvar",
Expand Down Expand Up @@ -192,6 +194,8 @@
"_endpoint",
"CalmEndpoint",
"AppProtection",
"JobScheduler",
"AhvVmRecoveryResources",
"ahv_vm_recovery_spec",
"Job",
]
44 changes: 44 additions & 0 deletions calm/dsl/builtins/models/calm_ref.py
Original file line number Diff line number Diff line change
Expand Up @@ -330,3 +330,47 @@ def compile(cls, name=None, **kwargs):
"name": vrc_name,
"uuid": vrc_uuid,
}

class Resource_Type:
def __new__(cls, name, **kwargs):
kwargs["__ref_cls__"] = cls
kwargs["name"] = name
return _calm_ref(**kwargs)

def compile(cls, name, **kwargs):

client = get_api_client()

if name:
params = {"filter": "name=={}".format(name), "length": 250}
res, err = client.resource_types.list(params)
if err:
LOG.error(err)
sys.exit(-1)

res = res.json()
if res["metadata"]["total_matches"] == 0:
LOG.error("No vm with name '{}' found".format(name))
sys.exit(-1)

elif res["metadata"]["total_matches"] > 1:
LOG.error(
"Multiple resource type with same name found. "
"Please provide resource type uuid"
)
sys.exit(-1)

resource_type_uuid = res["entities"][0]["status"]["uuid"]
else:
LOG.error(
"Resource type name not passed, " "pls pass resource type name"
)
sys.exit(-1)

resource_type_ref = {
"uuid": resource_type_uuid,
"name": name,
"kind": "resource_type",
}

return resource_type_ref
10 changes: 10 additions & 0 deletions calm/dsl/builtins/models/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,13 @@ class TYPE:
TYPE.TIME,
TYPE.DATETIME,
]


class SYSTEM_ACTIONS:
CREATE = "create"
START = "start"
RESTART = "restart"
UPDATE = "update"
STOP = "stop"
DELETE = "delete"
SOFT_DELETE = "soft_delete"
83 changes: 83 additions & 0 deletions calm/dsl/builtins/models/credential.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
import sys
from copy import deepcopy

from distutils.version import LooseVersion as LV

from .entity import EntityType, Entity
from .validator import PropertyValidator
from .utils import read_file
from calm.dsl.builtins import Ref
from calm.dsl.api.handle import get_api_client
from calm.dsl.log import get_logging_handle
from calm.dsl.store import Version

LOG = get_logging_handle(__name__)


# Credential
Expand All @@ -13,6 +24,8 @@ class CredentialType(EntityType):
def compile(cls):
cdict = super().compile()
cdict.pop("default", None)
if cdict["type"] == "PASSWORD":
cdict.pop("passphrase", None)
return cdict


Expand Down Expand Up @@ -79,3 +92,73 @@ def secret_cred(
kwargs["editables"] = editables

return _credential(**kwargs)


def dynamic_cred(
username,
account,
resource_type=None,
variable_dict={},
name="default",
default=False,
type="PASSWORD",
editables=dict(),
):
client = get_api_client()
secret = {"attrs": {"is_secret_modified": True}, "value": "@@{secret}@@"}

# Below line is required as account ref returns uuid in account ref dict
# which is not required for dynamic cred cases

kwargs = {}
kwargs["type"] = type
kwargs["username"] = username
kwargs["secret"] = secret
kwargs["name"] = name
kwargs["default"] = default
kwargs["cred_class"] = "dynamic"
kwargs["account"] = account

if not resource_type:
resource_type = Ref.Resource_Type(account.name)

if variable_dict:
resource_type_uuid = resource_type.compile()["uuid"]
res, err = client.resource_types.read(id=resource_type_uuid)
if err:
LOG.error(err)
sys.exit(-1)

resource_type_payload = res.json()

cred_attr_list = (
resource_type_payload.get("spec", {})
.get("resources", {})
.get("schema_list", {})
)

if not cred_attr_list:
LOG.error("No Cred-Variables found in account")
sys.exit(-1)

variable_list = list()
for cred_attr in cred_attr_list:
cred_attr_copy = deepcopy(cred_attr)
var_name = cred_attr["name"]
if var_name in variable_dict:
cred_attr_copy["value"] = variable_dict.pop(var_name)

cred_attr_copy.pop("uuid", None)
variable_list.append(cred_attr_copy)

if variable_dict:
LOG.error("Variables '{}' not found in account cred-attrs")
sys.exit("Unknown variables found in credential")

kwargs["variable_list"] = variable_list
kwargs["resource_type"] = resource_type

if editables:
kwargs["editables"] = editables

return _credential(**kwargs)
Loading

0 comments on commit c1a3a6b

Please sign in to comment.