diff --git a/.openapi-generator/FILES b/.openapi-generator/FILES index 21f1d20..b5145ef 100644 --- a/.openapi-generator/FILES +++ b/.openapi-generator/FILES @@ -16,6 +16,7 @@ docs/ClusterLayout.md docs/CreateBucketRequest.md docs/CreateBucketRequestLocalAlias.md docs/CreateBucketRequestLocalAliasAllow.md +docs/GetHealth200Response.md docs/GetNodes200Response.md docs/ImportKeyRequest.md docs/KeyApi.md @@ -64,6 +65,7 @@ garage_admin_sdk/model/cluster_layout.py garage_admin_sdk/model/create_bucket_request.py garage_admin_sdk/model/create_bucket_request_local_alias.py garage_admin_sdk/model/create_bucket_request_local_alias_allow.py +garage_admin_sdk/model/get_health200_response.py garage_admin_sdk/model/get_nodes200_response.py garage_admin_sdk/model/import_key_request.py garage_admin_sdk/model/key_info.py @@ -94,4 +96,5 @@ setup.cfg setup.py test-requirements.txt test/__init__.py +test/test_get_health200_response.py tox.ini diff --git a/README.md b/README.md index 7c32fbc..3e46be3 100644 --- a/README.md +++ b/README.md @@ -124,8 +124,9 @@ Class | Method | HTTP request | Description *LayoutApi* | [**apply_layout**](docs/LayoutApi.md#apply_layout) | **POST** /layout/apply | Apply staged layout *LayoutApi* | [**get_layout**](docs/LayoutApi.md#get_layout) | **GET** /layout | Details on the current and staged layout *LayoutApi* | [**revert_layout**](docs/LayoutApi.md#revert_layout) | **POST** /layout/revert | Clear staged layout -*NodesApi* | [**add_node**](docs/NodesApi.md#add_node) | **POST** /connect | Connect target node to other Garage nodes -*NodesApi* | [**get_nodes**](docs/NodesApi.md#get_nodes) | **GET** /status | Status of this node and other nodes in the cluster +*NodesApi* | [**add_node**](docs/NodesApi.md#add_node) | **POST** /connect | Connect a new node +*NodesApi* | [**get_health**](docs/NodesApi.md#get_health) | **GET** /health | Cluster health report +*NodesApi* | [**get_nodes**](docs/NodesApi.md#get_nodes) | **GET** /status | Describe cluster ## Documentation For Models @@ -143,6 +144,7 @@ Class | Method | HTTP request | Description - [CreateBucketRequest](docs/CreateBucketRequest.md) - [CreateBucketRequestLocalAlias](docs/CreateBucketRequestLocalAlias.md) - [CreateBucketRequestLocalAliasAllow](docs/CreateBucketRequestLocalAliasAllow.md) + - [GetHealth200Response](docs/GetHealth200Response.md) - [GetNodes200Response](docs/GetNodes200Response.md) - [ImportKeyRequest](docs/ImportKeyRequest.md) - [KeyInfo](docs/KeyInfo.md) diff --git a/docs/GetHealth200Response.md b/docs/GetHealth200Response.md new file mode 100644 index 0000000..f93f6da --- /dev/null +++ b/docs/GetHealth200Response.md @@ -0,0 +1,19 @@ +# GetHealth200Response + + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**status** | **str** | | +**known_nodes** | **int** | | +**connected_nodes** | **int** | | +**storage_nodes** | **int** | | +**storage_nodes_ok** | **int** | | +**partitions** | **int** | | +**partitions_quorum** | **int** | | +**partitions_all_ok** | **int** | | +**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/docs/NodesApi.md b/docs/NodesApi.md index 703dd05..d1e4884 100644 --- a/docs/NodesApi.md +++ b/docs/NodesApi.md @@ -4,14 +4,15 @@ All URIs are relative to *http://localhost:3903/v1* Method | HTTP request | Description ------------- | ------------- | ------------- -[**add_node**](NodesApi.md#add_node) | **POST** /connect | Connect target node to other Garage nodes -[**get_nodes**](NodesApi.md#get_nodes) | **GET** /status | Status of this node and other nodes in the cluster +[**add_node**](NodesApi.md#add_node) | **POST** /connect | Connect a new node +[**get_health**](NodesApi.md#get_health) | **GET** /health | Cluster health report +[**get_nodes**](NodesApi.md#get_nodes) | **GET** /status | Describe cluster # **add_node** > [AddNode200ResponseInner] add_node(request_body) -Connect target node to other Garage nodes +Connect a new node Instructs this Garage node to connect to other Garage nodes at specified `@`. `node_id` is generated automatically on node start. @@ -49,7 +50,7 @@ with garage_admin_sdk.ApiClient(configuration) as api_client: # example passing only required values which don't have defaults set try: - # Connect target node to other Garage nodes + # Connect a new node api_response = api_instance.add_node(request_body) pprint(api_response) except garage_admin_sdk.ApiException as e: @@ -87,10 +88,84 @@ Name | Type | Description | Notes [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) +# **get_health** +> GetHealth200Response get_health() + +Cluster health report + +Returns the global status of the cluster, the number of connected nodes (over the number of known ones), the number of healthy storage nodes (over the declared ones), and the number of healthy partitions (over the total). + +### Example + +* Bearer Authentication (bearerAuth): + +```python +import time +import garage_admin_sdk +from garage_admin_sdk.api import nodes_api +from garage_admin_sdk.model.get_health200_response import GetHealth200Response +from pprint import pprint +# Defining the host is optional and defaults to http://localhost:3903/v1 +# See configuration.py for a list of all supported configuration parameters. +configuration = garage_admin_sdk.Configuration( + host = "http://localhost:3903/v1" +) + +# The client must configure the authentication and authorization parameters +# in accordance with the API server security policy. +# Examples for each auth method are provided below, use the example that +# satisfies your auth use case. + +# Configure Bearer authorization: bearerAuth +configuration = garage_admin_sdk.Configuration( + access_token = 'YOUR_BEARER_TOKEN' +) + +# Enter a context with an instance of the API client +with garage_admin_sdk.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = nodes_api.NodesApi(api_client) + + # example, this endpoint has no required or optional parameters + try: + # Cluster health report + api_response = api_instance.get_health() + pprint(api_response) + except garage_admin_sdk.ApiException as e: + print("Exception when calling NodesApi->get_health: %s\n" % e) +``` + + +### Parameters +This endpoint does not need any parameter. + +### Return type + +[**GetHealth200Response**](GetHealth200Response.md) + +### Authorization + +[bearerAuth](../README.md#bearerAuth) + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**500** | The server can not answer your request because it is in a bad state | - | +**200** | Information about the queried node, its environment and the current layout | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + # **get_nodes** > GetNodes200Response get_nodes() -Status of this node and other nodes in the cluster +Describe cluster Returns the cluster's current status, including: - ID of the node being queried and its version of the Garage daemon - Live nodes - Currently configured cluster layout - Staged changes to the cluster layout *Capacity is given in bytes* @@ -127,7 +202,7 @@ with garage_admin_sdk.ApiClient(configuration) as api_client: # example, this endpoint has no required or optional parameters try: - # Status of this node and other nodes in the cluster + # Describe cluster api_response = api_instance.get_nodes() pprint(api_response) except garage_admin_sdk.ApiException as e: diff --git a/garage_admin_sdk/api/nodes_api.py b/garage_admin_sdk/api/nodes_api.py index 98bcd3a..b6aad98 100644 --- a/garage_admin_sdk/api/nodes_api.py +++ b/garage_admin_sdk/api/nodes_api.py @@ -22,6 +22,7 @@ from garage_admin_sdk.model_utils import ( # noqa: F401 validate_and_convert_types ) from garage_admin_sdk.model.add_node200_response_inner import AddNode200ResponseInner +from garage_admin_sdk.model.get_health200_response import GetHealth200Response from garage_admin_sdk.model.get_nodes200_response import GetNodes200Response @@ -88,6 +89,50 @@ class NodesApi(object): }, api_client=api_client ) + self.get_health_endpoint = _Endpoint( + settings={ + 'response_type': (GetHealth200Response,), + 'auth': [ + 'bearerAuth' + ], + 'endpoint_path': '/health', + 'operation_id': 'get_health', + 'http_method': 'GET', + 'servers': None, + }, + params_map={ + 'all': [ + ], + 'required': [], + 'nullable': [ + ], + 'enum': [ + ], + 'validation': [ + ] + }, + root_map={ + 'validations': { + }, + 'allowed_values': { + }, + 'openapi_types': { + }, + 'attribute_map': { + }, + 'location_map': { + }, + 'collection_format_map': { + } + }, + headers_map={ + 'accept': [ + 'application/json' + ], + 'content_type': [], + }, + api_client=api_client + ) self.get_nodes_endpoint = _Endpoint( settings={ 'response_type': (GetNodes200Response,), @@ -138,7 +183,7 @@ class NodesApi(object): request_body, **kwargs ): - """Connect target node to other Garage nodes # noqa: E501 + """Connect a new node # noqa: E501 Instructs this Garage node to connect to other Garage nodes at specified `@`. `node_id` is generated automatically on node start. # noqa: E501 This method makes a synchronous HTTP request by default. To make an @@ -216,11 +261,89 @@ class NodesApi(object): request_body return self.add_node_endpoint.call_with_http_info(**kwargs) + def get_health( + self, + **kwargs + ): + """Cluster health report # noqa: E501 + + Returns the global status of the cluster, the number of connected nodes (over the number of known ones), the number of healthy storage nodes (over the declared ones), and the number of healthy partitions (over the total). # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.get_health(async_req=True) + >>> result = thread.get() + + + Keyword Args: + _return_http_data_only (bool): response data without head status + code and headers. Default is True. + _preload_content (bool): if False, the urllib3.HTTPResponse object + will be returned without reading/decoding response data. + Default is True. + _request_timeout (int/float/tuple): timeout setting for this request. If + one number provided, it will be total request timeout. It can also + be a pair (tuple) of (connection, read) timeouts. + Default is None. + _check_input_type (bool): specifies if type checking + should be done one the data sent to the server. + Default is True. + _check_return_type (bool): specifies if type checking + should be done one the data received from the server. + Default is True. + _spec_property_naming (bool): True if the variable names in the input data + are serialized names, as specified in the OpenAPI document. + False if the variable names in the input data + are pythonic names, e.g. snake case (default) + _content_type (str/None): force body content-type. + Default is None and content-type will be predicted by allowed + content-types and body. + _host_index (int/None): specifies the index of the server + that we want to use. + Default is read from the configuration. + _request_auths (list): set to override the auth_settings for an a single + request; this effectively ignores the authentication + in the spec for a single request. + Default is None + async_req (bool): execute request asynchronously + + Returns: + GetHealth200Response + If the method is called asynchronously, returns the request + thread. + """ + kwargs['async_req'] = kwargs.get( + 'async_req', False + ) + kwargs['_return_http_data_only'] = kwargs.get( + '_return_http_data_only', True + ) + kwargs['_preload_content'] = kwargs.get( + '_preload_content', True + ) + kwargs['_request_timeout'] = kwargs.get( + '_request_timeout', None + ) + kwargs['_check_input_type'] = kwargs.get( + '_check_input_type', True + ) + kwargs['_check_return_type'] = kwargs.get( + '_check_return_type', True + ) + kwargs['_spec_property_naming'] = kwargs.get( + '_spec_property_naming', False + ) + kwargs['_content_type'] = kwargs.get( + '_content_type') + kwargs['_host_index'] = kwargs.get('_host_index') + kwargs['_request_auths'] = kwargs.get('_request_auths', None) + return self.get_health_endpoint.call_with_http_info(**kwargs) + def get_nodes( self, **kwargs ): - """Status of this node and other nodes in the cluster # noqa: E501 + """Describe cluster # noqa: E501 Returns the cluster's current status, including: - ID of the node being queried and its version of the Garage daemon - Live nodes - Currently configured cluster layout - Staged changes to the cluster layout *Capacity is given in bytes* # noqa: E501 This method makes a synchronous HTTP request by default. To make an diff --git a/garage_admin_sdk/model/get_health200_response.py b/garage_admin_sdk/model/get_health200_response.py new file mode 100644 index 0000000..88d1b53 --- /dev/null +++ b/garage_admin_sdk/model/get_health200_response.py @@ -0,0 +1,311 @@ +""" + Garage Administration API v0+garage-v0.9.0 + + Administrate your Garage cluster programatically, including status, layout, keys, buckets, and maintainance tasks. *Disclaimer: The API is not stable yet, hence its v0 tag. The API can change at any time, and changes can include breaking backward compatibility. Read the changelog and upgrade your scripts before upgrading. Additionnaly, this specification is very early stage and can contain bugs, especially on error return codes/types that are not tested yet. Do not expect a well finished and polished product!* # noqa: E501 + + The version of the OpenAPI document: v0.9.0 + Generated by: https://openapi-generator.tech +""" + + +import re # noqa: F401 +import sys # noqa: F401 + +from garage_admin_sdk.model_utils import ( # noqa: F401 + ApiTypeError, + ModelComposed, + ModelNormal, + ModelSimple, + cached_property, + change_keys_js_to_python, + convert_js_args_to_python_args, + date, + datetime, + file_type, + none_type, + validate_get_composed_info, + OpenApiModel +) +from garage_admin_sdk.exceptions import ApiAttributeError + + + +class GetHealth200Response(ModelNormal): + """NOTE: This class is auto generated by OpenAPI Generator. + Ref: https://openapi-generator.tech + + Do not edit the class manually. + + Attributes: + allowed_values (dict): The key is the tuple path to the attribute + and the for var_name this is (var_name,). The value is a dict + with a capitalized key describing the allowed value and an allowed + value. These dicts store the allowed enum values. + attribute_map (dict): The key is attribute name + and the value is json key in definition. + discriminator_value_class_map (dict): A dict to go from the discriminator + variable value to the discriminator class name. + validations (dict): The key is the tuple path to the attribute + and the for var_name this is (var_name,). The value is a dict + that stores validations for max_length, min_length, max_items, + min_items, exclusive_maximum, inclusive_maximum, exclusive_minimum, + inclusive_minimum, and regex. + additional_properties_type (tuple): A tuple of classes accepted + as additional properties values. + """ + + allowed_values = { + } + + validations = { + } + + @cached_property + def additional_properties_type(): + """ + This must be a method because a model may have properties that are + of type self, this must run after the class is loaded + """ + return (bool, date, datetime, dict, float, int, list, str, none_type,) # noqa: E501 + + _nullable = False + + @cached_property + def openapi_types(): + """ + This must be a method because a model may have properties that are + of type self, this must run after the class is loaded + + Returns + openapi_types (dict): The key is attribute name + and the value is attribute type. + """ + return { + 'status': (str,), # noqa: E501 + 'known_nodes': (int,), # noqa: E501 + 'connected_nodes': (int,), # noqa: E501 + 'storage_nodes': (int,), # noqa: E501 + 'storage_nodes_ok': (int,), # noqa: E501 + 'partitions': (int,), # noqa: E501 + 'partitions_quorum': (int,), # noqa: E501 + 'partitions_all_ok': (int,), # noqa: E501 + } + + @cached_property + def discriminator(): + return None + + + attribute_map = { + 'status': 'status', # noqa: E501 + 'known_nodes': 'knownNodes', # noqa: E501 + 'connected_nodes': 'connectedNodes', # noqa: E501 + 'storage_nodes': 'storageNodes', # noqa: E501 + 'storage_nodes_ok': 'storageNodesOk', # noqa: E501 + 'partitions': 'partitions', # noqa: E501 + 'partitions_quorum': 'partitionsQuorum', # noqa: E501 + 'partitions_all_ok': 'partitionsAllOk', # noqa: E501 + } + + read_only_vars = { + } + + _composed_schemas = {} + + @classmethod + @convert_js_args_to_python_args + def _from_openapi_data(cls, status, known_nodes, connected_nodes, storage_nodes, storage_nodes_ok, partitions, partitions_quorum, partitions_all_ok, *args, **kwargs): # noqa: E501 + """GetHealth200Response - a model defined in OpenAPI + + Args: + status (str): + known_nodes (int): + connected_nodes (int): + storage_nodes (int): + storage_nodes_ok (int): + partitions (int): + partitions_quorum (int): + partitions_all_ok (int): + + Keyword Args: + _check_type (bool): if True, values for parameters in openapi_types + will be type checked and a TypeError will be + raised if the wrong type is input. + Defaults to True + _path_to_item (tuple/list): This is a list of keys or values to + drill down to the model in received_data + when deserializing a response + _spec_property_naming (bool): True if the variable names in the input data + are serialized names, as specified in the OpenAPI document. + False if the variable names in the input data + are pythonic names, e.g. snake case (default) + _configuration (Configuration): the instance to use when + deserializing a file_type parameter. + If passed, type conversion is attempted + If omitted no type conversion is done. + _visited_composed_classes (tuple): This stores a tuple of + classes that we have traveled through so that + if we see that class again we will not use its + discriminator again. + When traveling through a discriminator, the + composed schema that is + is traveled through is added to this set. + For example if Animal has a discriminator + petType and we pass in "Dog", and the class Dog + allOf includes Animal, we move through Animal + once using the discriminator, and pick Dog. + Then in Dog, we will make an instance of the + Animal class but this time we won't travel + through its discriminator because we passed in + _visited_composed_classes = (Animal,) + """ + + _check_type = kwargs.pop('_check_type', True) + _spec_property_naming = kwargs.pop('_spec_property_naming', True) + _path_to_item = kwargs.pop('_path_to_item', ()) + _configuration = kwargs.pop('_configuration', None) + _visited_composed_classes = kwargs.pop('_visited_composed_classes', ()) + + self = super(OpenApiModel, cls).__new__(cls) + + if args: + for arg in args: + if isinstance(arg, dict): + kwargs.update(arg) + else: + raise ApiTypeError( + "Invalid positional arguments=%s passed to %s. Remove those invalid positional arguments." % ( + args, + self.__class__.__name__, + ), + path_to_item=_path_to_item, + valid_classes=(self.__class__,), + ) + + self._data_store = {} + self._check_type = _check_type + self._spec_property_naming = _spec_property_naming + self._path_to_item = _path_to_item + self._configuration = _configuration + self._visited_composed_classes = _visited_composed_classes + (self.__class__,) + + self.status = status + self.known_nodes = known_nodes + self.connected_nodes = connected_nodes + self.storage_nodes = storage_nodes + self.storage_nodes_ok = storage_nodes_ok + self.partitions = partitions + self.partitions_quorum = partitions_quorum + self.partitions_all_ok = partitions_all_ok + for var_name, var_value in kwargs.items(): + if var_name not in self.attribute_map and \ + self._configuration is not None and \ + self._configuration.discard_unknown_keys and \ + self.additional_properties_type is None: + # discard variable. + continue + setattr(self, var_name, var_value) + return self + + required_properties = set([ + '_data_store', + '_check_type', + '_spec_property_naming', + '_path_to_item', + '_configuration', + '_visited_composed_classes', + ]) + + @convert_js_args_to_python_args + def __init__(self, status, known_nodes, connected_nodes, storage_nodes, storage_nodes_ok, partitions, partitions_quorum, partitions_all_ok, *args, **kwargs): # noqa: E501 + """GetHealth200Response - a model defined in OpenAPI + + Args: + status (str): + known_nodes (int): + connected_nodes (int): + storage_nodes (int): + storage_nodes_ok (int): + partitions (int): + partitions_quorum (int): + partitions_all_ok (int): + + Keyword Args: + _check_type (bool): if True, values for parameters in openapi_types + will be type checked and a TypeError will be + raised if the wrong type is input. + Defaults to True + _path_to_item (tuple/list): This is a list of keys or values to + drill down to the model in received_data + when deserializing a response + _spec_property_naming (bool): True if the variable names in the input data + are serialized names, as specified in the OpenAPI document. + False if the variable names in the input data + are pythonic names, e.g. snake case (default) + _configuration (Configuration): the instance to use when + deserializing a file_type parameter. + If passed, type conversion is attempted + If omitted no type conversion is done. + _visited_composed_classes (tuple): This stores a tuple of + classes that we have traveled through so that + if we see that class again we will not use its + discriminator again. + When traveling through a discriminator, the + composed schema that is + is traveled through is added to this set. + For example if Animal has a discriminator + petType and we pass in "Dog", and the class Dog + allOf includes Animal, we move through Animal + once using the discriminator, and pick Dog. + Then in Dog, we will make an instance of the + Animal class but this time we won't travel + through its discriminator because we passed in + _visited_composed_classes = (Animal,) + """ + + _check_type = kwargs.pop('_check_type', True) + _spec_property_naming = kwargs.pop('_spec_property_naming', False) + _path_to_item = kwargs.pop('_path_to_item', ()) + _configuration = kwargs.pop('_configuration', None) + _visited_composed_classes = kwargs.pop('_visited_composed_classes', ()) + + if args: + for arg in args: + if isinstance(arg, dict): + kwargs.update(arg) + else: + raise ApiTypeError( + "Invalid positional arguments=%s passed to %s. Remove those invalid positional arguments." % ( + args, + self.__class__.__name__, + ), + path_to_item=_path_to_item, + valid_classes=(self.__class__,), + ) + + self._data_store = {} + self._check_type = _check_type + self._spec_property_naming = _spec_property_naming + self._path_to_item = _path_to_item + self._configuration = _configuration + self._visited_composed_classes = _visited_composed_classes + (self.__class__,) + + self.status = status + self.known_nodes = known_nodes + self.connected_nodes = connected_nodes + self.storage_nodes = storage_nodes + self.storage_nodes_ok = storage_nodes_ok + self.partitions = partitions + self.partitions_quorum = partitions_quorum + self.partitions_all_ok = partitions_all_ok + for var_name, var_value in kwargs.items(): + if var_name not in self.attribute_map and \ + self._configuration is not None and \ + self._configuration.discard_unknown_keys and \ + self.additional_properties_type is None: + # discard variable. + continue + setattr(self, var_name, var_value) + if var_name in self.read_only_vars: + raise ApiAttributeError(f"`{var_name}` is a read-only attribute. Use `from_openapi_data` to instantiate " + f"class with read only attributes.") diff --git a/garage_admin_sdk/models/__init__.py b/garage_admin_sdk/models/__init__.py index 465e6d9..d8682b3 100644 --- a/garage_admin_sdk/models/__init__.py +++ b/garage_admin_sdk/models/__init__.py @@ -22,6 +22,7 @@ from garage_admin_sdk.model.cluster_layout import ClusterLayout from garage_admin_sdk.model.create_bucket_request import CreateBucketRequest from garage_admin_sdk.model.create_bucket_request_local_alias import CreateBucketRequestLocalAlias from garage_admin_sdk.model.create_bucket_request_local_alias_allow import CreateBucketRequestLocalAliasAllow +from garage_admin_sdk.model.get_health200_response import GetHealth200Response from garage_admin_sdk.model.get_nodes200_response import GetNodes200Response from garage_admin_sdk.model.import_key_request import ImportKeyRequest from garage_admin_sdk.model.key_info import KeyInfo diff --git a/test/test_get_health200_response.py b/test/test_get_health200_response.py new file mode 100644 index 0000000..87357f0 --- /dev/null +++ b/test/test_get_health200_response.py @@ -0,0 +1,35 @@ +""" + Garage Administration API v0+garage-v0.9.0 + + Administrate your Garage cluster programatically, including status, layout, keys, buckets, and maintainance tasks. *Disclaimer: The API is not stable yet, hence its v0 tag. The API can change at any time, and changes can include breaking backward compatibility. Read the changelog and upgrade your scripts before upgrading. Additionnaly, this specification is very early stage and can contain bugs, especially on error return codes/types that are not tested yet. Do not expect a well finished and polished product!* # noqa: E501 + + The version of the OpenAPI document: v0.9.0 + Generated by: https://openapi-generator.tech +""" + + +import sys +import unittest + +import garage_admin_sdk +from garage_admin_sdk.model.get_health200_response import GetHealth200Response + + +class TestGetHealth200Response(unittest.TestCase): + """GetHealth200Response unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def testGetHealth200Response(self): + """Test GetHealth200Response""" + # FIXME: construct object with mandatory attributes with example values + # model = GetHealth200Response() # noqa: E501 + pass + + +if __name__ == '__main__': + unittest.main()