diff --git a/addon/flamenco/manager/__init__.py b/addon/flamenco/manager/__init__.py index bd86aa21..f717af80 100644 --- a/addon/flamenco/manager/__init__.py +++ b/addon/flamenco/manager/__init__.py @@ -10,7 +10,7 @@ """ -__version__ = "186dd064" +__version__ = "f2438a89" # import ApiClient from flamenco.manager.api_client import ApiClient diff --git a/addon/flamenco/manager/api/meta_api.py b/addon/flamenco/manager/api/meta_api.py index 2adb0883..802ffe28 100644 --- a/addon/flamenco/manager/api/meta_api.py +++ b/addon/flamenco/manager/api/meta_api.py @@ -30,6 +30,7 @@ from flamenco.manager.model.manager_variable_audience import ManagerVariableAudi from flamenco.manager.model.manager_variables import ManagerVariables from flamenco.manager.model.path_check_input import PathCheckInput from flamenco.manager.model.path_check_result import PathCheckResult +from flamenco.manager.model.wizard_config import WizardConfig class MetaApi(object): @@ -363,6 +364,54 @@ class MetaApi(object): }, api_client=api_client ) + self.save_wizard_config_endpoint = _Endpoint( + settings={ + 'response_type': None, + 'auth': [], + 'endpoint_path': '/api/v3/configuration/wizard', + 'operation_id': 'save_wizard_config', + 'http_method': 'POST', + 'servers': None, + }, + params_map={ + 'all': [ + 'wizard_config', + ], + 'required': [], + 'nullable': [ + ], + 'enum': [ + ], + 'validation': [ + ] + }, + root_map={ + 'validations': { + }, + 'allowed_values': { + }, + 'openapi_types': { + 'wizard_config': + (WizardConfig,), + }, + 'attribute_map': { + }, + 'location_map': { + 'wizard_config': 'body', + }, + 'collection_format_map': { + } + }, + headers_map={ + 'accept': [ + 'application/json' + ], + 'content_type': [ + 'application/json' + ] + }, + api_client=api_client + ) def check_blender_exe_path( self, @@ -879,3 +928,76 @@ class MetaApi(object): kwargs['_host_index'] = kwargs.get('_host_index') return self.get_version_endpoint.call_with_http_info(**kwargs) + def save_wizard_config( + self, + **kwargs + ): + """Update the Manager's configuration, and restart it in fully functional mode. # noqa: E501 + + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.save_wizard_config(async_req=True) + >>> result = thread.get() + + + Keyword Args: + wizard_config (WizardConfig): Configuration to save.. [optional] + _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. + async_req (bool): execute request asynchronously + + Returns: + None + 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') + return self.save_wizard_config_endpoint.call_with_http_info(**kwargs) + diff --git a/addon/flamenco/manager/api_client.py b/addon/flamenco/manager/api_client.py index 4ef81c4f..af3f2136 100644 --- a/addon/flamenco/manager/api_client.py +++ b/addon/flamenco/manager/api_client.py @@ -76,7 +76,7 @@ class ApiClient(object): self.default_headers[header_name] = header_value self.cookie = cookie # Set default User-Agent. - self.user_agent = 'Flamenco/186dd064 (Blender add-on)' + self.user_agent = 'Flamenco/f2438a89 (Blender add-on)' def __enter__(self): return self diff --git a/addon/flamenco/manager/configuration.py b/addon/flamenco/manager/configuration.py index 4daaf214..543d4a7f 100644 --- a/addon/flamenco/manager/configuration.py +++ b/addon/flamenco/manager/configuration.py @@ -404,7 +404,7 @@ conf = flamenco.manager.Configuration( "OS: {env}\n"\ "Python Version: {pyversion}\n"\ "Version of the API: 1.0.0\n"\ - "SDK Package Version: 186dd064".\ + "SDK Package Version: f2438a89".\ format(env=sys.platform, pyversion=sys.version) def get_host_settings(self): diff --git a/addon/flamenco/manager/docs/BlenderPathCheckResult.md b/addon/flamenco/manager/docs/BlenderPathCheckResult.md index 8349776b..a21772f3 100644 --- a/addon/flamenco/manager/docs/BlenderPathCheckResult.md +++ b/addon/flamenco/manager/docs/BlenderPathCheckResult.md @@ -4,11 +4,11 @@ ## Properties Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- +**input** | **str** | The input that was given to find this Blender. | **path** | **str** | The path that was found. | **source** | [**BlenderPathSource**](BlenderPathSource.md) | | **is_usable** | **bool** | Whether the path is usable or not. | **cause** | **str** | Description of why this path is (not) usable. | -**input** | **str** | The input that was given to find this Blender. | [optional] **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/addon/flamenco/manager/docs/MetaApi.md b/addon/flamenco/manager/docs/MetaApi.md index ce0a5525..8b29728a 100644 --- a/addon/flamenco/manager/docs/MetaApi.md +++ b/addon/flamenco/manager/docs/MetaApi.md @@ -11,6 +11,7 @@ Method | HTTP request | Description [**get_configuration_file**](MetaApi.md#get_configuration_file) | **GET** /api/v3/configuration/file | Retrieve the configuration of Flamenco Manager. [**get_variables**](MetaApi.md#get_variables) | **GET** /api/v3/configuration/variables/{audience}/{platform} | Get the variables of this Manager. Used by the Blender add-on to recognise two-way variables, and for the web interface to do variable replacement based on the browser's platform. [**get_version**](MetaApi.md#get_version) | **GET** /api/v3/version | Get the Flamenco version of this Manager +[**save_wizard_config**](MetaApi.md#save_wizard_config) | **POST** /api/v3/configuration/wizard | Update the Manager's configuration, and restart it in fully functional mode. # **check_blender_exe_path** @@ -468,3 +469,79 @@ No authorization required [[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) +# **save_wizard_config** +> save_wizard_config() + +Update the Manager's configuration, and restart it in fully functional mode. + +### Example + + +```python +import time +import flamenco.manager +from flamenco.manager.api import meta_api +from flamenco.manager.model.error import Error +from flamenco.manager.model.wizard_config import WizardConfig +from pprint import pprint +# Defining the host is optional and defaults to http://localhost +# See configuration.py for a list of all supported configuration parameters. +configuration = flamenco.manager.Configuration( + host = "http://localhost" +) + + +# Enter a context with an instance of the API client +with flamenco.manager.ApiClient() as api_client: + # Create an instance of the API class + api_instance = meta_api.MetaApi(api_client) + wizard_config = WizardConfig( + storage_location="storage_location_example", + blender_executable=BlenderPathCheckResult( + input="input_example", + path="path_example", + source=BlenderPathSource("file_association"), + is_usable=True, + cause="cause_example", + ), + ) # WizardConfig | Configuration to save. (optional) + + # example passing only required values which don't have defaults set + # and optional values + try: + # Update the Manager's configuration, and restart it in fully functional mode. + api_instance.save_wizard_config(wizard_config=wizard_config) + except flamenco.manager.ApiException as e: + print("Exception when calling MetaApi->save_wizard_config: %s\n" % e) +``` + + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **wizard_config** | [**WizardConfig**](WizardConfig.md)| Configuration to save. | [optional] + +### Return type + +void (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**204** | Normal response. The webapp should do a full refresh at this point. | - | +**0** | Something went wrong. | - | + +[[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) + diff --git a/addon/flamenco/manager/docs/WizardConfig.md b/addon/flamenco/manager/docs/WizardConfig.md new file mode 100644 index 00000000..aabc7b59 --- /dev/null +++ b/addon/flamenco/manager/docs/WizardConfig.md @@ -0,0 +1,14 @@ +# WizardConfig + +Configuration obtained from the First-Time Wizard. + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**storage_location** | **str** | Directory used for job file storage. | +**blender_executable** | [**BlenderPathCheckResult**](BlenderPathCheckResult.md) | | +**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/addon/flamenco/manager/model/blender_path_check_result.py b/addon/flamenco/manager/model/blender_path_check_result.py index ee295daf..8256064d 100644 --- a/addon/flamenco/manager/model/blender_path_check_result.py +++ b/addon/flamenco/manager/model/blender_path_check_result.py @@ -87,11 +87,11 @@ class BlenderPathCheckResult(ModelNormal): """ lazy_import() return { + 'input': (str,), # noqa: E501 'path': (str,), # noqa: E501 'source': (BlenderPathSource,), # noqa: E501 'is_usable': (bool,), # noqa: E501 'cause': (str,), # noqa: E501 - 'input': (str,), # noqa: E501 } @cached_property @@ -100,11 +100,11 @@ class BlenderPathCheckResult(ModelNormal): attribute_map = { + 'input': 'input', # noqa: E501 'path': 'path', # noqa: E501 'source': 'source', # noqa: E501 'is_usable': 'is_usable', # noqa: E501 'cause': 'cause', # noqa: E501 - 'input': 'input', # noqa: E501 } read_only_vars = { @@ -114,10 +114,11 @@ class BlenderPathCheckResult(ModelNormal): @classmethod @convert_js_args_to_python_args - def _from_openapi_data(cls, path, source, is_usable, cause, *args, **kwargs): # noqa: E501 + def _from_openapi_data(cls, input, path, source, is_usable, cause, *args, **kwargs): # noqa: E501 """BlenderPathCheckResult - a model defined in OpenAPI Args: + input (str): The input that was given to find this Blender. path (str): The path that was found. source (BlenderPathSource): is_usable (bool): Whether the path is usable or not. @@ -154,7 +155,6 @@ class BlenderPathCheckResult(ModelNormal): Animal class but this time we won't travel through its discriminator because we passed in _visited_composed_classes = (Animal,) - input (str): The input that was given to find this Blender.. [optional] # noqa: E501 """ _check_type = kwargs.pop('_check_type', True) @@ -182,6 +182,7 @@ class BlenderPathCheckResult(ModelNormal): self._configuration = _configuration self._visited_composed_classes = _visited_composed_classes + (self.__class__,) + self.input = input self.path = path self.source = source self.is_usable = is_usable @@ -206,10 +207,11 @@ class BlenderPathCheckResult(ModelNormal): ]) @convert_js_args_to_python_args - def __init__(self, path, source, is_usable, cause, *args, **kwargs): # noqa: E501 + def __init__(self, input, path, source, is_usable, cause, *args, **kwargs): # noqa: E501 """BlenderPathCheckResult - a model defined in OpenAPI Args: + input (str): The input that was given to find this Blender. path (str): The path that was found. source (BlenderPathSource): is_usable (bool): Whether the path is usable or not. @@ -246,7 +248,6 @@ class BlenderPathCheckResult(ModelNormal): Animal class but this time we won't travel through its discriminator because we passed in _visited_composed_classes = (Animal,) - input (str): The input that was given to find this Blender.. [optional] # noqa: E501 """ _check_type = kwargs.pop('_check_type', True) @@ -272,6 +273,7 @@ class BlenderPathCheckResult(ModelNormal): self._configuration = _configuration self._visited_composed_classes = _visited_composed_classes + (self.__class__,) + self.input = input self.path = path self.source = source self.is_usable = is_usable diff --git a/addon/flamenco/manager/model/wizard_config.py b/addon/flamenco/manager/model/wizard_config.py new file mode 100644 index 00000000..1870b9cd --- /dev/null +++ b/addon/flamenco/manager/model/wizard_config.py @@ -0,0 +1,273 @@ +""" + Flamenco manager + + Render Farm manager API # noqa: E501 + + The version of the OpenAPI document: 1.0.0 + Generated by: https://openapi-generator.tech +""" + + +import re # noqa: F401 +import sys # noqa: F401 + +from flamenco.manager.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 flamenco.manager.exceptions import ApiAttributeError + + +def lazy_import(): + from flamenco.manager.model.blender_path_check_result import BlenderPathCheckResult + globals()['BlenderPathCheckResult'] = BlenderPathCheckResult + + +class WizardConfig(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 + """ + lazy_import() + 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. + """ + lazy_import() + return { + 'storage_location': (str,), # noqa: E501 + 'blender_executable': (BlenderPathCheckResult,), # noqa: E501 + } + + @cached_property + def discriminator(): + return None + + + attribute_map = { + 'storage_location': 'storageLocation', # noqa: E501 + 'blender_executable': 'blenderExecutable', # noqa: E501 + } + + read_only_vars = { + } + + _composed_schemas = {} + + @classmethod + @convert_js_args_to_python_args + def _from_openapi_data(cls, storage_location, blender_executable, *args, **kwargs): # noqa: E501 + """WizardConfig - a model defined in OpenAPI + + Args: + storage_location (str): Directory used for job file storage. + blender_executable (BlenderPathCheckResult): + + 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', ()) + + self = super(OpenApiModel, cls).__new__(cls) + + if args: + 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.storage_location = storage_location + self.blender_executable = blender_executable + 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, storage_location, blender_executable, *args, **kwargs): # noqa: E501 + """WizardConfig - a model defined in OpenAPI + + Args: + storage_location (str): Directory used for job file storage. + blender_executable (BlenderPathCheckResult): + + 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: + 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.storage_location = storage_location + self.blender_executable = blender_executable + 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/addon/flamenco/manager/models/__init__.py b/addon/flamenco/manager/models/__init__.py index 41a1a69e..1e46f2f5 100644 --- a/addon/flamenco/manager/models/__init__.py +++ b/addon/flamenco/manager/models/__init__.py @@ -66,6 +66,7 @@ from flamenco.manager.model.task_status_change import TaskStatusChange from flamenco.manager.model.task_summary import TaskSummary from flamenco.manager.model.task_update import TaskUpdate from flamenco.manager.model.task_worker import TaskWorker +from flamenco.manager.model.wizard_config import WizardConfig from flamenco.manager.model.worker import Worker from flamenco.manager.model.worker_all_of import WorkerAllOf from flamenco.manager.model.worker_list import WorkerList diff --git a/addon/flamenco/manager_README.md b/addon/flamenco/manager_README.md index abc52c3a..266a8ba4 100644 --- a/addon/flamenco/manager_README.md +++ b/addon/flamenco/manager_README.md @@ -4,7 +4,7 @@ Render Farm manager API The `flamenco.manager` package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project: - API version: 1.0.0 -- Package version: 186dd064 +- Package version: f2438a89 - Build package: org.openapitools.codegen.languages.PythonClientCodegen For more information, please visit [https://flamenco.io/](https://flamenco.io/) @@ -93,6 +93,7 @@ Class | Method | HTTP request | Description *MetaApi* | [**get_configuration_file**](flamenco/manager/docs/MetaApi.md#get_configuration_file) | **GET** /api/v3/configuration/file | Retrieve the configuration of Flamenco Manager. *MetaApi* | [**get_variables**](flamenco/manager/docs/MetaApi.md#get_variables) | **GET** /api/v3/configuration/variables/{audience}/{platform} | Get the variables of this Manager. Used by the Blender add-on to recognise two-way variables, and for the web interface to do variable replacement based on the browser's platform. *MetaApi* | [**get_version**](flamenco/manager/docs/MetaApi.md#get_version) | **GET** /api/v3/version | Get the Flamenco version of this Manager +*MetaApi* | [**save_wizard_config**](flamenco/manager/docs/MetaApi.md#save_wizard_config) | **POST** /api/v3/configuration/wizard | Update the Manager's configuration, and restart it in fully functional mode. *ShamanApi* | [**shaman_checkout**](flamenco/manager/docs/ShamanApi.md#shaman_checkout) | **POST** /api/v3/shaman/checkout/create | Create a directory, and symlink the required files into it. The files must all have been uploaded to Shaman before calling this endpoint. *ShamanApi* | [**shaman_checkout_requirements**](flamenco/manager/docs/ShamanApi.md#shaman_checkout_requirements) | **POST** /api/v3/shaman/checkout/requirements | Checks a Shaman Requirements file, and reports which files are unknown. *ShamanApi* | [**shaman_file_store**](flamenco/manager/docs/ShamanApi.md#shaman_file_store) | **POST** /api/v3/shaman/files/{checksum}/{filesize} | Store a new file on the Shaman server. Note that the Shaman server can forcibly close the HTTP connection when another client finishes uploading the exact same file, to prevent double uploads. The file's contents should be sent in the request body. @@ -170,6 +171,7 @@ Class | Method | HTTP request | Description - [TaskSummary](flamenco/manager/docs/TaskSummary.md) - [TaskUpdate](flamenco/manager/docs/TaskUpdate.md) - [TaskWorker](flamenco/manager/docs/TaskWorker.md) + - [WizardConfig](flamenco/manager/docs/WizardConfig.md) - [Worker](flamenco/manager/docs/Worker.md) - [WorkerAllOf](flamenco/manager/docs/WorkerAllOf.md) - [WorkerList](flamenco/manager/docs/WorkerList.md) diff --git a/internal/worker/mocks/client.gen.go b/internal/worker/mocks/client.gen.go index 487c091d..c7db040c 100644 --- a/internal/worker/mocks/client.gen.go +++ b/internal/worker/mocks/client.gen.go @@ -616,6 +616,46 @@ func (mr *MockFlamencoClientMockRecorder) RequestWorkerStatusChangeWithResponse( return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RequestWorkerStatusChangeWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).RequestWorkerStatusChangeWithResponse), varargs...) } +// SaveWizardConfigWithBodyWithResponse mocks base method. +func (m *MockFlamencoClient) SaveWizardConfigWithBodyWithResponse(arg0 context.Context, arg1 string, arg2 io.Reader, arg3 ...api.RequestEditorFn) (*api.SaveWizardConfigResponse, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1, arg2} + for _, a := range arg3 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "SaveWizardConfigWithBodyWithResponse", varargs...) + ret0, _ := ret[0].(*api.SaveWizardConfigResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SaveWizardConfigWithBodyWithResponse indicates an expected call of SaveWizardConfigWithBodyWithResponse. +func (mr *MockFlamencoClientMockRecorder) SaveWizardConfigWithBodyWithResponse(arg0, arg1, arg2 interface{}, arg3 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1, arg2}, arg3...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveWizardConfigWithBodyWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).SaveWizardConfigWithBodyWithResponse), varargs...) +} + +// SaveWizardConfigWithResponse mocks base method. +func (m *MockFlamencoClient) SaveWizardConfigWithResponse(arg0 context.Context, arg1 api.SaveWizardConfigJSONRequestBody, arg2 ...api.RequestEditorFn) (*api.SaveWizardConfigResponse, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "SaveWizardConfigWithResponse", varargs...) + ret0, _ := ret[0].(*api.SaveWizardConfigResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SaveWizardConfigWithResponse indicates an expected call of SaveWizardConfigWithResponse. +func (mr *MockFlamencoClientMockRecorder) SaveWizardConfigWithResponse(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveWizardConfigWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).SaveWizardConfigWithResponse), varargs...) +} + // ScheduleTaskWithResponse mocks base method. func (m *MockFlamencoClient) ScheduleTaskWithResponse(arg0 context.Context, arg1 ...api.RequestEditorFn) (*api.ScheduleTaskResponse, error) { m.ctrl.T.Helper() diff --git a/pkg/api/openapi_client.gen.go b/pkg/api/openapi_client.gen.go index f1ca06e9..1fb73926 100644 --- a/pkg/api/openapi_client.gen.go +++ b/pkg/api/openapi_client.gen.go @@ -114,6 +114,11 @@ type ClientInterface interface { // GetVariables request GetVariables(ctx context.Context, audience ManagerVariableAudience, platform string, reqEditors ...RequestEditorFn) (*http.Response, error) + // SaveWizardConfig request with any body + SaveWizardConfigWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + SaveWizardConfig(ctx context.Context, body SaveWizardConfigJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + // SubmitJob request with any body SubmitJobWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) @@ -328,6 +333,30 @@ func (c *Client) GetVariables(ctx context.Context, audience ManagerVariableAudie return c.Client.Do(req) } +func (c *Client) SaveWizardConfigWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewSaveWizardConfigRequestWithBody(c.Server, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) SaveWizardConfig(ctx context.Context, body SaveWizardConfigJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewSaveWizardConfigRequest(c.Server, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + func (c *Client) SubmitJobWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { req, err := NewSubmitJobRequestWithBody(c.Server, contentType, body) if err != nil { @@ -1046,6 +1075,46 @@ func NewGetVariablesRequest(server string, audience ManagerVariableAudience, pla return req, nil } +// NewSaveWizardConfigRequest calls the generic SaveWizardConfig builder with application/json body +func NewSaveWizardConfigRequest(server string, body SaveWizardConfigJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewSaveWizardConfigRequestWithBody(server, "application/json", bodyReader) +} + +// NewSaveWizardConfigRequestWithBody generates requests for SaveWizardConfig with any type of body +func NewSaveWizardConfigRequestWithBody(server string, contentType string, body io.Reader) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/api/v3/configuration/wizard") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + // NewSubmitJobRequest calls the generic SubmitJob builder with application/json body func NewSubmitJobRequest(server string, body SubmitJobJSONRequestBody) (*http.Request, error) { var bodyReader io.Reader @@ -2263,6 +2332,11 @@ type ClientWithResponsesInterface interface { // GetVariables request GetVariablesWithResponse(ctx context.Context, audience ManagerVariableAudience, platform string, reqEditors ...RequestEditorFn) (*GetVariablesResponse, error) + // SaveWizardConfig request with any body + SaveWizardConfigWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*SaveWizardConfigResponse, error) + + SaveWizardConfigWithResponse(ctx context.Context, body SaveWizardConfigJSONRequestBody, reqEditors ...RequestEditorFn) (*SaveWizardConfigResponse, error) + // SubmitJob request with any body SubmitJobWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*SubmitJobResponse, error) @@ -2519,6 +2593,28 @@ func (r GetVariablesResponse) StatusCode() int { return 0 } +type SaveWizardConfigResponse struct { + Body []byte + HTTPResponse *http.Response + JSONDefault *Error +} + +// Status returns HTTPResponse.Status +func (r SaveWizardConfigResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r SaveWizardConfigResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + type SubmitJobResponse struct { Body []byte HTTPResponse *http.Response @@ -3291,6 +3387,23 @@ func (c *ClientWithResponses) GetVariablesWithResponse(ctx context.Context, audi return ParseGetVariablesResponse(rsp) } +// SaveWizardConfigWithBodyWithResponse request with arbitrary body returning *SaveWizardConfigResponse +func (c *ClientWithResponses) SaveWizardConfigWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*SaveWizardConfigResponse, error) { + rsp, err := c.SaveWizardConfigWithBody(ctx, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseSaveWizardConfigResponse(rsp) +} + +func (c *ClientWithResponses) SaveWizardConfigWithResponse(ctx context.Context, body SaveWizardConfigJSONRequestBody, reqEditors ...RequestEditorFn) (*SaveWizardConfigResponse, error) { + rsp, err := c.SaveWizardConfig(ctx, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseSaveWizardConfigResponse(rsp) +} + // SubmitJobWithBodyWithResponse request with arbitrary body returning *SubmitJobResponse func (c *ClientWithResponses) SubmitJobWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*SubmitJobResponse, error) { rsp, err := c.SubmitJobWithBody(ctx, contentType, body, reqEditors...) @@ -3852,6 +3965,32 @@ func ParseGetVariablesResponse(rsp *http.Response) (*GetVariablesResponse, error return response, nil } +// ParseSaveWizardConfigResponse parses an HTTP response from a SaveWizardConfigWithResponse call +func ParseSaveWizardConfigResponse(rsp *http.Response) (*SaveWizardConfigResponse, error) { + bodyBytes, err := ioutil.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &SaveWizardConfigResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && true: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSONDefault = &dest + + } + + return response, nil +} + // ParseSubmitJobResponse parses an HTTP response from a SubmitJobWithResponse call func ParseSubmitJobResponse(rsp *http.Response) (*SubmitJobResponse, error) { bodyBytes, err := ioutil.ReadAll(rsp.Body) diff --git a/pkg/api/openapi_server.gen.go b/pkg/api/openapi_server.gen.go index 1f57abeb..f5752b95 100644 --- a/pkg/api/openapi_server.gen.go +++ b/pkg/api/openapi_server.gen.go @@ -31,6 +31,9 @@ type ServerInterface interface { // Get the variables of this Manager. Used by the Blender add-on to recognise two-way variables, and for the web interface to do variable replacement based on the browser's platform. // (GET /api/v3/configuration/variables/{audience}/{platform}) GetVariables(ctx echo.Context, audience ManagerVariableAudience, platform string) error + // Update the Manager's configuration, and restart it in fully functional mode. + // (POST /api/v3/configuration/wizard) + SaveWizardConfig(ctx echo.Context) error // Submit a new job for Flamenco Manager to execute. // (POST /api/v3/jobs) SubmitJob(ctx echo.Context) error @@ -201,6 +204,15 @@ func (w *ServerInterfaceWrapper) GetVariables(ctx echo.Context) error { return err } +// SaveWizardConfig converts echo context to params. +func (w *ServerInterfaceWrapper) SaveWizardConfig(ctx echo.Context) error { + var err error + + // Invoke the callback with all the unmarshalled arguments + err = w.Handler.SaveWizardConfig(ctx) + return err +} + // SubmitJob converts echo context to params. func (w *ServerInterfaceWrapper) SubmitJob(ctx echo.Context) error { var err error @@ -700,6 +712,7 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL router.POST(baseURL+"/api/v3/configuration/check/shared-storage", wrapper.CheckSharedStoragePath) router.GET(baseURL+"/api/v3/configuration/file", wrapper.GetConfigurationFile) router.GET(baseURL+"/api/v3/configuration/variables/:audience/:platform", wrapper.GetVariables) + router.POST(baseURL+"/api/v3/configuration/wizard", wrapper.SaveWizardConfig) router.POST(baseURL+"/api/v3/jobs", wrapper.SubmitJob) router.GET(baseURL+"/api/v3/jobs/last-rendered", wrapper.FetchGlobalLastRenderedInfo) router.POST(baseURL+"/api/v3/jobs/query", wrapper.QueryJobs) diff --git a/pkg/api/openapi_spec.gen.go b/pkg/api/openapi_spec.gen.go index 8f34d351..43d2cfce 100644 --- a/pkg/api/openapi_spec.gen.go +++ b/pkg/api/openapi_spec.gen.go @@ -18,169 +18,171 @@ import ( // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "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", - "AA==", + "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", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/pkg/api/openapi_types.gen.go b/pkg/api/openapi_types.gen.go index eaf9585a..852fc228 100644 --- a/pkg/api/openapi_types.gen.go +++ b/pkg/api/openapi_types.gen.go @@ -226,7 +226,7 @@ type BlenderPathCheckResult struct { Cause string `json:"cause"` // The input that was given to find this Blender. - Input *string `json:"input,omitempty"` + Input string `json:"input"` // Whether the path is usable or not. IsUsable bool `json:"is_usable"` @@ -640,6 +640,14 @@ type TaskWorker struct { Name string `json:"name"` } +// Configuration obtained from the First-Time Wizard. +type WizardConfig struct { + BlenderExecutable BlenderPathCheckResult `json:"blenderExecutable"` + + // Directory used for job file storage. + StorageLocation string `json:"storageLocation"` +} + // Worker defines model for Worker. type Worker struct { // Embedded struct due to allOf(#/components/schemas/WorkerSummary) @@ -715,6 +723,9 @@ type CheckBlenderExePathJSONBody PathCheckInput // CheckSharedStoragePathJSONBody defines parameters for CheckSharedStoragePath. type CheckSharedStoragePathJSONBody PathCheckInput +// SaveWizardConfigJSONBody defines parameters for SaveWizardConfig. +type SaveWizardConfigJSONBody WizardConfig + // SubmitJobJSONBody defines parameters for SubmitJob. type SubmitJobJSONBody SubmittedJob @@ -766,6 +777,9 @@ type CheckBlenderExePathJSONRequestBody CheckBlenderExePathJSONBody // CheckSharedStoragePathJSONRequestBody defines body for CheckSharedStoragePath for application/json ContentType. type CheckSharedStoragePathJSONRequestBody CheckSharedStoragePathJSONBody +// SaveWizardConfigJSONRequestBody defines body for SaveWizardConfig for application/json ContentType. +type SaveWizardConfigJSONRequestBody SaveWizardConfigJSONBody + // SubmitJobJSONRequestBody defines body for SubmitJob for application/json ContentType. type SubmitJobJSONRequestBody SubmitJobJSONBody diff --git a/web/app/src/manager-api/ApiClient.js b/web/app/src/manager-api/ApiClient.js index 78eea20c..b7628e8c 100644 --- a/web/app/src/manager-api/ApiClient.js +++ b/web/app/src/manager-api/ApiClient.js @@ -55,7 +55,7 @@ class ApiClient { * @default {} */ this.defaultHeaders = { - 'User-Agent': 'Flamenco/186dd064 / webbrowser' + 'User-Agent': 'Flamenco/f2438a89 / webbrowser' }; /** diff --git a/web/app/src/manager-api/index.js b/web/app/src/manager-api/index.js index 21012c78..cce8d4cc 100644 --- a/web/app/src/manager-api/index.js +++ b/web/app/src/manager-api/index.js @@ -65,6 +65,7 @@ import TaskStatusChange from './model/TaskStatusChange'; import TaskSummary from './model/TaskSummary'; import TaskUpdate from './model/TaskUpdate'; import TaskWorker from './model/TaskWorker'; +import WizardConfig from './model/WizardConfig'; import Worker from './model/Worker'; import WorkerAllOf from './model/WorkerAllOf'; import WorkerList from './model/WorkerList'; @@ -432,6 +433,12 @@ export { */ TaskWorker, + /** + * The WizardConfig model constructor. + * @property {module:model/WizardConfig} + */ + WizardConfig, + /** * The Worker model constructor. * @property {module:model/Worker} diff --git a/web/app/src/manager-api/manager/MetaApi.js b/web/app/src/manager-api/manager/MetaApi.js index b6621669..6fa73cd5 100644 --- a/web/app/src/manager-api/manager/MetaApi.js +++ b/web/app/src/manager-api/manager/MetaApi.js @@ -21,6 +21,7 @@ import ManagerVariable from '../model/ManagerVariable'; import ManagerVariableAudience from '../model/ManagerVariableAudience'; import PathCheckInput from '../model/PathCheckInput'; import PathCheckResult from '../model/PathCheckResult'; +import WizardConfig from '../model/WizardConfig'; /** * Meta service. @@ -339,4 +340,48 @@ export default class MetaApi { } + /** + * Update the Manager's configuration, and restart it in fully functional mode. + * @param {Object} opts Optional parameters + * @param {module:model/WizardConfig} opts.wizardConfig Configuration to save. + * @return {Promise} a {@link https://www.promisejs.org/|Promise}, with an object containing HTTP response + */ + saveWizardConfigWithHttpInfo(opts) { + opts = opts || {}; + let postBody = opts['wizardConfig']; + + let pathParams = { + }; + let queryParams = { + }; + let headerParams = { + }; + let formParams = { + }; + + let authNames = []; + let contentTypes = ['application/json']; + let accepts = ['application/json']; + let returnType = null; + return this.apiClient.callApi( + '/api/v3/configuration/wizard', 'POST', + pathParams, queryParams, headerParams, formParams, postBody, + authNames, contentTypes, accepts, returnType, null + ); + } + + /** + * Update the Manager's configuration, and restart it in fully functional mode. + * @param {Object} opts Optional parameters + * @param {module:model/WizardConfig} opts.wizardConfig Configuration to save. + * @return {Promise} a {@link https://www.promisejs.org/|Promise} + */ + saveWizardConfig(opts) { + return this.saveWizardConfigWithHttpInfo(opts) + .then(function(response_and_data) { + return response_and_data.data; + }); + } + + } diff --git a/web/app/src/manager-api/model/BlenderPathCheckResult.js b/web/app/src/manager-api/model/BlenderPathCheckResult.js index 0a0400a5..8e545f86 100644 --- a/web/app/src/manager-api/model/BlenderPathCheckResult.js +++ b/web/app/src/manager-api/model/BlenderPathCheckResult.js @@ -23,14 +23,15 @@ class BlenderPathCheckResult { /** * Constructs a new BlenderPathCheckResult. * @alias module:model/BlenderPathCheckResult + * @param input {String} The input that was given to find this Blender. * @param path {String} The path that was found. * @param source {module:model/BlenderPathSource} * @param isUsable {Boolean} Whether the path is usable or not. * @param cause {String} Description of why this path is (not) usable. */ - constructor(path, source, isUsable, cause) { + constructor(input, path, source, isUsable, cause) { - BlenderPathCheckResult.initialize(this, path, source, isUsable, cause); + BlenderPathCheckResult.initialize(this, input, path, source, isUsable, cause); } /** @@ -38,7 +39,8 @@ class BlenderPathCheckResult { * This method is used by the constructors of any subclasses, in order to implement multiple inheritance (mix-ins). * Only for internal use. */ - static initialize(obj, path, source, isUsable, cause) { + static initialize(obj, input, path, source, isUsable, cause) { + obj['input'] = input; obj['path'] = path; obj['source'] = source; obj['is_usable'] = isUsable; diff --git a/web/app/src/manager-api/model/WizardConfig.js b/web/app/src/manager-api/model/WizardConfig.js new file mode 100644 index 00000000..07107d59 --- /dev/null +++ b/web/app/src/manager-api/model/WizardConfig.js @@ -0,0 +1,86 @@ +/** + * Flamenco manager + * Render Farm manager API + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + * + */ + +import ApiClient from '../ApiClient'; +import BlenderPathCheckResult from './BlenderPathCheckResult'; + +/** + * The WizardConfig model module. + * @module model/WizardConfig + * @version 0.0.0 + */ +class WizardConfig { + /** + * Constructs a new WizardConfig. + * Configuration obtained from the First-Time Wizard. + * @alias module:model/WizardConfig + * @param storageLocation {String} Directory used for job file storage. + * @param blenderExecutable {module:model/BlenderPathCheckResult} + */ + constructor(storageLocation, blenderExecutable) { + + WizardConfig.initialize(this, storageLocation, blenderExecutable); + } + + /** + * Initializes the fields of this object. + * This method is used by the constructors of any subclasses, in order to implement multiple inheritance (mix-ins). + * Only for internal use. + */ + static initialize(obj, storageLocation, blenderExecutable) { + obj['storageLocation'] = storageLocation; + obj['blenderExecutable'] = blenderExecutable; + } + + /** + * Constructs a WizardConfig from a plain JavaScript object, optionally creating a new instance. + * Copies all relevant properties from data to obj if supplied or a new instance if not. + * @param {Object} data The plain JavaScript object bearing properties of interest. + * @param {module:model/WizardConfig} obj Optional instance to populate. + * @return {module:model/WizardConfig} The populated WizardConfig instance. + */ + static constructFromObject(data, obj) { + if (data) { + obj = obj || new WizardConfig(); + + if (data.hasOwnProperty('storageLocation')) { + obj['storageLocation'] = ApiClient.convertToType(data['storageLocation'], 'String'); + } + if (data.hasOwnProperty('blenderExecutable')) { + obj['blenderExecutable'] = BlenderPathCheckResult.constructFromObject(data['blenderExecutable']); + } + } + return obj; + } + + +} + +/** + * Directory used for job file storage. + * @member {String} storageLocation + */ +WizardConfig.prototype['storageLocation'] = undefined; + +/** + * @member {module:model/BlenderPathCheckResult} blenderExecutable + */ +WizardConfig.prototype['blenderExecutable'] = undefined; + + + + + + +export default WizardConfig; +