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

"public_settings" and "private_settings" in extension for Azure Stateful Node #20

Merged
merged 2 commits into from
Dec 19, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
9 changes: 9 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,12 @@ Release Summary
---------------

Added new fields in azure_stateful_node module.


v1.3.3
======

Release Summary
---------------

- spot.cloud_modules.azure_stateful_node - Added `public_settings` and `protected_settings` fields in the `extensions` object.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Version 2 of Spot's Python SDK does not support Python 2.7 so this collection re

## Spot Python SDK compatibility

Version `1.2.0` of this collection requires at least version `2.1.30` of Spot's Python SDK.
Version `1.3.3` of this collection requires at least version `2.3.1` of Spot's Python SDK.

## Included content

Expand Down Expand Up @@ -53,7 +53,7 @@ be manually installed using pip and from the collection project's root, running:
pip install requirements.txt
or:

pip install spotinst_sdk2>=2.3.0
pip install spotinst_sdk2>=2.3.1

## Using this collection

Expand Down
10 changes: 10 additions & 0 deletions changelogs/changelog.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
ancestor: null
releases:
1.3.3:
changes:
release_summary: Added `public_settings` and `protected_settings` fields in the `extensions` object.
fragments:
- 1-3-3-summary.yml
modules:
- description: Create, update, delete or Import Spot Azure Stateful Nodes
name: azure_stateful_node
namespace: ''
release_date: '2023-12-18'
chandra1-n marked this conversation as resolved.
Show resolved Hide resolved
1.3.2:
changes:
release_summary: Added new fields in azure_stateful_node module
Expand Down
1 change: 1 addition & 0 deletions docs/examples/stateful_node/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@
* [Perform an action on a Stateful Node](azure-stateful-node-with-action.yaml)
* [Delete a Stateful Node](azure-stateful-node-delete.yaml)
* [Import an Azure VM to Stateful Node](azure-stateful-node-import.yaml)
* [Create a Stateful Node with Extensions](azure-stateful-node-extensions.yaml)
<!--te-->
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
do_not_update:
- region
- resource_group_name
- compute.os
stateful_node_config:
deletion_config:
deallocation_config:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
do_not_update:
- region
- resource_group_name
- compute.os
stateful_node:
name: "ansible-stateful-node-example"
description: "a sample Stateful Node created via Ansible"
Expand Down
81 changes: 81 additions & 0 deletions docs/examples/stateful_node/azure-stateful-node-extensions.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
- hosts: localhost
tasks:
- name: stateful_node
spot.cloud_modules.azure_stateful_node:
state: present # absent = delete, present = create/update
credentials_path: "./credentials.yaml"
uniqueness_by: "id"
do_not_update:
- compute.os
- region
- resource_group_name
stateful_node:
name: "ansible-stateful-node-example"
description: "a sample Stateful Node created via Ansible"
region: "eastus"
resource_group_name: "AutomationResourceGroup"
persistence:
data_disks_persistence_mode: "reattach"
os_disk_persistence_mode: "reattach"
should_persist_data_disks: false
should_persist_network: false
should_persist_os_disk: true
strategy:
availability_vs_cost: 75
draining_timeout: 120
fallback_to_od: false
preferred_lifecycle: "spot"
revert_to_spot:
perform_at: "always"
compute:
os: "Windows"
zones: ["1", "2"]
preferred_zone: "2"
vm_sizes:
od_sizes: ["standard_ds1_v2"]
spot_sizes: ["standard_ds1_v2", "standard_ds2_v2"]
preferred_spot_sizes: ["standard_ds1_v2"]
launch_specification:
boot_diagnostics:
is_enabled: true
type: "managed"
image:
marketplace:
publisher: "MicrosoftWindowsServer"
version: "latest"
sku: "2016-Datacenter"
offer: "WindowsServer"
login:
user_name: "azureuser"
password: "<your-password>"
network:
resource_group_name: "AutomationResourceGroup"
virtual_network_name: "Automation-VirtualNetwork"
network_interfaces:
- is_primary: true
assign_public_ip: false
public_ip_sku: "Standard"
subnet_name: "Automation-PrivateSubnet"
enable_ip_forwarding: true
os_disk:
size_g_b: 130
type: "Standard_LRS"
extensions:
- api_version: "1.10"
minor_version_auto_upgrade: true
name: "MyTestExtension"
publisher: "Microsoft.Compute"
type: "CustomScriptExtension"
public_settings:
commandToExecute: "myExecutionCommand"
storageAccountName: "myStorageAccountName"
storageAccountKey: "myStorageAccountKey"
fileUris:
- "https://testspotinstautomation.blob.core.windows.net/testcontainer/Azuretest.sh"
tags:
- tag_key: "Creator"
tag_value: "Ansible Test"
- tag_key: "Name"
tag_value: "Ansible Extensions Example"
register: result
- debug: var=result
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
do_not_update:
- region
- resource_group_name
- compute.os
stateful_node_config:
import_vm_config: # Import configuration
draining_timeout: 120
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
do_not_update:
- region
- resource_group_name
- compute.os
action: "pause" # resume, recycle <------ if you would just like to perform an action, leave all other fields as is and include this line.
stateful_node:
name: "ansible-stateful-node-example-with-action"
Expand Down
2 changes: 1 addition & 1 deletion galaxy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace: spot
name: cloud_modules

# The version of the collection. Must be compatible with semantic versioning
version: 1.3.2
version: 1.3.3

# The path to the Markdown (.md) readme file. This path is relative to the root of the collection
readme: README.md
Expand Down
31 changes: 30 additions & 1 deletion plugins/modules/azure_stateful_node.py
Original file line number Diff line number Diff line change
Expand Up @@ -833,6 +833,7 @@
"stateful_node_config.import_vm_config": "ImportVmConfiguration"
}


LIST_MEMBER_CLS_NAME_BY_ATTR_NAME = {
"stateful_node.compute.launch_specification.load_balancers_config.load_balancers": "LoadBalancer",
"stateful_node.compute.launch_specification.network.network_interfaces.application_security_groups": "ApplicationSecurityGroup",
Expand All @@ -842,6 +843,11 @@
}


LIST_OBJECTS_CLS_NAME_BY_ATTR_NAME = [
"stateful_node.compute.launch_specification.extensions.public_settings",
"stateful_node.compute.launch_specification.extensions.protected_settings"
]

def to_snake_case(camel_str):
import re
ret_val = re.sub(r'(?<!^)(?=[A-Z])', '_', camel_str).lower()
Expand Down Expand Up @@ -892,16 +898,33 @@ def get_client(module):
else:
session = spotinst.SpotinstSession(auth_token=token)

client = session.client("stateful_node_azure", log_level="debug")
client = session.client("stateful_node_azure")

return client


def serialize_json_object(obj):
if isinstance(obj, dict):
serialized_dict = {}
for key, value in obj.items():
serialized_dict[key] = serialize_json_object(value)
return serialized_dict
elif isinstance(obj, list):
serialized_list = []
for item in obj:
serialized_list.append(serialize_json_object(item))
return serialized_list
else:
return obj


def turn_to_model(content, field_name: str, curr_path=None):
if content is None:
return None

elif is_primitive(content):
return content

elif isinstance(content, list):
new_l = []

Expand All @@ -917,6 +940,10 @@ def turn_to_model(content, field_name: str, curr_path=None):
else:
curr_path = field_name

# To handle Dictionary where keys are not known in advance
if curr_path in LIST_OBJECTS_CLS_NAME_BY_ATTR_NAME:
return serialize_json_object(content)

override = find_in_overrides(curr_path)
key_to_use = override if override else to_pascal_case(field_name)

Expand Down Expand Up @@ -1334,6 +1361,8 @@ def main():
name=dict(type="str", required=True),
publisher=dict(type="str", required=True),
type=dict(type="str", required=True),
public_settings=dict(type="str"),
protected_settings=dict(type="str"),
)

marketplace_image_fields = dict(
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
spotinst_sdk2>=2.3.0
spotinst_sdk2>=2.3.1
2 changes: 1 addition & 1 deletion tests/unit/requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
spotinst_sdk2>=2.3.0; python_version >= "3.6"
spotinst_sdk2>=2.3.1; python_version >= "3.6"
Loading