From dc8ac25745747b9c1775013ab30f0288acb6cdb6 Mon Sep 17 00:00:00 2001 From: Amrutha Ramanathan <105342664+ramrutha497@users.noreply.github.com> Date: Thu, 20 Jun 2024 17:59:56 +0530 Subject: [PATCH 1/3] update azure api support --- spotinst_sdk2/clients/ocean/__init__.py | 156 +++++++++++++++++++ spotinst_sdk2/models/ocean/azure/__init__.py | 45 ++++++ 2 files changed, 201 insertions(+) diff --git a/spotinst_sdk2/clients/ocean/__init__.py b/spotinst_sdk2/clients/ocean/__init__.py index eef292dd..856a5f70 100644 --- a/spotinst_sdk2/clients/ocean/__init__.py +++ b/spotinst_sdk2/clients/ocean/__init__.py @@ -1154,6 +1154,7 @@ def delete_extended_resource_definition(self, ocean_extended_resource_definition class OceanAzureClient(Client): __base_ocean_cluster_url = "/ocean/azure/np/cluster" __base_ocean_vng_url = "/ocean/azure/np/virtualNodeGroup" + __base_ocean_k8s_url = "/ocean/azure/k8s/cluster/" def create_ocean_cluster(self, ocean: azure_ocean.Ocean): """ @@ -1693,9 +1694,164 @@ def list_migrations(self, ocean_id: str): response, self.camel_to_underscore) return formatted_response["response"] + + def detach_instances(self, ocean_id: str, detach_nodes: azure_ocean.DetachNodes): + """ + Detach instances from your Ocean cluster. + + # Arguments + detach_instance (DetachNodes): Detach Nodes Object + + # Returns + (Object): Detach Nodes response + """ + request = azure_ocean.DetachNodesRequest(detach_nodes) + + excluded_missing_dict = self.exclude_missing( + json.loads(request.toJSON())) + + formatted_missing_dict = self.convert_json( + excluded_missing_dict, self.underscore_to_camel) + + body_json = json.dumps(formatted_missing_dict) + + response = self.send_put( + body=body_json, + url=self.__base_ocean_cluster_url + "/detachNodes", + entity_name='ocean detach nodes') + + formatted_response = self.convert_json( + response, self.camel_to_underscore) + + return formatted_response["response"]["items"][0] + + def fetch_right_sizing_recommendations(self, ocean_id: str, filter: azure_ocean.RightSizingFilter): + """ + Get right-sizing recommendations for an Ocean cluster and filter them according to namespace or label. + + # Arguments + ocean_id (String): Ocean Cluster Identifier + filter (RightSizingFilter): RightSizingFilter Object + + # Returns + (Object): Migration create response + """ + request = azure_ocean.FetchRightSizingRequest(filter) + + excluded_missing_dict = self.exclude_missing( + json.loads(request.toJSON())) + + formatted_missing_dict = self.convert_json( + excluded_missing_dict, self.underscore_to_camel) + + body_json = json.dumps(formatted_missing_dict) + + response = self.send_post( + body=body_json, + url=self.__base_ocean_cluster_url + "/" + ocean_id + "/rightSizing/suggestion", + entity_name='ocean_azure_rightsizing') + + formatted_response = self.convert_json(response, + self.camel_to_underscore) + + return formatted_response["response"] + + def get_elastilog(self, ocean_id: str, from_date: str, to_date: str, severity: str = None, resource_id: str = None, + limit: int = None): + """ + Get the log of an Ocean Cluster. + + # Arguments + to_date (String): end date value + from_date (String): beginning date value + severity(String) (Optional): Log level severity + resource_id(String) (Optional): specific resource identifier + limit(int) (Optional): Maximum number of lines to extract in a response + + # Returns + (Object): Ocean Get Log API response + """ + geturl = self.__base_ocean_cluster_url + "/" + ocean_id + "/log" + query_params = dict(toDate=to_date, fromDate=from_date, severity=severity, + resourceId=resource_id, limit=limit) + + result = self.send_get( + url=geturl, entity_name='ocean azure elastilog', query_params=query_params) + + formatted_response = self.convert_json( + result, self.camel_to_underscore) + + return formatted_response["response"]["items"] + + def get_aggregated_detailed_costs(self, ocean_id: str, aggregated_cluster_costs: azure_ocean.AggregatedClusterCosts): + """ + Provides Kubernetes cluster resource usage and costs over a time interval which can be grouped and/or filtered by label/annotaion + + # Arguments + ocean_id (String): ID of the Ocean Cluster + aggregated_cluster_costs (AggregatedClusterCosts): Aggregated Cluster Costs request + + # Returns + (Object): Aggregated Cluster Costs API response + """ + aggregated_cluster_costs_request = azure_ocean.AggregatedClusterCostRequest( + aggregated_cluster_costs) + + excluded_missing_dict = self.exclude_missing( + json.loads(aggregated_cluster_costs_request.toJSON())) + + formatted_missing_dict = self.convert_json_with_list_of_lists( + excluded_missing_dict, self.underscore_to_camel) + + body_json = json.dumps(formatted_missing_dict) + + aggregated_costs_response = self.send_post( + body=body_json, + url=self.__base_ocean_k8s_url + ocean_id + "/aggregatedCosts", + entity_name='ocean (aggregated cluster costs)') + + formatted_response = self.convert_json( + aggregated_costs_response, self.camel_to_underscore) + + return formatted_response["response"]["items"][0] + + def get_aggregated_summary_costs(self, ocean_id: str, aggregated_cluster_costs: azure_ocean.AggregatedClusterCosts): + """ + Provides Kubernetes cluster summary usage and costs over a time interval which can be grouped and/or filtered by label/annotaion + + # Arguments + ocean_id (String): ID of the Ocean Cluster + aggregated_cluster_costs (AggregatedClusterCosts): Aggregated Cluster Costs request + + # Returns + (Object): Aggregated Cluster Costs API response + """ + aggregated_cluster_costs_request = azure_ocean.AggregatedClusterCostRequest( + aggregated_cluster_costs) + + excluded_missing_dict = self.exclude_missing( + json.loads(aggregated_cluster_costs_request.toJSON())) + + formatted_missing_dict = self.convert_json_with_list_of_lists( + excluded_missing_dict, self.underscore_to_camel) + + body_json = json.dumps(formatted_missing_dict) + + aggregated_summary_costs_response = self.send_post( + body=body_json, + url=self.__base_ocean_k8s_url + + ocean_id + "/aggregatedCosts/summary", + entity_name='ocean (aggregated summary costs)') + + formatted_response = self.convert_json( + aggregated_summary_costs_response, self.camel_to_underscore) + + return formatted_response["response"]["items"][0] # endregion + + class OceanGcpClient(Client): __base_ocean_url = "/ocean/k8s/cluster/" __base_ocean_cluster_url = "/ocean/gcp/k8s/cluster" diff --git a/spotinst_sdk2/models/ocean/azure/__init__.py b/spotinst_sdk2/models/ocean/azure/__init__.py index f9382ae9..bc78f107 100644 --- a/spotinst_sdk2/models/ocean/azure/__init__.py +++ b/spotinst_sdk2/models/ocean/azure/__init__.py @@ -893,3 +893,48 @@ def toJSON(self): return json.dumps(self, default=lambda o: o.__dict__, sort_keys=True, indent=4) # endregion + + +class DetachNodes: + """ + # Arguments + node_names_to_detach: List[str] + ocean_id: str + """ + def __init__(self, + node_names_to_detach: List[str] = none, + ocean_id: str = none): + self.node_names_to_detach = node_names_to_detach + self.ocean_id = ocean_id + + +class DetachNodesRequest: + def __init__(self, detachNodes: DetachNodes): + self.node_names_to_detach = detachNodes.node_names_to_detach + self.ocean_id = detachNodes.ocean_id + + def toJSON(self): + return json.dumps(self, default=lambda o: o.__dict__, + sort_keys=True, indent=4) + + +class RightSizingFilter: + """ + # Arguments + attribute: Attribute + namespaces: List[str] + """ + def __init__(self, + attribute: Attribute = none, + namespaces: List[str] = none): + self.attribute = attribute + self.namespaces = namespaces + + +class FetchRightSizingRequest: + def __init__(self, filter: RightSizingFilter): + self.filter = filter + + def toJSON(self): + return json.dumps(self, default=lambda o: o.__dict__, + sort_keys=True, indent=4) \ No newline at end of file From 0bac435822dead6bf85710f5a1634ec91525b933 Mon Sep 17 00:00:00 2001 From: Amrutha Ramanathan <105342664+ramrutha497@users.noreply.github.com> Date: Fri, 21 Jun 2024 12:35:16 +0530 Subject: [PATCH 2/3] update changes --- spotinst_sdk2/clients/ocean/__init__.py | 31 -------------------- spotinst_sdk2/models/ocean/azure/__init__.py | 22 -------------- 2 files changed, 53 deletions(-) diff --git a/spotinst_sdk2/clients/ocean/__init__.py b/spotinst_sdk2/clients/ocean/__init__.py index 856a5f70..05894e0a 100644 --- a/spotinst_sdk2/clients/ocean/__init__.py +++ b/spotinst_sdk2/clients/ocean/__init__.py @@ -1725,37 +1725,6 @@ def detach_instances(self, ocean_id: str, detach_nodes: azure_ocean.DetachNodes) return formatted_response["response"]["items"][0] - def fetch_right_sizing_recommendations(self, ocean_id: str, filter: azure_ocean.RightSizingFilter): - """ - Get right-sizing recommendations for an Ocean cluster and filter them according to namespace or label. - - # Arguments - ocean_id (String): Ocean Cluster Identifier - filter (RightSizingFilter): RightSizingFilter Object - - # Returns - (Object): Migration create response - """ - request = azure_ocean.FetchRightSizingRequest(filter) - - excluded_missing_dict = self.exclude_missing( - json.loads(request.toJSON())) - - formatted_missing_dict = self.convert_json( - excluded_missing_dict, self.underscore_to_camel) - - body_json = json.dumps(formatted_missing_dict) - - response = self.send_post( - body=body_json, - url=self.__base_ocean_cluster_url + "/" + ocean_id + "/rightSizing/suggestion", - entity_name='ocean_azure_rightsizing') - - formatted_response = self.convert_json(response, - self.camel_to_underscore) - - return formatted_response["response"] - def get_elastilog(self, ocean_id: str, from_date: str, to_date: str, severity: str = None, resource_id: str = None, limit: int = None): """ diff --git a/spotinst_sdk2/models/ocean/azure/__init__.py b/spotinst_sdk2/models/ocean/azure/__init__.py index bc78f107..d6fa3621 100644 --- a/spotinst_sdk2/models/ocean/azure/__init__.py +++ b/spotinst_sdk2/models/ocean/azure/__init__.py @@ -916,25 +916,3 @@ def __init__(self, detachNodes: DetachNodes): def toJSON(self): return json.dumps(self, default=lambda o: o.__dict__, sort_keys=True, indent=4) - - -class RightSizingFilter: - """ - # Arguments - attribute: Attribute - namespaces: List[str] - """ - def __init__(self, - attribute: Attribute = none, - namespaces: List[str] = none): - self.attribute = attribute - self.namespaces = namespaces - - -class FetchRightSizingRequest: - def __init__(self, filter: RightSizingFilter): - self.filter = filter - - def toJSON(self): - return json.dumps(self, default=lambda o: o.__dict__, - sort_keys=True, indent=4) \ No newline at end of file From d6091387e106fceaa6568c1cd0ade8e787106b36 Mon Sep 17 00:00:00 2001 From: Anurag Sharma Date: Fri, 21 Jun 2024 14:24:03 +0530 Subject: [PATCH 3/3] Documentation update --- CHANGELOG.md | 4 + docs/clients/ocean/ocean_azure_client.md | 77 ++++++++++++++++++++ docs/models/ocean/azure.md | 14 ++++ spotinst_sdk2/clients/ocean/__init__.py | 10 +-- spotinst_sdk2/models/ocean/azure/__init__.py | 7 +- spotinst_sdk2/version.py | 2 +- 6 files changed, 104 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 953c8627..f04db4d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## [3.8.0] - 2024-06-21 +### Added +- Added detach nodes, get elastilog and cost APIs for Ocean AKS. + ## [3.7.1] - 2024-06-17 ### Fixed - Fixed `AggressiveScaleDown` model in GCP Ocean. diff --git a/docs/clients/ocean/ocean_azure_client.md b/docs/clients/ocean/ocean_azure_client.md index fd3db039..067720d8 100644 --- a/docs/clients/ocean/ocean_azure_client.md +++ b/docs/clients/ocean/ocean_azure_client.md @@ -377,3 +377,80 @@ __Returns__ `(Object)`: Ocean Migrations response +

detach_nodes

+ +```python +OceanAzureClient.detach_nodes(detach_nodes: DetachNodes) +``` + +Detach nodes from your Ocean cluster. + +__Arguments__ + +- __detach_nodes (DetachNodes)__: Detach Nodes Object + +__Returns__ + +`(Object)`: Detach Nodes response + +

get_elastilog

+ +```python +OceanAzureClient.get_elastilog(ocean_id: str, + from_date: str, + to_date: str, + severity: str = None, + resource_id: str = None, + limit: int = None) +``` + +Get the log of an Ocean Cluster. + +__Arguments__ + +- __to_date (String)__: end date value +- __from_date (String)__: beginning date value +- __severity(String) (Optional)__: Log level severity +- __resource_id(String) (Optional)__: specific resource identifier +- __limit(int) (Optional)__: Maximum number of lines to extract in a response + +__Returns__ + +`(Object)`: Ocean Get Log API response + +

get_aggregated_detailed_costs

+ +```python +OceanAzureClient.get_aggregated_detailed_costs( + ocean_id: str, aggregated_cluster_costs: AggregatedClusterCosts) +``` + +Provides Kubernetes cluster resource usage and costs over a time interval which can be grouped and/or filtered by label/annotaion + +__Arguments__ + +- __ocean_id (String)__: ID of the Ocean Cluster +- __aggregated_cluster_costs (AggregatedClusterCosts)__: Aggregated Cluster Costs request + +__Returns__ + +`(Object)`: Aggregated Cluster Costs API response + +

get_aggregated_summary_costs

+ +```python +OceanAzureClient.get_aggregated_summary_costs( + ocean_id: str, aggregated_cluster_costs: AggregatedClusterCosts) +``` + +Provides Kubernetes cluster summary usage and costs over a time interval which can be grouped and/or filtered by label/annotaion + +__Arguments__ + +- __ocean_id (String)__: ID of the Ocean Cluster +- __aggregated_cluster_costs (AggregatedClusterCosts)__: Aggregated Cluster Costs request + +__Returns__ + +`(Object)`: Aggregated Cluster Costs API response + diff --git a/docs/models/ocean/azure.md b/docs/models/ocean/azure.md index 89a9e81e..d50fcf3e 100644 --- a/docs/models/ocean/azure.md +++ b/docs/models/ocean/azure.md @@ -844,3 +844,17 @@ __Arguments__ - __should_evict_standalone_pods__: bool - __should_terminate_nodes__: bool +

DetachNodes

+ +```python +DetachNodes(self, + node_names_to_detach: + typing.List[str] = 'd3043820717d74d9a17694c176d39733', + ocean_id: str = 'd3043820717d74d9a17694c176d39733') +``` + +__Arguments__ + +- __node_names_to_detach__: List[str] +- __ocean_id__: str + diff --git a/spotinst_sdk2/clients/ocean/__init__.py b/spotinst_sdk2/clients/ocean/__init__.py index 05894e0a..440da79b 100644 --- a/spotinst_sdk2/clients/ocean/__init__.py +++ b/spotinst_sdk2/clients/ocean/__init__.py @@ -1695,12 +1695,12 @@ def list_migrations(self, ocean_id: str): return formatted_response["response"] - def detach_instances(self, ocean_id: str, detach_nodes: azure_ocean.DetachNodes): + def detach_nodes(self, detach_nodes: azure_ocean.DetachNodes): """ - Detach instances from your Ocean cluster. + Detach nodes from your Ocean cluster. # Arguments - detach_instance (DetachNodes): Detach Nodes Object + detach_nodes (DetachNodes): Detach Nodes Object # Returns (Object): Detach Nodes response @@ -1809,7 +1809,7 @@ def get_aggregated_summary_costs(self, ocean_id: str, aggregated_cluster_costs: aggregated_summary_costs_response = self.send_post( body=body_json, url=self.__base_ocean_k8s_url + - ocean_id + "/aggregatedCosts/summary", + ocean_id + "/aggregatedCosts/summary", entity_name='ocean (aggregated summary costs)') formatted_response = self.convert_json( @@ -1819,8 +1819,6 @@ def get_aggregated_summary_costs(self, ocean_id: str, aggregated_cluster_costs: # endregion - - class OceanGcpClient(Client): __base_ocean_url = "/ocean/k8s/cluster/" __base_ocean_cluster_url = "/ocean/gcp/k8s/cluster" diff --git a/spotinst_sdk2/models/ocean/azure/__init__.py b/spotinst_sdk2/models/ocean/azure/__init__.py index d6fa3621..ba39b6f7 100644 --- a/spotinst_sdk2/models/ocean/azure/__init__.py +++ b/spotinst_sdk2/models/ocean/azure/__init__.py @@ -901,6 +901,7 @@ class DetachNodes: node_names_to_detach: List[str] ocean_id: str """ + def __init__(self, node_names_to_detach: List[str] = none, ocean_id: str = none): @@ -909,9 +910,9 @@ def __init__(self, class DetachNodesRequest: - def __init__(self, detachNodes: DetachNodes): - self.node_names_to_detach = detachNodes.node_names_to_detach - self.ocean_id = detachNodes.ocean_id + def __init__(self, detach_nodes_obj: DetachNodes): + self.node_names_to_detach = detach_nodes_obj.node_names_to_detach + self.ocean_id = detach_nodes_obj.ocean_id def toJSON(self): return json.dumps(self, default=lambda o: o.__dict__, diff --git a/spotinst_sdk2/version.py b/spotinst_sdk2/version.py index 380cd80a..99d6aece 100644 --- a/spotinst_sdk2/version.py +++ b/spotinst_sdk2/version.py @@ -1 +1 @@ -__version__ = '3.7.1' +__version__ = '3.8.0'