nutanix / calm-dsl

Keep Calm and DSL On!
https://nutanix.github.io/calm-dsl/
Apache License 2.0
32 stars 51 forks source link

[Bug] BP creation does not have correct account when cluster as macro. #304

Open glover-chris opened 2 months ago

glover-chris commented 2 months ago

Describe the bug What's happening -> Blueprint is created with different account which is not present in environment.

Why it is happening -> It happens when we use cluster as macros. In builtins/models/substrate.py we tag PE account uuid associated with account used in substrate as account uuid in bp payload. To get this account we are doing a lookup in cache and as cluster name read from blueprint is a macro. It's not able to find cluster uuid associated with it's name from cache. Hence, account uuid becomes empty. Since, account uuid is empty while uploading bp. It takes up the first account that is present in server. In this case it is another account which is not present in env.

BP IS BELOW###########

""" Windows Server on AHV Multi-VM Blueprint """

import json import os import sys

from calm.dsl.builtins import Service, Package, Substrate from calm.dsl.builtins import ( Deployment, Profile, Blueprint, ) from calm.dsl.builtins import from calm.dsl.builtins import action, parallel, ref, basic_cred, CalmVariable, CalmTask from calm.dsl.builtins import vm_disk_package, read_file, read_local_file, file_exists from calm.dsl.builtins import AppEdit, PatchField, AhvUpdateConfigAttrs from calm.dsl.builtins import vm_disk_package, AhvVm, AhvVmDisk, AhvVmNic from calm.dsl.builtins import AhvVmGC, AhvVmResources, ahv_vm, read_ahv_spec, read_spec, readiness_probe from calm.dsl.runbooks import CalmEndpoint as Endpoint from calm.dsl.store import

PROJECT_ROOT = os.environ['PROJECT_ROOT'] SELF_SERVICE_ADDRESS = os.environ['CALM_IP_ADDRESS'] SELF_SERVICE_USERNAME = os.environ['CALM_USER'] SELF_SERVICE_SECRET = os.environ['CALM_PASS'] CALM_PROJECT = os.environ['CALM_PROJECT']

######################################################### ENV management ##########################################################################

Add this section in your bps/rbs to bring the environment parameters and scripts

#

All common references start with common config file, which path is located in the make variable COMMON_CONFIG_FILE.

#

All bp/rb specific references start with the bp/rb config file, which path is located in the make variable USECASE_CONFIG_FILE.

#

COMMON_CONFIG_FILE contains paths of parameters files (JSONs) and folders containing scripts used by all bps/rbs.

#

USECASE_CONFIG_FILE contains paths of parameters files (JSONs) and folders containing scripts used specifically by the use case.

todo: config files should be templetised for customization by the calling context (makefile or pielines) --> in the future templates should

be committed to the source code repo

todo: how to manage secrets from the calling context

(configs created on the fly from template then deleted ?, directly passed to sys env variables instead of files?)

The DSL_HELPERS_FOLDER (first reference in the COMMON_CONFIG_FILE json) gets variables and scripts within the repo folder structure to be used

in the bp/rb Python file during runtime (inside the locals() dict) as Python variables.

###################################################################################################################################################

CALM_ENVIRONMENT is exported via Makefile, otherwise, set environment variable on local machine

CALM_ENVIRONMENT = os.environ['CALM_ENVIRONMENT'].lower() CALM_ENV_CONFIG_PATH = os.path.join(PROJECT_ROOT + "/.local",CALM_ENVIRONMENT,(CALM_ENVIRONMENT + "-config.json")) COMMON_CONFIG_FILE = os.environ["COMMON_CONFIG_FILE"] COMMON_CONFIG = json.load(open(COMMON_CONFIG_FILE)) COMMON_CONFIG = {k: v.replace(".", PROJECT_ROOT, 1) for k,v in COMMON_CONFIG.items()}

endregion

region get the use case config

USECASE_CONFIG_FILE = os.environ["USECASE_CONFIG_FILE"] USECASE_CONFIG = json.load(open(USECASE_CONFIG_FILE))

endregion

region helper functions

DSL_HELPERS_FOLDER = COMMON_CONFIG["DSL_HELPERS_FOLDER"] sys.path.insert(0, DSL_HELPERS_FOLDER) from dsl_helpers import * del(locals()["DSL_HELPERS_FOLDER"]) #delete the variable because it will be loaded again by the helper function which is now available

endregion

region Bring the environment

failexec = False

Load the parameters from the use case config file

failexec = loadEnvVarsFromFile(path=USECASE_CONFIG_FILE, dict=locals()) or failexec

Load the common environment parameters

failexec = loadEnvVarsFromFile(path=CALM_ENV_CONFIG_PATH, dict=locals()) or failexec

Load the common lib scripts

failexec = loadScriptsFromFolder(path=COMMON_CONFIG["COMMON_LIB_FOLDER"], dict=locals()) or failexec

Load the common tasks scripts

failexec = loadScriptsFromFolder(path=COMMON_CONFIG["COMMON_TASKS_FOLDER"], dict=locals()) or failexec

Load the common environment parameters

failexec = loadEnvVarsFromFile(path=COMMON_CONFIG["COMMON_ENV_FILE"], dict=locals()) or failexec

Load the use case specific environment parameters

failexec = loadEnvVarsFromFile(path=USECASE_CONFIG["USECASE_ENV_FILE"], dict=locals()) or failexec

Load the use case specific lib scripts

failexec = loadScriptsFromFolder(path=USECASE_CONFIG["USECASE_LIB_FOLDER"], dict=locals()) or failexec

Load the use case tasks scripts

failexec = loadScriptsFromFolder(path=USECASE_CONFIG["USECASE_TASKS_FOLDER"], dict=locals()) or failexec if failexec: exit(1)

endregion

################################################################################################################################################### ######################################################### ENV management END####################################################################### ###################################################################################################################################################

THE BELOW VARIABLE IS NEEDED IN THE PROFILE CLASS SINCE IT HAS A DIFFERENT PYTHON CONTEXT SO WE IMPORT THE LOCAL DICT TO USE IN THE CLASS

VAR_DICT = locals()

WIN_ENDPOINT = (f"{blueprint_endpoints['windows_endpoint_name']}")

######################################################################

DEFINE CREDENTIALS

CRED_PROVIDER = password_state_config["password_state_provider_name"]

DOMAIN_USER = password_state_config['PASSWORD_STATE_CREDENTIALS']['password_state_id_information']['ad_id'] DOMAIN_DICT = {"cred_id": DOMAIN_USER} BP_CRED_AD = dynamic_cred('@@{username}@@', Ref.Account(CRED_PROVIDER), name="AD_PROVIDER_USERNAME", type="PASSWORD", variable_dict=DOMAIN_DICT)

RDSROOT_USER = password_state_config['PASSWORD_STATE_CREDENTIALS']['password_state_id_information']['rdsroot_id'] RDSROOT_DICT = {"cred_id": RDSROOT_USER} BP_CRED_RDSROOT = dynamic_cred('@@{username}@@', Ref.Account(CRED_PROVIDER), name="RDSROOT_USERNAME", type="PASSWORD", variable_dict=RDSROOT_DICT, default=True)

RDSMON_USER = password_state_config['PASSWORD_STATE_CREDENTIALS']['password_state_id_information']['rdsmon_id'] RDSMON_DICT = {"cred_id": RDSMON_USER} BP_CRED_RDSMON = dynamic_cred('@@{username}@@', Ref.Account(CRED_PROVIDER), name="RDSMON_USERNAME", type="PASSWORD", variable_dict=RDSMON_DICT)

SELF_SERVICE_USER = password_state_config['PASSWORD_STATE_CREDENTIALS']['password_state_id_information']['self_service_id'] SELF_SERVICE_DICT = {"cred_id": SELF_SERVICE_USER} BP_CRED_SELF_SERVICE = dynamic_cred('@@{username}@@', Ref.Account(CRED_PROVIDER), name="SELF_SERVICE_USERNAME", type="PASSWORD", variable_dict=SELF_SERVICE_DICT)

INFOBLOX_USER = password_state_config['PASSWORD_STATE_CREDENTIALS']['password_state_id_information']['infoblox_id'] INFOBLOX_DICT = {"cred_id": INFOBLOX_USER} BP_CRED_INFOBLOX = dynamic_cred('@@{username}@@', Ref.Account(CRED_PROVIDER), name="INFOBLOX_USERNAME", type="PASSWORD", variable_dict=INFOBLOX_DICT)

DISCOVERY_USER = password_state_config['PASSWORD_STATE_CREDENTIALS']['password_state_id_information']['discovery_id'] DISCOVERY_DICT = {"cred_id": DISCOVERY_USER} BP_CRED_DISCOVERY = dynamic_cred('@@{username}@@', Ref.Account(CRED_PROVIDER), name="DISCOVERY_USERNAME", type="PASSWORD", variable_dict=DISCOVERY_DICT)

CMDB_USER = password_state_config['PASSWORD_STATE_CREDENTIALS']['password_state_id_information']['cmdb_id'] CMDB_DICT = {"cred_id": CMDB_USER} BP_CRED_CMDB = dynamic_cred('@@{username}@@', Ref.Account(CRED_PROVIDER), name="CMDB_USERNAME", type="PASSWORD", variable_dict=CMDB_DICT)

PASSWORDSTATE_LOCAL_LIST_USER = password_state_config['PASSWORD_STATE_CREDENTIALS']['password_state_id_information']['passwordstate_bcx_local_admin_passwords_id'] PASSWORDSTATE_LOCAL_LIST_DICT = {"cred_id": PASSWORDSTATE_LOCAL_LIST_USER} BP_CRED_LOCAL_LIST_PASSWORDSTATE = dynamic_cred('@@{username}@@', Ref.Account(CRED_PROVIDER), name="PASSWORDSTATE_LOCAL_LIST_USERNAME", type="PASSWORD", variable_dict=PASSWORDSTATE_LOCAL_LIST_DICT)

PASSWORDSTATE_SECURITYGROUP_USER = password_state_config['PASSWORD_STATE_CREDENTIALS']['password_state_id_information']['passwordstate_securitygroups_id'] PASSWORDSTATE_SECURITYGROUP_DICT = {"cred_id": PASSWORDSTATE_SECURITYGROUP_USER} BP_CRED_SECURITYGROUP_PASSWORDSTATE = dynamic_cred('@@{username}@@', Ref.Account(CRED_PROVIDER), name="PASSWORDSTATE_SECURITYGROUP_USERNAME", type="PASSWORD", variable_dict=PASSWORDSTATE_SECURITYGROUP_DICT)

PC_USER = password_state_config['PASSWORD_STATE_CREDENTIALS']['password_state_id_information']['prism_central_id'] PC_DICT = {"cred_id": PC_USER} BP_CRED_PC = dynamic_cred('@@{username}@@', Ref.Account(CRED_PROVIDER), name="PC_USERNAME", type="PASSWORD", variable_dict=PC_DICT)

END CREDENTIALS

#####################################################################

#####################################################################

DEFINE DOWNLOADABLE IMAGE

disk_package = vm_disk_package( name="disk_package", description="", config={ "name": "disk_package", "image": { "name": "@@{VM_Provision.image_name}@@", "type": "DISK_IMAGE", "source": "@@{VM_Provision.image_source}@@", "architecture": "X86_64", }, "product": {"name": "win", "version": "@@{VM_Provision.image_version}@@"}, "checksum": {}, }, )

END DOWNLOADABLE IMAGE

####################################################################

####################################################################

DEFINE SERVICE

class VM_Provision(Service):

image_source = CalmVariable.WithOptions.FromTask(CalmTask.Exec.escript(script="print('@@{IMAGE_INFO}@@'.split(' - ')[1])"),label="OS Image Source", is_hidden=False, is_mandatory=True)
image_name = CalmVariable.WithOptions.FromTask(CalmTask.Exec.escript(script="print('@@{IMAGE_INFO}@@'.split(' - ')[0])"),label="OS Image Name", is_hidden=False, is_mandatory=True)
image_version = CalmVariable.WithOptions.FromTask(CalmTask.Exec.escript(script="print('@@{IMAGE_INFO}@@'.split(' - ')[2])"),label="OS Image Version", is_hidden=False, is_mandatory=True)
IMAGE_INFO = CalmVariable.WithOptions.FromTask(CalmTask.Exec.escript.py3(script=GET_IMAGE_INFO),label="Image information",is_mandatory=True,is_hidden=False,description="",)
DISCOVERY_RUNBOOK_IP_ADDRESS = CalmVariable.Simple("", label="Dummy variable only used by Discovery runbook", is_mandatory=False, is_hidden=True, runtime=False, description="Dummy variable only used by Discovery runbook")
fetch_images = CalmVariable.Simple("False",label="Dummy variable only used by Scale-Out",is_mandatory=False,is_hidden=True,runtime=False,description="")
final_ram = CalmVariable.Simple("", label="", is_mandatory=False, is_hidden=False, runtime=False, description="")
final_socket = CalmVariable.Simple("", label="", is_mandatory=False, is_hidden=False, runtime=False, description="")
vm_uuid = CalmVariable.Simple("", label="", is_mandatory=False, is_hidden=False, runtime=False, description="")
shutdown_status = CalmVariable.Simple("", label="", is_mandatory=False, is_hidden=False, runtime=False, description="")

@action
def NGTTools_Tasks():
    CalmTask.Delay(name="wait_20_before_ngt_mount", delay_seconds=20,)
    CalmTask.Exec.escript.py3(name="Mount_NGT",script=build_task_script(script_file_name="ngt_enable.py", dict=locals()),)
    CalmTask.Delay(name="wait_20_before_ngt_install", delay_seconds=20,)
    CalmTask.Exec.powershell(name="Install_NGT",script=build_task_script(script_file_name="ngt_install.ps1", dict=locals()),cred=ref(BP_CRED_RDSROOT),)
    CalmTask.Exec.powershell(name="EjectCDRom",script=build_task_script(script_file_name="eject_cdrom.ps1", dict=locals()),cred=ref(BP_CRED_RDSROOT),)

END SERVICE

#####################################################################

#####################################################################

DEFINE PACKAGE

DEFINE AHV PACKAGE FOR INHERITANCE

class Package_Common(Package): services = [ref(VM_Provision)]

@action
def __install__():
    CalmTask.Exec.powershell(
        name="Join AD Domain",
        filename=os.path.join(
        "usecase_tasks", "join_domain.ps1"
        ),
        cred=ref(BP_CRED_RDSROOT),
    )
    CalmTask.Exec.escript.py3(name="Check Login",script=build_task_script(script_file_name="calm_check_login.py", dict=locals()),)
    CalmTask.Exec.escript.py3(name="Create CMDB CI for VM",script=build_task_script(script_file_name="create_cmdb_ci.py", dict=locals()),)
    CalmTask.Exec.escript.py3(name="Init Discovery Scan",script=build_task_script(script_file_name="init_discovery_scan.py", dict=locals()),)
    CalmTask.Exec.powershell(name="add_security_groups",filename=os.path.join("usecase_tasks","add_security_groups.ps1"),cred=ref(BP_CRED_RDSROOT),)

@action
def __uninstall__():
    CalmTask.Exec.escript.py3(name="Change CMDB Asset Status",script=build_task_script(script_file_name="change_cmdb_assest_status.py", dict=locals()),target=ref(VM_Provision),)
    CalmTask.Exec.powershell(name="Unjoin from AD",script=build_task_script(script_file_name="unjoin_domain.ps1", dict=locals()),target_endpoint=ref(Endpoint.use_existing(WIN_ENDPOINT)))
    CalmTask.Exec.escript.py3(name="Delete Library Variable",script=build_task_script(script_file_name="delete_libvar.py", dict=locals()),target=ref(VM_Provision),)

class Package_Small(Package_Common): pass

class Package_Medium(Package_Common): pass

class Package_Large(Package_Common): pass

class Package_XLarge(Package_Common): pass

END PACKAGE

##############################################################

#############################################################

DEFINE AHV RESOURCES

class AhvVmResources_Common(AhvVmResources): vCPUs = 1 cores_per_vCPU = 1 memory = 4 guest_customization = AhvVmGC.Sysprep.PreparedScript.withoutDomain( filename=os.path.join("specs", "hostname_sysprep_unattend_xml.xml") ) disks = [AhvVmDisk.Disk.Scsi.cloneFromVMDiskPackage(disk_package, bootable=True), AhvVmDisk.CdRom.Ide.emptyCdRom()] boot_type = "UEFI" nics = [AhvVmNic.NormalNic.ingress("@@{network.uuid}@@")]

class AhvVmResources_Small(AhvVmResources_Common): pass

class AhvVmResources_Medium(AhvVmResources_Common): vCPUs = 2

class AhvVmResources_Large(AhvVmResources_Common): vCPUs = 2 memory = 8

class AhvVmResources_XLarge(AhvVmResources_Common): vCPUs = 2 memory = 16

END AHV RESOURCES

##############################################################

#############################################################

DEFINE SUBSTRATE

DEFINE SUBSTRATE FOR INHERITANCE

name = "@@{fqdn}@@" cluster = Ref.Cluster(name="@@{target_cluster.uuid}@@")

class Substrate_Common(Substrate): """VM Default Substrate"""

account = Ref.Account(name="account_a")
os_type = "Windows"
provider_type = "AHV_VM"
provider_spec_editables = read_spec(os.path.join("specs", "ahv_create_spec_editables.yaml"))
readiness_probe = readiness_probe(connection_type="POWERSHELL",disabled=False,retries="5",connection_port=5985,
    address="@@{platform.status.resources.nic_list[0].ip_endpoint_list[0].ip}@@",delay_secs="120",credential=ref(BP_CRED_RDSROOT),)

@action
def __pre_create__():
    CalmTask.Exec.escript.py3(name="fix_macros",script=build_task_script(script_file_name="fix_macros.py", dict=locals()),)
    CalmTask.Exec.escript.py3(name="select_cluster",script=build_task_script(script_file_name="select_cluster.py", dict=locals()),)
    CalmTask.SetVariable.escript.py3(name="Get Remote Prism Central Address",script=build_task_script(script_file_name="get_remote_pc_address.py", dict=locals()),variables=["PC_PROVIDER_ADDRESS"],)
    CalmTask.SetVariable.escript.py3(name="Get Network Data",script=build_task_script(script_file_name="get_network_data.py", dict=locals()),variables=["network"],)
    CalmTask.SetVariable.escript.py3(name="Get Target Cluster",script=build_task_script(script_file_name="get_target_cluster.py", dict=locals()),variables=["target_cluster"],)
    CalmTask.SetVariable.escript.py3(name="set_hostname",script=build_task_script(script_file_name="set_hostname.py", dict=locals()),variables=["fqdn", "hostname"],)
    CalmTask.Exec.escript.py3(name="Create Libvar for Hostname",script=build_task_script(script_file_name="update_libvar_hostname.py", dict=locals()),)
    CalmTask.SetVariable.escript.py3(name="create_passwordstate_credential",script=build_task_script(script_file_name="create_passwordstate_credential.py", dict=locals()),variables=["OS_MAIN_ACCT_ID", "OS_MAIN_ACCT_USERNAME"],)
    CalmTask.SetVariable.escript.py3(name="add_passwordstate_rbac",script=build_task_script(script_file_name="add_passwordstate_rbac.py", dict=locals()),variables=["security_group_list"])
    CalmTask.SetVariable.escript.py3(name="Get Timezone",script=build_task_script(script_file_name="get_timezone.py", dict=locals()),variables=["timezone"],)
@action
def __post_create__():
    CalmTask.Exec.escript.py3(name="select_category_for_vm",script=build_task_script(script_file_name="select_category_for_vm.py", dict=locals()),)
    VM_Provision.NGTTools_Tasks(name="Configure NGT")

class Substrate_Small(Substrate_Common): provider_spec = ahv_vm( name = name, resources = AhvVmResources_Small, cluster = cluster, )

@action
def __vm_restart__():
    pass
@action
def __vm_check_login__():
    pass

class Substrate_Medium(Substrate_Common): provider_spec = ahv_vm( name = name, resources = AhvVmResources_Medium, cluster = cluster, )

@action
def __vm_restart__():
    pass
@action
def __vm_check_login__():
    pass

class Substrate_Large(Substrate_Common): provider_spec = ahv_vm( name = name, resources = AhvVmResources_Large, cluster = cluster, )

@action
def __vm_restart__():
    pass
@action
def __vm_check_login__():
    pass

class Substrate_XLarge(Substrate_Common): provider_spec = ahv_vm( name = name, resources = AhvVmResources_XLarge, cluster = cluster, )

@action
def __vm_restart__():
    pass
@action
def __vm_check_login__():
    pass

END SUBSTRATE

#############################################################

#############################################################

DEFINE DEPLOYMENT

DEFINE AHV DEPLOYMENT FOR INHERITANCE

class Deployment_Common(Deployment): min_replicas = "1" max_replicas = "10" default_replicas = "@@{NUMBER_OF_VMS}@@"

class Deployment_Small(Deployment_Common): packages = [ref(Package_Small)] substrate = ref(Substrate_Small)

class Deployment_Medium(Deployment_Common): packages = [ref(Package_Medium)] substrate = ref(Substrate_Medium)

class Deployment_Large(Deployment_Common): packages = [ref(Package_Large)] substrate = ref(Substrate_Large)

class Deployment_XLarge(Deployment_Common): packages = [ref(Package_XLarge)] substrate = ref(Substrate_XLarge)

END DEPLOYMENT

###############################################################

###############################################################

BEGIN PROFILES

DEFINE THE COMMON PROFILE FOR INHERITANCE (HIDDEN IN GUI)

class Profile_Common(Profile): environments = [Ref.Environment(name="AHV-ENV")] """ Need for Scale-Out/In as they do not expand the Calm macro calm_username Downstream tasks will need to use this macro to get the Calm Username when Scale-Out/In is utilized """ MY_USERNAME = CalmVariable.WithOptions.FromTask(CalmTask.Exec.escript(name="My Username",script="print('@@{calm_username}@@')"),label="My Username") """ Need for Scale-Out/In as they do not expand the Calm macro calm_project_name Downstream tasks will need to use this macro to get the Calm Project Name when Scale-Out/In is utilized """ PROJECT_NAME = CalmVariable.WithOptions.FromTask(CalmTask.Exec.escript(name="Project Name",script="print('@@{calm_project_name}@@')"),label="Project Name") SELF_SERVICE_ADDRESS = CalmVariable.Simple(SELF_SERVICE_ADDRESS, description="", label="Self Service FQDN", is_hidden=True) SELF_SERVICE_SECURE = CalmVariable.Simple("False", label="", is_mandatory=False, is_hidden=True, runtime=False, description="") SELF_SERVICE_INSTANCE_FUNCTION = CalmVariable.Simple(calm_config['calm_instance_function'], description="", label="", is_hidden=True) INFOBLOX_ADDRESS = CalmVariable.Simple(infoblox_config["INFOBLOX_ENDPOINT"], label="", is_mandatory=False, is_hidden=True, runtime=False, description="") INFOBLOX_SECURE = CalmVariable.Simple("False", label="", is_mandatory=False, is_hidden=True, runtime=False, description="") INFOBLOX_WAPI_VERSION = CalmVariable.Simple(infoblox_config["INFOBLOX_WAPI_VERSION"], label="", is_mandatory=False, is_hidden=True, runtime=False, description="") AD_DOMAIN = CalmVariable.Simple(blueprint_variables["AD_DOMAIN"],label="AD_DOMAIN", is_mandatory=True, is_hidden=True, runtime=True, description="Active Directory Domain Name",) AD_DOMAIN_NETBIOS = CalmVariable.Simple(blueprint_variables["AD_DOMAIN_NETBIOS"],label="AD_DOMAIN_NETBIOS", is_mandatory=True, is_hidden=True, runtime=True, description="Active Directory Domain NetBIOS Name",) AD_OU_PATH = CalmVariable.Simple(blueprint_variables["AD_OU_PATH"], label="AD_OU_PATH", is_mandatory=True, is_hidden=True, runtime=True, description="Active Directory OU path for creating security groups",) OS = CalmVariable.WithOptions(["WIN2022", "WIN2019", "WIN2016"],label="OS Version",default="WIN2022",is_mandatory=True,is_hidden=False,runtime=True,description="The version of OS you want all VMs in the applications to have",) SYSTEM_ROLE = CalmVariable.WithOptions.FromTask.string(CalmTask.Exec.escript.py3(script=QUERY_SYSTEM_ROLE),label="System Role",is_mandatory=True,description="Select the role for the system.",) SYSTEM_ENVIRONMENT = CalmVariable.WithOptions.FromTask.string(CalmTask.Exec.escript.py3(script=QUERY_SYSTEM_ENVIRONMENT),label="System Environment",is_mandatory=True,description="",) DISCOVERY_ENDPOINT = CalmVariable.Simple(blueprint_variables['DISCOVERY_ENDPOINT'], description="", label="Discovery FQDN", is_hidden=True) CMDB_ENDPOINT = CalmVariable.Simple(json.dumps(CMDB_ENDPOINT), description="", label="CMDB FQDN", is_hidden=True) PASSWORDSTATE_ENDPOINT = CalmVariable.Simple(password_state_config["password_state_fqdn"], description="", label="Passwordstate FQDN", is_hidden=True) PASSWORDSTATE_LIST_ID = CalmVariable.Simple(password_state_config['PASSWORD_STATE_CREDENTIALS']['password_state_id_information']['passwordstate_list_id'], description="", label="Passwordstate BCX Local Passwords List Id", is_hidden=True) NUMBER_OF_VMS = CalmVariable.WithOptions(["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"], default="1", label="# of VMs", description="The number of VMs you want in the application", is_mandatory=True, runtime=True) OS_MAIN_ACCT_ID = CalmVariable.Simple("", label="Placeholder variable", is_mandatory=False, is_hidden=True, runtime=False, description="Placeholder variable") CONFIGURATION_FILES_LOCATION = CalmVariable.Simple(blueprint_variables['CONFIGURATION_FILES_LOCATION'], description="", label="URL for the configuration files root", is_hidden=True) PLATFORM_TYPE = CalmVariable.Simple("AHV",label="Variable used to determine hypervisor type",is_mandatory=False,is_hidden=True,runtime=False,description="") PROJECT_ESX_INFRASTRUCTURE_LIST = CalmVariable.Simple( json.dumps(PROJECT_ESX_INFRASTRUCTURE_LIST), label="ESX infrastructure static data", is_mandatory=True, is_hidden=(True if PROJECT_ESX_INFRASTRUCTURE_LIST else False), runtime=(False if PROJECT_ESX_INFRASTRUCTURE_LIST else True), description="ESX infrastructure static data" )

@action
def GetCredential(name="Get Credential"):
    CalmTask.Exec.escript.py3(name="get_passwordstate_credential", script=build_task_script(script_file_name="get_passwordstate_credential.py", dict=locals()), target=ref(VM_Provision))
@action
def CreateRecoveryPoint(name="Create Recovery Point"):
    expiration_days = CalmVariable.Simple.int("14",label="# of days to keep Recovery Points",is_mandatory=False,is_hidden=False,runtime=True,description="",regex='^([0-9]|[1-9][0-9]|[12][0-9][0-9]|3[0-5][0-9]|36[0-5])$')
    max_recovery_points = CalmVariable.Simple("3",label="Max Number of Recovery Points Allowed",is_mandatory=False,is_hidden=True,runtime=False,description="")
    recovery_point_type = CalmVariable.WithOptions.Predefined(["CRASH_CONSISTENT","APPLICATION_CONSISTENT"],default="CRASH_CONSISTENT",label="Type of Recovery Point",is_mandatory=False,is_hidden=False,runtime=True,description="")
    CalmTask.Exec.escript.py3(name="create_vm_recovery_point", script=build_task_script(script_file_name="create_vm_recovery_point.py", dict=locals()), target=ref(VM_Provision))
@action
def RestoreRecoveryPoint(name="Restore Recovery Point"):
    CalmTask.Exec.escript.py3(name="revert_vm_recovery_point", script=build_task_script(script_file_name="revert_vm_recovery_point.py", dict=locals()), target=ref(VM_Provision))
@action
def DeleteRecoveryPoint(name="Delete Recovery Point"):
    CalmTask.Exec.escript.py3(name="delete_vm_recovery_point", script=build_task_script(script_file_name="delete_vm_recovery_point.py", dict=locals()), target=ref(VM_Provision))

@action
def UpdateConfig(name="Update CPU RAM of VM"):
    """Update Compute And/OR RAM """

    RAM = CalmVariable.Simple.int("0",label="RAM To Add/Decrease (GB)",is_mandatory=True,is_hidden=False,runtime=True,description="Use zero for no change",)
    CPU = CalmVariable.Simple.int("0",label="Number of CPU To Add/Decrease",is_mandatory=True,is_hidden=False,runtime=True,description="Use zero for no change",)
    action = CalmVariable.WithOptions(["Increase","Decrease"],default = "Increase",label="Resource action",validate_regex=False,is_mandatory=False,is_hidden=False,
        runtime=True,description="Decrease in config will shutdown the VM for some time !!!",)
    VM_NAME = CalmVariable.WithOptions.FromTask(CalmTask.Exec.escript.py3(name="Get Application VM list",script=build_task_script(script_file_name="get_app_vms.py", dict=locals()),),
        label="Select VM",is_mandatory=False,is_hidden=False,)
    CalmTask.SetVariable.escript.py3(
        name="Validate Request",
        script=build_task_script(script_file_name="validate_update_config.py", dict=locals()),
        variables=["final_ram","final_socket","vm_uuid","shutdown_status"],
        target=ref(VM_Provision),
    )
    CalmTask.Exec.escript.py3(
        name="Update VM Config",
        script=build_task_script(script_file_name="update_config.py", dict=locals()),
        target=ref(VM_Provision),
    )

class Small_1vCPU_4GB(Profile_Common): deployments = [Deployment_Small]

@action
def ScaleOut(name="Scale Out"):
    increase_count = CalmVariable.Simple("1",label="Expand by # of VMs",is_mandatory=False,is_hidden=False,runtime=True,description="",)
    fetch_images = CalmVariable.Simple("True",label="",is_mandatory=False,is_hidden=True,runtime=False,description="")
    CalmTask.SetVariable.escript.py3(name="get_image_info", script=build_task_script(script_file_name="get_image_info.py", dict=locals()), target=ref(VM_Provision), variables=["image_name", "image_source", "image_version"])
    CalmTask.Scaling.scale_out("@@{increase_count}@@",name="ScaleOut",target=ref(Deployment_Small),)
@action
def ScaleIn(name="Scale In"):
    decrease_count = CalmVariable.Simple("1",label="Shrink by # of VMs",is_mandatory=False,is_hidden=False,runtime=True,description="",)
    CalmTask.Scaling.scale_in("@@{decrease_count}@@",name="ScaleIn",target=ref(Deployment_Small),)

class Medium_2vCPU_4GB(Profile_Common): deployments = [Deployment_Medium]

@action
def ScaleOut(name="Scale Out"):
    increase_count = CalmVariable.Simple("1",label="Expand by # of VMs",is_mandatory=False,is_hidden=False,runtime=True,description="",)
    fetch_images = CalmVariable.Simple("True",label="",is_mandatory=False,is_hidden=True,runtime=False,description="")
    CalmTask.SetVariable.escript.py3(name="get_image_info", script=build_task_script(script_file_name="get_image_info.py", dict=locals()), target=ref(VM_Provision), variables=["image_name", "image_source", "image_version"])
    CalmTask.Scaling.scale_out("@@{increase_count}@@",name="ScaleOut",target=ref(Deployment_Medium),)
@action
def ScaleIn(name="Scale In"):
    decrease_count = CalmVariable.Simple("1",label="Shrink by # of VMs",is_mandatory=False,is_hidden=False,runtime=True,description="",)
    CalmTask.Scaling.scale_in("@@{decrease_count}@@",name="ScaleIn",target=ref(Deployment_Medium),)

class Large_2vCPU_8GB(Profile_Common): deployments = [Deployment_Large]

@action
def ScaleOut(name="Scale Out"):
    increase_count = CalmVariable.Simple("1",label="Expand by # of VMs",is_mandatory=False,is_hidden=False,runtime=True,description="",)
    fetch_images = CalmVariable.Simple("True",label="",is_mandatory=False,is_hidden=True,runtime=False,description="")
    CalmTask.SetVariable.escript.py3(name="get_image_info", script=build_task_script(script_file_name="get_image_info.py", dict=locals()), target=ref(VM_Provision), variables=["image_name", "image_source", "image_version"])
    CalmTask.Scaling.scale_out("@@{increase_count}@@",name="ScaleOut",target=ref(Deployment_Large),)
@action
def ScaleIn(name="Scale In"):
    decrease_count = CalmVariable.Simple("1",label="Shrink by # of VMs",is_mandatory=False,is_hidden=False,runtime=True,description="",)
    CalmTask.Scaling.scale_in("@@{decrease_count}@@",name="ScaleIn",target=ref(Deployment_Large),)

class XLarge_2vCPU_16GB(Profile_Common): deployments = [Deployment_XLarge]

@action
def ScaleOut(name="Scale Out"):
    increase_count = CalmVariable.Simple("1",label="Expand by # of VMs",is_mandatory=False,is_hidden=False,runtime=True,description="",)
    fetch_images = CalmVariable.Simple("True",label="",is_mandatory=False,is_hidden=True,runtime=False,description="")
    CalmTask.SetVariable.escript.py3(name="get_image_info", script=build_task_script(script_file_name="get_image_info.py", dict=locals()), target=ref(VM_Provision), variables=["image_name", "image_source", "image_version"])
    CalmTask.Scaling.scale_out("@@{increase_count}@@",name="ScaleOut",target=ref(Deployment_XLarge),)
@action
def ScaleIn(name="Scale In"):
    decrease_count = CalmVariable.Simple("1",label="Shrink by # of VMs",is_mandatory=False,is_hidden=False,runtime=True,description="",)
    CalmTask.Scaling.scale_in("@@{decrease_count}@@",name="ScaleIn",target=ref(Deployment_XLarge),)

END PROFILES

##############################################################

##############################################################

DEFINE BLUEPRINT

class Windows_BP(Blueprint): services = [VM_Provision] packages = [Package_Small, Package_Medium, Package_Large, Package_XLarge, disk_package] substrates = [Substrate_Small, Substrate_Medium, Substrate_Large, Substrate_XLarge] profiles = [Small_1vCPU_4GB, Medium_2vCPU_4GB, Large_2vCPU_8GB, XLarge_2vCPU_16GB] credentials = [BP_CRED_RDSROOT, BP_CRED_RDSMON, BP_CRED_AD, BP_CRED_SELF_SERVICE, BP_CRED_INFOBLOX, BP_CRED_DISCOVERY, BP_CRED_CMDB, BP_CRED_LOCAL_LIST_PASSWORDSTATE, BP_CRED_SECURITYGROUP_PASSWORDSTATE, BP_CRED_PC]

END BLUEPRINT

############################################################

Setting the Docstring for blueprint to description file contents.

This file is used for both blueprint and marketplace descriptions.

Windows_BP.doc = read_file('mp_meta/bp-description-ahv.md')

def main(): print(Windows_BP.json_dumps(pprint=True))

if name == "main": main()