Skip to content

Commit 3fcd8e8

Browse files
authored
Support for Partition profile Create Copy and Modify (#156)
Support for Partition profile Create Copy and Modify
1 parent 2e84b72 commit 3fcd8e8

File tree

3 files changed

+1384
-0
lines changed

3 files changed

+1384
-0
lines changed

plugins/module_utils/hmc_rest_client.py

Lines changed: 291 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2725,3 +2725,294 @@ def fetchJobStatusJSON(self, job_url):
27252725
except Exception as e:
27262726
logger.error("Failed to check job status: %s", e)
27272727
return "Error"
2728+
2729+
def getAllPartitionProfiles(self, lpar_uuid, profile_name=None):
2730+
url = "https://{0}/rest/api/uom/LogicalPartition/{1}/LogicalPartitionProfile".format(self.hmc_ip, lpar_uuid)
2731+
header = {'X-API-Session': self.session,
2732+
'Accept': '*/*'}
2733+
resp = open_url(url,
2734+
headers=header,
2735+
method='GET',
2736+
validate_certs=False,
2737+
force_basic_auth=True,
2738+
timeout=300)
2739+
if resp.code != 200:
2740+
logger.debug("Get of partition profile failed. Respsonse code: %d", resp.code)
2741+
return None
2742+
response = resp.read()
2743+
if profile_name is None:
2744+
return response
2745+
elif profile_name is not None:
2746+
post_response = xml_strip_namespace(response)
2747+
entries = post_response.xpath("//entry")
2748+
for entry in entries:
2749+
profile_name_elem = entry.xpath(".//ProfileName")
2750+
if profile_name_elem and profile_name_elem[0].text == profile_name:
2751+
atom_id_elem = entry.xpath(".//AtomID")
2752+
if atom_id_elem:
2753+
return atom_id_elem[0].text
2754+
return None
2755+
2756+
def getCurrentPartitionProfiles(self, lpar_uuid, profile_uuid):
2757+
url = "https://{0}/rest/api/uom/LogicalPartition/{1}/LogicalPartitionProfile/{2}".format(self.hmc_ip, lpar_uuid, profile_uuid)
2758+
header = {'X-API-Session': self.session,
2759+
'Accept': '*/*'}
2760+
resp = open_url(url,
2761+
headers=header,
2762+
method='GET',
2763+
validate_certs=False,
2764+
force_basic_auth=True,
2765+
timeout=300)
2766+
if resp.code != 200:
2767+
logger.debug("Get of partition profile failed. Respsonse code: %d", resp.code)
2768+
return None
2769+
response = resp.read()
2770+
return response
2771+
2772+
def copyPartitionProfile(self, lpar_uuid, params):
2773+
payload = {
2774+
"JobRequest": {
2775+
"Metadata": {
2776+
"Atom": ""
2777+
},
2778+
"RequestedOperation": {
2779+
"Metadata": {
2780+
"Atom": ""
2781+
},
2782+
"OperationName": "CopyProfile",
2783+
"GroupName": "LogicalPartition"
2784+
},
2785+
"JobParameters": {
2786+
"Metadata": {
2787+
"Atom": ""
2788+
},
2789+
"JobParameter": [
2790+
{
2791+
"Metadata": {
2792+
"Atom": ""
2793+
},
2794+
"ParameterName": "existingPartitionProfileName",
2795+
"ParameterValue": params['name']
2796+
},
2797+
{
2798+
"Metadata": {
2799+
"Atom": ""
2800+
},
2801+
"ParameterName": "newPartitionProfileName",
2802+
"ParameterValue": params['duplicate_prof_name']
2803+
}
2804+
]
2805+
}
2806+
}
2807+
}
2808+
url = "https://{0}/rest/api/uom/LogicalPartition/{1}/do/CopyProfile".format(self.hmc_ip, lpar_uuid)
2809+
header = {'X-API-Session': self.session,
2810+
'Accept': 'application/json',
2811+
'Content-Type': 'application/vnd.ibm.powervm.web+json; type=JobRequest'}
2812+
try:
2813+
resp = open_url(url,
2814+
headers=header,
2815+
data=json.dumps(payload),
2816+
method='PUT',
2817+
validate_certs=False,
2818+
force_basic_auth=True,
2819+
timeout=300)
2820+
resp = json.loads(resp.read())
2821+
self_link = resp['entry']['selfLink']
2822+
response = self.fetchJobStatusJSON(self_link)
2823+
status = response['entry']['content']['JobResponse']['Status']
2824+
if status == 'FAILED_BEFORE_COMPLETION':
2825+
response = response['entry']['content']['JobResponse']
2826+
if response.get('ResponseException'):
2827+
return response
2828+
elif status == 'COMPLETED_OK':
2829+
return 200
2830+
except Exception as e:
2831+
logger.debug("Error in copyPartitionProfile: %s", str(e))
2832+
return f"Error: {str(e)}"
2833+
2834+
def dedicatedProcessorPayload(self, params):
2835+
payload = '''
2836+
<AssignAllResources kxe="false" kb="COD">false</AssignAllResources>
2837+
<ProcessorAttributes kxe="false" kb="CUR" schemaVersion="V1_0">
2838+
<Metadata>
2839+
<Atom/>
2840+
</Metadata>
2841+
<DedicatedProcessorConfiguration kxe="false" kb="CUD" schemaVersion="V1_0">
2842+
<Metadata>
2843+
<Atom/>
2844+
</Metadata>
2845+
<DesiredProcessors kb="CUD" kxe="false">{0}</DesiredProcessors>
2846+
<MaximumProcessors kb="CUD" kxe="false">{1}</MaximumProcessors>
2847+
<MinimumProcessors kxe="false" kb="CUD">{2}</MinimumProcessors>
2848+
</DedicatedProcessorConfiguration>
2849+
<HasDedicatedProcessors kxe="false" kb="CUD">{3}</HasDedicatedProcessors>
2850+
<SharingMode kxe="false" kb="CUD">{4}</SharingMode>
2851+
</ProcessorAttributes>
2852+
'''.format(params['desired_processors'], params['maximum_processors'], params['minimum_processors'],
2853+
params['processor_mode'], params['allow_processor_sharing'])
2854+
return payload
2855+
2856+
def sharedProcessorPayload(self, params):
2857+
payload = '''
2858+
<AssignAllResources kb="COD" kxe="false">false</AssignAllResources>
2859+
<ProcessorAttributes kxe="false" kb="CUR" schemaVersion="V1_0">
2860+
<Metadata>
2861+
<Atom/>
2862+
</Metadata>
2863+
<HasDedicatedProcessors kxe="false" kb="CUD">{0}</HasDedicatedProcessors>
2864+
<SharedProcessorConfiguration kxe="false" kb="CUD" schemaVersion="V1_0">
2865+
<Metadata>
2866+
<Atom/>
2867+
</Metadata>
2868+
<DesiredProcessingUnits kb="CUD" kxe="false">{1}</DesiredProcessingUnits>
2869+
<DesiredVirtualProcessors kxe="false" kb="CUD">{2}</DesiredVirtualProcessors>
2870+
<MaximumProcessingUnits kb="CUD" kxe="false">{3}</MaximumProcessingUnits>
2871+
<MaximumVirtualProcessors kxe="false" kb="CUD">{4}</MaximumVirtualProcessors>
2872+
<MinimumProcessingUnits kxe="false" kb="CUD">{5}</MinimumProcessingUnits>
2873+
<MinimumVirtualProcessors kb="CUD" kxe="false">{6}</MinimumVirtualProcessors>
2874+
<SharedProcessorPoolID kb="CUD" kxe="false">{7}</SharedProcessorPoolID>
2875+
<UncappedWeight kb="CUD" kxe="false">{8}</UncappedWeight>
2876+
</SharedProcessorConfiguration>
2877+
<SharingMode kb="CUD" kxe="false">{9}</SharingMode>
2878+
</ProcessorAttributes>
2879+
'''.format(params['processor_mode'], params['desired_processing_units'], params['desired_processors'],
2880+
params['maximum_processing_units'], params['maximum_processors'], params['minimum_processing_units'],
2881+
params['minimum_processors'], params['shared_processor_pool'], params['uncapped_weight'], params['sharing_mode'])
2882+
return payload
2883+
2884+
def createPartitionProfile(self, lpar_uuid, params):
2885+
partiton_profile_xmlstr = ''
2886+
template_partition_profile = '''<LogicalPartitionProfile:LogicalPartitionProfile
2887+
xmlns:LogicalPartitionProfile="http://www.ibm.com/xmlns/systems/power/firmware/uom/mc/2012_10/"
2888+
xmlns="http://www.ibm.com/xmlns/systems/power/firmware/uom/mc/2012_10/"
2889+
xmlns:ns2="http://www.w3.org/XML/1998/namespace/k2" schemaVersion="V1_0">'''
2890+
partiton_profile_xmlstr += template_partition_profile
2891+
if params['processor_mode'].lower() == 'false':
2892+
partiton_profile_xmlstr += self.sharedProcessorPayload(params)
2893+
else:
2894+
partiton_profile_xmlstr += self.dedicatedProcessorPayload(params)
2895+
memory_payload = '''<ProfileMemory kb="CUR" kxe="false" schemaVersion="V1_0">
2896+
<Metadata>
2897+
<Atom/>
2898+
</Metadata>
2899+
<ActiveMemoryExpansionEnabled kb="CUD" kxe="false">{0}</ActiveMemoryExpansionEnabled>
2900+
<ActiveMemorySharingEnabled kb="CUD" kxe="false">false</ActiveMemorySharingEnabled>
2901+
<DesiredHugePageCount kb="CUD" kxe="false">{1}</DesiredHugePageCount>
2902+
<DesiredMemory kxe="false" kb="CUD">{2}</DesiredMemory>
2903+
<ExpansionFactor kb="CUD" kxe="false">{3}</ExpansionFactor>
2904+
<HardwarePageTableRatio kb="CUD" kxe="false">{4}</HardwarePageTableRatio>
2905+
<MaximumHugePageCount kb="CUD" kxe="false">{5}</MaximumHugePageCount>
2906+
<MaximumMemory kb="CUD" kxe="false">{6}</MaximumMemory>
2907+
<MinimumHugePageCount kb="CUD" kxe="false">{7}</MinimumHugePageCount>
2908+
<MinimumMemory kxe="false" kb="CUD">{8}</MinimumMemory>
2909+
<DesiredPhysicalPageTableRatio ksv="V1_6_0" kb="CUD" kxe="false">{9}</DesiredPhysicalPageTableRatio>
2910+
</ProfileMemory>
2911+
<ProfileName kb="CUR" kxe="false">{10}</ProfileName>
2912+
</LogicalPartitionProfile:LogicalPartitionProfile>
2913+
'''.format(str(params['active_memory_expansion']).lower(),
2914+
params['desired_huge_pagecount'], params['desired_memory'], params['expansion_factor'], params['hardware_page_tableratio'],
2915+
params['maximum_huge_pagecount'], params['maximum_memory'], params['minimum_huge_pagecount'],
2916+
params['minimum_memory'], params['desired_physical_page_tableratio'], params['name'])
2917+
partiton_profile_xmlstr += memory_payload
2918+
if 'sharing_mode' in params:
2919+
if params['sharing_mode'] == 'capped':
2920+
xml_tree = etree.fromstring(partiton_profile_xmlstr.encode())
2921+
for elem in xml_tree.xpath('.//*[local-name()="UncappedWeight"]'):
2922+
elem.getparent().remove(elem)
2923+
partiton_profile_xmlstr = etree.tostring(xml_tree, encoding='unicode')
2924+
url = "https://{0}/rest/api/uom/LogicalPartition/{1}/LogicalPartitionProfile".format(self.hmc_ip, lpar_uuid)
2925+
header = {'X-API-Session': self.session,
2926+
'Accept': '*/*',
2927+
'Content-Type': 'application/vnd.ibm.powervm.uom+xml; type=LogicalPartitionProfile'}
2928+
try:
2929+
resp = open_url(url,
2930+
headers=header,
2931+
data=partiton_profile_xmlstr,
2932+
method='PUT',
2933+
validate_certs=False,
2934+
force_basic_auth=True,
2935+
timeout=300)
2936+
response = resp.read()
2937+
except Exception as e:
2938+
if hasattr(e, 'read'):
2939+
response = e.read()
2940+
post_response = xml_strip_namespace(response)
2941+
error_message_elements = post_response.xpath("//Message")
2942+
logger.debug(response)
2943+
return e.code, error_message_elements[0].text.strip()
2944+
else:
2945+
return f"Error: {str(e)}"
2946+
post_response = xml_strip_namespace(response)
2947+
profile_name_elements = post_response.xpath("//ProfileName")
2948+
if profile_name_elements:
2949+
return 200, profile_name_elements[0].text
2950+
return "Error: Profile creation failed with unknown error"
2951+
2952+
def updatePartitionProfile(self, lpar_uuid, partition_uuid, params):
2953+
partiton_profile_xmlstr = ''
2954+
template_partition_profile = '''<LogicalPartitionProfile:LogicalPartitionProfile
2955+
xmlns:LogicalPartitionProfile="http://www.ibm.com/xmlns/systems/power/firmware/uom/mc/2012_10/"
2956+
xmlns="http://www.ibm.com/xmlns/systems/power/firmware/uom/mc/2012_10/"
2957+
xmlns:ns2="http://www.w3.org/XML/1998/namespace/k2" schemaVersion="V1_0">'''
2958+
partiton_profile_xmlstr += template_partition_profile
2959+
if params['processor_mode'].lower() == 'false':
2960+
partiton_profile_xmlstr += self.sharedProcessorPayload(params)
2961+
else:
2962+
partiton_profile_xmlstr += self.dedicatedProcessorPayload(params)
2963+
memory_payload = '''<ProfileMemory kb="CUR" kxe="false" schemaVersion="V1_0">
2964+
<Metadata>
2965+
<Atom/>
2966+
</Metadata>
2967+
<ActiveMemoryExpansionEnabled kb="CUD" kxe="false">{0}</ActiveMemoryExpansionEnabled>
2968+
<ActiveMemorySharingEnabled kb="CUD" kxe="false">false</ActiveMemorySharingEnabled>
2969+
<DesiredHugePageCount kb="CUD" kxe="false">{1}</DesiredHugePageCount>
2970+
<DesiredMemory kxe="false" kb="CUD">{2}</DesiredMemory>
2971+
<ExpansionFactor kb="CUD" kxe="false">{3}</ExpansionFactor>
2972+
<HardwarePageTableRatio kb="CUD" kxe="false">{4}</HardwarePageTableRatio>
2973+
<MaximumHugePageCount kb="CUD" kxe="false">{5}</MaximumHugePageCount>
2974+
<MaximumMemory kb="CUD" kxe="false">{6}</MaximumMemory>
2975+
<MinimumHugePageCount kb="CUD" kxe="false">{7}</MinimumHugePageCount>
2976+
<MinimumMemory kxe="false" kb="CUD">{8}</MinimumMemory>
2977+
<DesiredPhysicalPageTableRatio ksv="V1_6_0" kb="CUD" kxe="false">{9}</DesiredPhysicalPageTableRatio>
2978+
</ProfileMemory>
2979+
<ProfileName kb="CUR" kxe="false">{10}</ProfileName>
2980+
</LogicalPartitionProfile:LogicalPartitionProfile>
2981+
'''.format(str(params['active_memory_expansion']).lower(),
2982+
params['desired_huge_pagecount'], params['desired_memory'], params['expansion_factor'], params['hardware_page_tableratio'],
2983+
params['maximum_huge_pagecount'], params['maximum_memory'], params['minimum_huge_pagecount'],
2984+
params['minimum_memory'], params['desired_physical_page_tableratio'], params['name'])
2985+
partiton_profile_xmlstr += memory_payload
2986+
if 'sharing_mode' in params:
2987+
if params['sharing_mode'] == 'capped':
2988+
xml_tree = etree.fromstring(partiton_profile_xmlstr.encode())
2989+
for elem in xml_tree.xpath('.//*[local-name()="UncappedWeight"]'):
2990+
elem.getparent().remove(elem)
2991+
partiton_profile_xmlstr = etree.tostring(xml_tree, encoding='unicode')
2992+
url = "https://{0}/rest/api/uom/LogicalPartition/{1}/LogicalPartitionProfile/{2}".format(self.hmc_ip, lpar_uuid, partition_uuid)
2993+
header = {'X-API-Session': self.session,
2994+
'Accept': '*/*',
2995+
'Content-Type': 'application/vnd.ibm.powervm.uom+xml; type=LogicalPartitionProfile'}
2996+
try:
2997+
resp = open_url(url,
2998+
headers=header,
2999+
data=partiton_profile_xmlstr,
3000+
method='POST',
3001+
validate_certs=False,
3002+
force_basic_auth=True,
3003+
timeout=300)
3004+
response = resp.read()
3005+
except Exception as e:
3006+
if hasattr(e, 'read'):
3007+
response = e.read()
3008+
post_response = xml_strip_namespace(response)
3009+
error_message_elements = post_response.xpath("//Message")
3010+
logger.debug(response)
3011+
return e.code, error_message_elements[0].text.strip()
3012+
else:
3013+
return f"Error: {str(e)}"
3014+
post_response = xml_strip_namespace(response)
3015+
profile_name_elements = post_response.xpath("//ProfileName")
3016+
if profile_name_elements:
3017+
return 200, profile_name_elements[0].text
3018+
return "Error: Profile creation failed with unknown error"

0 commit comments

Comments
 (0)