From 99778a4a266eedeb04d8f7a5851c1f96d6e05ecf Mon Sep 17 00:00:00 2001 From: anton-sidelnikov Date: Fri, 31 Jan 2025 14:23:45 +0100 Subject: [PATCH 1/5] [Feat.] FunctionGraph Aliases and versions --- doc/source/sdk/guides/function_graph.rst | 56 ++++++++ doc/source/sdk/proxies/function_graph.rst | 15 ++ .../sdk/resources/function_graph/index.rst | 2 + .../sdk/resources/function_graph/v2/alias.rst | 13 ++ .../resources/function_graph/v2/version.rst | 13 ++ examples/function_graph/create_alias.py | 40 ++++++ examples/function_graph/delete_alias.py | 40 ++++++ examples/function_graph/get_alias.py | 42 ++++++ examples/function_graph/list_aliases.py | 24 ++++ examples/function_graph/list_versions.py | 24 ++++ examples/function_graph/publish_version.py | 41 ++++++ examples/function_graph/update_alias.py | 47 +++++++ otcextensions/sdk/function_graph/v2/_proxy.py | 107 ++++++++++++++ otcextensions/sdk/function_graph/v2/alias.py | 52 +++++++ otcextensions/sdk/function_graph/v2/event.py | 4 +- .../sdk/function_graph/v2/version.py | 73 ++++++++++ .../functional/sdk/function_graph/__init__.py | 50 +++++++ .../sdk/function_graph/v2/test_alias.py | 86 ++++++++++++ .../sdk/function_graph/v2/test_event.py | 2 +- .../unit/sdk/function_graph/v2/test_alias.py | 39 ++++++ .../unit/sdk/function_graph/v2/test_proxy.py | 130 ++++++++++++++++++ .../sdk/function_graph/v2/test_version.py | 36 +++++ 22 files changed, 932 insertions(+), 4 deletions(-) create mode 100644 doc/source/sdk/resources/function_graph/v2/alias.rst create mode 100644 doc/source/sdk/resources/function_graph/v2/version.rst create mode 100644 examples/function_graph/create_alias.py create mode 100644 examples/function_graph/delete_alias.py create mode 100644 examples/function_graph/get_alias.py create mode 100644 examples/function_graph/list_aliases.py create mode 100644 examples/function_graph/list_versions.py create mode 100644 examples/function_graph/publish_version.py create mode 100644 examples/function_graph/update_alias.py create mode 100644 otcextensions/sdk/function_graph/v2/alias.py create mode 100644 otcextensions/sdk/function_graph/v2/version.py create mode 100644 otcextensions/tests/functional/sdk/function_graph/v2/test_alias.py create mode 100644 otcextensions/tests/unit/sdk/function_graph/v2/test_alias.py create mode 100644 otcextensions/tests/unit/sdk/function_graph/v2/test_version.py diff --git a/doc/source/sdk/guides/function_graph.rst b/doc/source/sdk/guides/function_graph.rst index 3cbf93850..e630263d1 100644 --- a/doc/source/sdk/guides/function_graph.rst +++ b/doc/source/sdk/guides/function_graph.rst @@ -223,3 +223,59 @@ This API is used to update a test event. .. literalinclude:: ../examples/function_graph/update_event.py :lines: 16-45 + +Publishing a Function Version +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This API is used to publish a function version. + +.. literalinclude:: ../examples/function_graph/publish_version.py + :lines: 16-41 + +Querying the Versions of a Function +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This API is used to query the versions of a function. + +.. literalinclude:: ../examples/function_graph/list_versions.py + :lines: 16-24 + +Querying All Aliases of a Function +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This API is used to query the versions and aliases of a function. + +.. literalinclude:: ../examples/function_graph/list_aliases.py + :lines: 16-24 + +Creating an Alias for a Function Version +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This API is used to create an alias for a function version. + +.. literalinclude:: ../examples/function_graph/create_alias.py + :lines: 16-40 + +Deleting an Alias of a Function Version +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This API is used to delete an alias of a function version. + +.. literalinclude:: ../examples/function_graph/delete_alias.py + :lines: 16-40 + +Modifying the Alias of a Function Version +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This API is used to modify the alias of a function version. + +.. literalinclude:: ../examples/function_graph/update_alias.py + :lines: 16-47 + +Querying the Alias of a Function Version +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This API is used to query the alias of a function version. + +.. literalinclude:: ../examples/function_graph/get_alias.py + :lines: 16-47 diff --git a/doc/source/sdk/proxies/function_graph.rst b/doc/source/sdk/proxies/function_graph.rst index 2acfd2034..e782f850d 100644 --- a/doc/source/sdk/proxies/function_graph.rst +++ b/doc/source/sdk/proxies/function_graph.rst @@ -50,3 +50,18 @@ Events :noindex: :members: create_event, delete_event, events, get_event, update_event + +Versions +^^^^^^^^ + +.. autoclass:: otcextensions.sdk.function_graph.v2._proxy.Proxy + :noindex: + :members: versions, publish_version + +Aliases +^^^^^^^ + +.. autoclass:: otcextensions.sdk.function_graph.v2._proxy.Proxy + :noindex: + :members: aliases, create_alias, delete_alias, + update_alias, get_alias \ No newline at end of file diff --git a/doc/source/sdk/resources/function_graph/index.rst b/doc/source/sdk/resources/function_graph/index.rst index a0ac69002..47d48f009 100644 --- a/doc/source/sdk/resources/function_graph/index.rst +++ b/doc/source/sdk/resources/function_graph/index.rst @@ -9,3 +9,5 @@ FunctionGraph Resources v2/quota v2/dependency v2/event + v2/alias + v2/version diff --git a/doc/source/sdk/resources/function_graph/v2/alias.rst b/doc/source/sdk/resources/function_graph/v2/alias.rst new file mode 100644 index 000000000..3c0342a9d --- /dev/null +++ b/doc/source/sdk/resources/function_graph/v2/alias.rst @@ -0,0 +1,13 @@ +otcextensions.sdk.function_graph.v2.alias +========================================= + +.. automodule:: otcextensions.sdk.function_graph.v2.alias + +The Alias Class +--------------- + +The ``Alias`` class inherits from +:class:`~otcextensions.sdk.sdk_resource.Resource`. + +.. autoclass:: otcextensions.sdk.function_graph.v2.alias.Alias + :members: diff --git a/doc/source/sdk/resources/function_graph/v2/version.rst b/doc/source/sdk/resources/function_graph/v2/version.rst new file mode 100644 index 000000000..9f60fd68b --- /dev/null +++ b/doc/source/sdk/resources/function_graph/v2/version.rst @@ -0,0 +1,13 @@ +otcextensions.sdk.function_graph.v2.version +=========================================== + +.. automodule:: otcextensions.sdk.function_graph.v2.version + +The Version Class +----------------- + +The ``Version`` class inherits from +:class:`~otcextensions.sdk.sdk_resource.Resource`. + +.. autoclass:: otcextensions.sdk.function_graph.v2.version.Version + :members: diff --git a/examples/function_graph/create_alias.py b/examples/function_graph/create_alias.py new file mode 100644 index 000000000..ed40304d1 --- /dev/null +++ b/examples/function_graph/create_alias.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python3 +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +""" +Create new alias +""" +import openstack +from otcextensions import sdk + +openstack.enable_logging(True) +conn = openstack.connect(cloud='otc') +sdk.register_otc_extensions(conn) + +func_attrs = { + 'func_name': 'test-function', + 'package': 'default', + 'runtime': 'Python3.9', + 'handler': 'index.handler', + 'timeout': 30, + 'memory_size': 128, + 'code_type': 'inline', +} +fg = conn.functiongraph.create_function(**func_attrs) + +alias_attrs = { + 'name': 'a1', + 'version': 'new-version' +} +alias = conn.functiongraph.create_alias( + fg.func_urn, **alias_attrs +) diff --git a/examples/function_graph/delete_alias.py b/examples/function_graph/delete_alias.py new file mode 100644 index 000000000..6b22ec59b --- /dev/null +++ b/examples/function_graph/delete_alias.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python3 +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +""" +Delete alias +""" +import openstack +from otcextensions import sdk + +openstack.enable_logging(True) +conn = openstack.connect(cloud='otc') +sdk.register_otc_extensions(conn) + +func_attrs = { + 'func_name': 'test-function', + 'package': 'default', + 'runtime': 'Python3.9', + 'handler': 'index.handler', + 'timeout': 30, + 'memory_size': 128, + 'code_type': 'inline', +} +fg = conn.functiongraph.create_function(**func_attrs) +alias_attrs = { + 'name': 'a1', + 'version': 'new-version' +} +al = conn.functiongraph.create_alias( + fg.func_urn, **alias_attrs +) +conn.functiongraph.delete_aliasw(fg, al) diff --git a/examples/function_graph/get_alias.py b/examples/function_graph/get_alias.py new file mode 100644 index 000000000..79dc16b0d --- /dev/null +++ b/examples/function_graph/get_alias.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python3 +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +""" +Get alias +""" +import openstack +from otcextensions import sdk + +openstack.enable_logging(True) +conn = openstack.connect(cloud='otc') +sdk.register_otc_extensions(conn) + +alias_attrs = { + 'name': 'a1', + 'version': 'new-version' +} +func_attrs = { + 'func_name': 'test-function', + 'package': 'default', + 'runtime': 'Python3.9', + 'handler': 'index.handler', + 'timeout': 30, + 'memory_size': 128, + 'code_type': 'inline', +} +fg = conn.functiongraph.create_function(**func_attrs) +al = conn.functiongraph.create_alias( + fg, **alias_attrs +) +a = conn.functiongraph.get_alias( + fg, al) +print(a) diff --git a/examples/function_graph/list_aliases.py b/examples/function_graph/list_aliases.py new file mode 100644 index 000000000..1df61adcf --- /dev/null +++ b/examples/function_graph/list_aliases.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python3 +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +""" +Get all aliases +""" +import openstack +from otcextensions import sdk + +openstack.enable_logging(True) +conn = openstack.connect(cloud='otc') +sdk.register_otc_extensions(conn) + +for a in conn.functiongraph.aliases(func_urn='urn'): + print(a) diff --git a/examples/function_graph/list_versions.py b/examples/function_graph/list_versions.py new file mode 100644 index 000000000..ebabb28af --- /dev/null +++ b/examples/function_graph/list_versions.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python3 +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +""" +Get all versions +""" +import openstack +from otcextensions import sdk + +openstack.enable_logging(True) +conn = openstack.connect(cloud='otc') +sdk.register_otc_extensions(conn) + +for v in conn.functiongraph.versions(func_urn='urn'): + print(v) diff --git a/examples/function_graph/publish_version.py b/examples/function_graph/publish_version.py new file mode 100644 index 000000000..79b360231 --- /dev/null +++ b/examples/function_graph/publish_version.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python3 +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +""" +Publish new version +""" +import openstack +from otcextensions import sdk + +openstack.enable_logging(True) +conn = openstack.connect(cloud='otc') +sdk.register_otc_extensions(conn) + +func_attrs = { + 'func_name': 'test-function', + 'package': 'default', + 'runtime': 'Python3.9', + 'handler': 'index.handler', + 'timeout': 30, + 'memory_size': 128, + 'code_type': 'inline', +} +fg = conn.functiongraph.create_function(**func_attrs) + +publish_attrs = { + 'version': 'new-version', + 'description': 'otce', +} + +publish = conn.functiongraph.publish_version( + fg, **publish_attrs +) diff --git a/examples/function_graph/update_alias.py b/examples/function_graph/update_alias.py new file mode 100644 index 000000000..34efab98e --- /dev/null +++ b/examples/function_graph/update_alias.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python3 +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +""" +Update alias +""" +import openstack +from otcextensions import sdk + +openstack.enable_logging(True) +conn = openstack.connect(cloud='otc') +sdk.register_otc_extensions(conn) + +func_attrs = { + 'func_name': 'test-function', + 'package': 'default', + 'runtime': 'Python3.9', + 'handler': 'index.handler', + 'timeout': 30, + 'memory_size': 128, + 'code_type': 'inline', +} +fg = conn.functiongraph.create_function(**func_attrs) + +alias_attrs = { + 'name': 'a1', + 'version': 'new-version' +} +alias = conn.functiongraph.create_alias( + fg.func_urn, **alias_attrs +) + +new_attrs = { + 'version': 'new-version', + 'description': 'new', +} +updated = conn.functiongraph.update_alias( + fg, alias, **new_attrs) diff --git a/otcextensions/sdk/function_graph/v2/_proxy.py b/otcextensions/sdk/function_graph/v2/_proxy.py index a9e3a69db..3e0bd274f 100644 --- a/otcextensions/sdk/function_graph/v2/_proxy.py +++ b/otcextensions/sdk/function_graph/v2/_proxy.py @@ -17,6 +17,8 @@ from otcextensions.sdk.function_graph.v2 import quota as _quota from otcextensions.sdk.function_graph.v2 import dependency as _d from otcextensions.sdk.function_graph.v2 import event as _event +from otcextensions.sdk.function_graph.v2 import alias as _alias +from otcextensions.sdk.function_graph.v2 import version as _version class Proxy(proxy.Proxy): @@ -333,3 +335,108 @@ def update_event(self, function, event, **attrs): return self._update( _event.Event, event, function_urn=function_urn, **attrs ) + + # ======== Versions Methods ======== + def versions(self, func_urn): + """List all published versions. + + :param func_urn: The URN of the Function to fetch + events from. + :returns: A generator of Version instances. + """ + function_urn = func_urn.rpartition(":")[0] + return self._list(_version.Version, function_urn=function_urn) + + def publish_version(self, function, **attrs): + """Publish a new version from attributes. + + :param function: The URN or instance of the Function to create + event in. + :param dict attrs: Keyword arguments to publish a Version. + :returns: The created Version instance. + :rtype: :class:`~otcextensions.sdk.function_graph.v2.version.Version` + """ + function = self._get_resource(_function.Function, function) + function_urn = function.func_urn.rpartition(":")[0] + return self._create( + _version.Version, function_urn=function_urn, **attrs + ) + + # ======== Aliases Methods ======== + + def aliases(self, func_urn): + """List all aliases. + + :param func_urn: The URN of the Function to fetch + events from. + :returns: A generator of Alias instances. + """ + function_urn = func_urn.rpartition(":")[0] + return self._list(_alias.Alias, function_urn=function_urn) + + def create_alias(self, function, **attrs): + """Create a new alias from attributes. + + :param function: The URN or instance of the Function to create + event in. + :param dict attrs: Keyword arguments to create an Alias. + :returns: The created Event instance. + :rtype: :class:`~otcextensions.sdk.function_graph.v2.alias.Alias` + """ + function = self._get_resource(_function.Function, function) + function_urn = function.id.rpartition(":")[0] + return self._create( + _alias.Alias, function_urn=function_urn, **attrs + ) + + def delete_alias(self, function, alias, ignore_missing=True): + """Delete an alias. + + :param function: The URN or instance of the Function to delete + alias from. + :param ignore_missing: When False, + `openstack.exceptions.ResourceNotFound` + will be raised when the tag does not exist. + When True, no exception will be set when attempting + to delete a nonexistent event. + :param alias: The instance of the Alias to delete. + :returns: ``None`` + """ + function = self._get_resource(_function.Function, function) + function_urn = function.func_urn.rpartition(":")[0] + return self._delete( + _alias.Alias, alias, + function_urn=function_urn, ignore_missing=ignore_missing + ) + + def update_alias(self, function, alias, **attrs): + """Update an alias from attributes. + + :param alias: key id or an instance of + :class:`~otcextensions.sdk.function_graph.v2.alias.Alias` + :param function: The URN or instance of the Function to update + alias in. + :param dict attrs: Keyword arguments to update an Alias. + :returns: The updated Alias instance. + :rtype: :class:`~otcextensions.sdk.function_graph.v2.alias.Alias` + """ + function = self._get_resource(_function.Function, function) + a = self._get_resource(_alias.Alias, alias) + return a._update_alias(self, function, alias, **attrs) + + def get_alias(self, function, alias): + """Get one alias by ID. + + :param alias: key id or an instance of + :class:`~otcextensions.sdk.function_graph.v2.alias.Alias` + :param function: The value can be the ID of a function or + a :class:`~otcextensions.sdk.function_graph.v2.function.Function` + instance. + :returns: instance of + :class:`~otcextensions.sdk.function_graph.v2.alias.Alias` + """ + function = self._get_resource(_function.Function, function) + return self._get( + _alias.Alias, alias, + function_urn=function.func_urn + ) diff --git a/otcextensions/sdk/function_graph/v2/alias.py b/otcextensions/sdk/function_graph/v2/alias.py new file mode 100644 index 000000000..3a01af37b --- /dev/null +++ b/otcextensions/sdk/function_graph/v2/alias.py @@ -0,0 +1,52 @@ +# Licensed under the Apache License, Version 2.0 (the 'License'); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from openstack import resource +from openstack import exceptions + + +class Alias(resource.Resource): + base_path = '/fgs/functions/%(function_urn)s/aliases' + resources_key = '' + + # Capabilities + allow_create = True + allow_fetch = True + allow_delete = True + allow_list = True + allow_commit = True + + # Properties + function_urn = resource.URI('function_urn', type=str) + name = resource.Body('name', type=str, alternate_id=True) + version = resource.Body('version', type=str) + description = resource.Body('description', type=str) + additional_version_weights = resource.Body( + 'additional_version_weights', type=dict + ) + additional_version_strategy = resource.Body( + 'additional_version_strategy', type=dict + ) + + # Attributes + last_modified = resource.Body('last_modified', type=str) + alias_urn = resource.Body('alias_urn', type=str) + + def _update_alias(self, session, function, alias, **attrs): + """Update Function Alias + """ + urn = function.func_urn.rpartition(':')[0] + url = self.base_path % {'function_urn': urn} + f'/{alias.id}' + response = session.put(url, json=attrs) + exceptions.raise_from_response(response) + self._translate_response(response) + return self \ No newline at end of file diff --git a/otcextensions/sdk/function_graph/v2/event.py b/otcextensions/sdk/function_graph/v2/event.py index 431550012..32af88202 100644 --- a/otcextensions/sdk/function_graph/v2/event.py +++ b/otcextensions/sdk/function_graph/v2/event.py @@ -21,7 +21,7 @@ class ListEvents(resource.Resource): class Event(resource.Resource): base_path = '/fgs/functions/%(function_urn)s/events' - + resources_key = 'events' # Capabilities allow_create = True allow_fetch = True @@ -43,8 +43,6 @@ class Event(resource.Resource): id = resource.Body('id', type=str) #: Total number of test events. count = resource.Body('count', type=int) - #: Total number of test events. - events = resource.Body('events', type=list, list_type=ListEvents) #: Next read location. next_marker = resource.Body('next_marker', type=int) #: Last update time. diff --git a/otcextensions/sdk/function_graph/v2/version.py b/otcextensions/sdk/function_graph/v2/version.py new file mode 100644 index 000000000..9cf1545a7 --- /dev/null +++ b/otcextensions/sdk/function_graph/v2/version.py @@ -0,0 +1,73 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from openstack import resource + + +class Version(resource.Resource): + base_path = '/fgs/functions/%(function_urn)s/versions' + resources_key = 'versions' + # Capabilities + allow_create = True + allow_fetch = True + allow_list = True + + _query_mapping = resource.QueryParameters( + 'maxitems', 'marker' + ) + + # Properties + function_urn = resource.URI('function_urn', type=str) + digest = resource.Body('digest', type=str) + version = resource.Body('version', type=str) + description = resource.Body('description', type=str) + + # Attributes + next_marker = resource.Body('next_marker', type=int) + count = resource.Body('count', type=int) + func_urn = resource.Body('func_urn', type=str) + func_name = resource.Body('func_name', type=str) + domain_id = resource.Body('domain_id', type=str) + project_id = resource.Body('namespace', type=str) + project_name = resource.Body('project_name', type=str) + package = resource.Body('package', type=str) + runtime = resource.Body('runtime', type=str) + timeout = resource.Body('timeout', type=int) + handler = resource.Body('handler', type=str) + memory_size = resource.Body('memory_size', type=int) + cpu = resource.Body('cpu', type=int) + code_type = resource.Body('code_type', type=str) + code_url = resource.Body('code_url', type=str) + code_filename = resource.Body('code_filename', type=str) + code_size = resource.Body('code_size', type=int) + user_data = resource.Body('user_data', type=str) + encrypted_user_data = resource.Body('encrypted_user_data', type=str) + image_name = resource.Body('image_name', type=str) + xrole = resource.Body('xrole', type=str) + app_xrole = resource.Body('app_xrole', type=str) + version_description = resource.Body('version_description', type=str) + last_modified = resource.Body('last_modified', type=str) + func_vpc = resource.Body('func_vpc', type=dict) + mount_config = resource.Body('mount_config', type=dict) + strategy_config = resource.Body('strategy_config', type=dict) + dependencies = resource.Body('dependencies', type=dict) + initializer_handler = resource.Body('initializer_handler', type=str) + initializer_timeout = resource.Body('initializer_timeout', type=int) + pre_stop_handler = resource.Body('pre_stop_handler', type=str) + pre_stop_timeout = resource.Body('pre_stop_timeout', type=int) + enterprise_project_id = resource.Body('enterprise_project_id', type=str) + long_time = resource.Body('long_time', type=bool) + log_group_id = resource.Body('log_group_id', type=str) + log_stream_id = resource.Body('log_stream_id', type=str) + type = resource.Body('type', type=str) + enable_dynamic_memory = resource.Body('enable_dynamic_memory', type=bool) + function_async_config = resource.Body('function_async_config', type=dict) diff --git a/otcextensions/tests/functional/sdk/function_graph/__init__.py b/otcextensions/tests/functional/sdk/function_graph/__init__.py index e69de29bb..2bd984d8c 100644 --- a/otcextensions/tests/functional/sdk/function_graph/__init__.py +++ b/otcextensions/tests/functional/sdk/function_graph/__init__.py @@ -0,0 +1,50 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import uuid + +from otcextensions.tests.functional import base + + +class TestFg(base.BaseFunctionalTest): + uuid_v4 = uuid.uuid4().hex[:8] + function_attrs = { + 'func_name': 'test-function-' + uuid_v4, + 'package': 'default', + 'runtime': 'Python3.9', + 'handler': 'index.handler', + 'timeout': 30, + 'memory_size': 128, + 'code_type': 'inline', + 'func_code': { + 'file': 'CmltcG9ydCBqc29uCgpkZWYgaGFuZGxlcihldmVudCwgY29udGV4d' + 'Ck6CiAgICB0cnk6CiAgICAgICAgIyBQYXJzZSB0aGUgaW5wdXQgZX' + 'ZlbnQgKGRhdGEpCiAgICAgICAgaW5wdXRfZGF0YSA9IGpzb24ubG9' + 'hZHMoZXZlbnQpCiAgICAgICAgCiAgICAgICAgIyBQcmludCB0aGUg' + 'cHJvdmlkZWQgZGF0YQogICAgICAgIHByaW50KCJSZWNlaXZlZCBkY' + 'XRhOiIsIGlucHV0X2RhdGEpCiAgICAgICAgCiAgICAgICAgIyBSZX' + 'R1cm4gYSByZXNwb25zZQogICAgICAgIHJlc3BvbnNlID0gewogICA' + 'gICAgICAgICAic3RhdHVzQ29kZSI6IDIwMCwKICAgICAgICAgICAg' + 'ImJvZHkiOiBmIkRhdGEgcmVjZWl2ZWQ6IHtpbnB1dF9kYXRhfSIKI' + 'CAgICAgICB9CiAgICAgICAgcmV0dXJuIGpzb24uZHVtcHMocmVzcG' + '9uc2UpCgogICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOgogICAgICA' + 'gICMgSGFuZGxlIGVycm9ycwogICAgICAgIGVycm9yX3Jlc3BvbnNl' + 'ID0gewogICAgICAgICAgICAic3RhdHVzQ29kZSI6IDUwMCwKICAgI' + 'CAgICAgICAgImJvZHkiOiBmIkVycm9yOiB7c3RyKGUpfSIKICAgIC' + 'AgICB9CiAgICAgICAgcmV0dXJuIGpzb24uZHVtcHMoZXJyb3JfcmV' + 'zcG9uc2UpCg==' + } + } + + def setUp(self): + super(TestFg, self).setUp() + self.client = self.conn.functiongraph diff --git a/otcextensions/tests/functional/sdk/function_graph/v2/test_alias.py b/otcextensions/tests/functional/sdk/function_graph/v2/test_alias.py new file mode 100644 index 000000000..60b96b9c0 --- /dev/null +++ b/otcextensions/tests/functional/sdk/function_graph/v2/test_alias.py @@ -0,0 +1,86 @@ +# Licensed under the Apache License, Version 2.0 (the 'License'); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import uuid +from otcextensions.sdk.function_graph.v2 import function +from otcextensions.sdk.function_graph.v2 import version +from otcextensions.sdk.function_graph.v2 import alias + +from openstack import _log + +from otcextensions.tests.functional.sdk.function_graph import TestFg + +_logger = _log.setup_logging('openstack') + + +class TestFunctionEvent(TestFg): + ID = None + uuid = uuid.uuid4().hex[:8] + + def setUp(self): + super(TestFunctionEvent, self).setUp() + self.function = self.client.create_function(**TestFg.function_attrs) + assert isinstance(self.function, function.Function) + + self.publish_attrs = { + 'version': 'new-version', + 'description': 'otce', + } + + self.publish = self.client.publish_version( + self.function, **self.publish_attrs + ) + assert isinstance(self.publish, version.Version) + + self.alias_attrs = { + 'name': 'a1', + 'version': 'new-version' + } + self.alias = self.client.create_alias( + self.publish.func_urn, **self.alias_attrs + ) + assert isinstance(self.alias, alias.Alias) + self.ID = self.alias.name + self.addCleanup( + self.client.delete_function, + self.function + ) + self.addCleanup( + self.client.delete_alias, + self.function, + self.alias + ) + + def test_function_aliases(self): + elist = list(self.client.aliases( + func_urn=self.function.func_urn)) + self.assertIn(self.alias_attrs['name'], elist[0].name) + + def test_function_published_versions(self): + vlist = list(self.client.versions( + func_urn=self.function.func_urn)) + self.assertIn(self.publish_attrs['version'], vlist[1].version) + + def test_get_function_alias(self): + a = self.client.get_alias( + self.function, self.alias) + self.assertIn(self.ID, a.id) + + def test_update_function_alias(self): + attrs = { + 'version': 'new-version', + 'description': 'new', + } + updated = self.client.update_alias( + self.function, self.alias, **attrs) + self.assertIn(attrs['version'], updated.version) + self.assertIn(attrs['description'], updated.description) diff --git a/otcextensions/tests/functional/sdk/function_graph/v2/test_event.py b/otcextensions/tests/functional/sdk/function_graph/v2/test_event.py index 0c64d3d9a..5c27bd7b4 100644 --- a/otcextensions/tests/functional/sdk/function_graph/v2/test_event.py +++ b/otcextensions/tests/functional/sdk/function_graph/v2/test_event.py @@ -80,7 +80,7 @@ def setUp(self): def test_function_events(self): elist = list(self.conn.functiongraph.events( func_urn=self.function.func_urn)) - self.assertIn(self.ID, elist[0].events[0].id) + self.assertIn(self.ID, elist[0].id) def test_get_function_event(self): e = self.conn.functiongraph.get_event( diff --git a/otcextensions/tests/unit/sdk/function_graph/v2/test_alias.py b/otcextensions/tests/unit/sdk/function_graph/v2/test_alias.py new file mode 100644 index 000000000..e6d05324c --- /dev/null +++ b/otcextensions/tests/unit/sdk/function_graph/v2/test_alias.py @@ -0,0 +1,39 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from openstack.tests.unit import base + +from otcextensions.sdk.function_graph.v2 import alias + + +EXAMPLE = { + 'name': 'a1', + 'version': 'new-version' +} + + +class TestFunctionInvocation(base.TestCase): + + def test_basic(self): + sot = alias.Alias() + path = '/fgs/functions/%(function_urn)s/aliases' + self.assertEqual(path, sot.base_path) + self.assertTrue(sot.allow_create) + self.assertTrue(sot.allow_list) + self.assertTrue(sot.allow_delete) + self.assertTrue(sot.allow_fetch) + self.assertTrue(sot.allow_commit) + + def test_make_it(self): + sot = alias.Alias(**EXAMPLE) + self.assertEqual(EXAMPLE['name'], sot.name) + self.assertEqual(EXAMPLE['version'], sot.version) diff --git a/otcextensions/tests/unit/sdk/function_graph/v2/test_proxy.py b/otcextensions/tests/unit/sdk/function_graph/v2/test_proxy.py index 28fa007a0..f30590275 100644 --- a/otcextensions/tests/unit/sdk/function_graph/v2/test_proxy.py +++ b/otcextensions/tests/unit/sdk/function_graph/v2/test_proxy.py @@ -17,6 +17,8 @@ from otcextensions.sdk.function_graph.v2 import dependency as _d from otcextensions.sdk.function_graph.v2 import quota as _q from otcextensions.sdk.function_graph.v2 import event as _event +from otcextensions.sdk.function_graph.v2 import alias as _alias +from otcextensions.sdk.function_graph.v2 import version as _version from openstack.tests.unit import test_proxy_base @@ -349,3 +351,131 @@ def test_get_event(self): 'function_urn': func.func_urn, } ) + + +class TestFgAlias(TestFgProxy): + def test_aliases(self): + func_urn = ('urn:fss:eu-de:45c274f200d2498683982c8741fb76ac:' + 'function:default:access-mysql-js-1213-1737554083545:' + 'latest') + self.verify_list( + self.proxy.aliases, + _alias.Alias, + method_args=[func_urn], + expected_args=[], + expected_kwargs={ + 'function_urn': func_urn.rpartition(":")[0] + }, + ) + + def test_create_alias(self): + func = _function.Function( + name='test', + id='urn:fss:eu-de:45c274f200d2498683982c8741fb76ac:' + 'function:default:access-mysql-js-1213-1737554083545:' + 'latest' + ) + self.verify_create( + self.proxy.create_alias, + _alias.Alias, + method_kwargs={ + 'function': func, + 'name': 'test_event' + }, + expected_kwargs={ + 'function_urn': func.id.rpartition(":")[0], + 'name': 'test_event'} + ) + + def test_delete_alias(self): + func = _function.Function( + name='test', + func_urn='urn:fss:eu-de:45c274f200d2498683982c8741fb76ac:' + 'function:default:access-mysql-js-1213-1737554083545:' + 'latest' + ) + a = _alias.Alias( + name='test', + ) + self.verify_delete( + self.proxy.delete_alias, + _alias.Alias, + method_args=[func, a], + expected_args=[a], + expected_kwargs={'function_urn': func.func_urn.rpartition(":")[0]} + ) + + def test_update_event(self): + func = _function.Function( + name='test', + func_urn='urn:fss:eu-de:45c274f200d2498683982c8741fb76ac:' + 'function:default:access-mysql-js-1213-1737554083545:' + 'latest' + ) + a = _alias.Alias(name='test') + attrs = { + 'version': 'new-version', + 'description': 'new', + } + self._verify( + 'otcextensions.sdk.function_graph.v2.alias.' + 'Alias._update_alias', + self.proxy.update_alias, + method_args=[func, a], + method_kwargs=attrs, + expected_args=[self.proxy, func, a], + expected_kwargs=attrs + ) + + def test_get_event(self): + func = _function.Function( + name='test', + func_urn='urn:fss:eu-de:45c274f200d2498683982c8741fb76ac:' + 'function:default:access-mysql-js-1213-1737554083545:' + 'latest' + ) + a = _alias.Alias(name='test') + self.verify_get( + self.proxy.get_alias, + _alias.Alias, + method_args=[func, a], + expected_args=[a], + expected_kwargs={ + 'function_urn': func.func_urn, + } + ) + + +class TestFgVersion(TestFgProxy): + def test_versions(self): + func_urn = ('urn:fss:eu-de:45c274f200d2498683982c8741fb76ac:' + 'function:default:access-mysql-js-1213-1737554083545:' + 'latest') + self.verify_list( + self.proxy.versions, + _version.Version, + method_args=[func_urn], + expected_args=[], + expected_kwargs={ + 'function_urn': func_urn.rpartition(":")[0] + }, + ) + + def test_publish_version(self): + func = _function.Function( + name='test', + func_urn='urn:fss:eu-de:45c274f200d2498683982c8741fb76ac:' + 'function:default:access-mysql-js-1213-1737554083545:' + 'latest' + ) + self.verify_create( + self.proxy.publish_version, + _version.Version, + method_kwargs={ + 'function': func, + 'name': 'test_event' + }, + expected_kwargs={ + 'function_urn': func.func_urn.rpartition(":")[0], + 'name': 'test_event'} + ) diff --git a/otcextensions/tests/unit/sdk/function_graph/v2/test_version.py b/otcextensions/tests/unit/sdk/function_graph/v2/test_version.py new file mode 100644 index 000000000..43d16dde0 --- /dev/null +++ b/otcextensions/tests/unit/sdk/function_graph/v2/test_version.py @@ -0,0 +1,36 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from openstack.tests.unit import base + +from otcextensions.sdk.function_graph.v2 import version + + +EXAMPLE = { + 'version': 'new-version', + 'description': 'otce', +} + + +class TestFunctionInvocation(base.TestCase): + + def test_basic(self): + sot = version.Version() + path = '/fgs/functions/%(function_urn)s/versions' + self.assertEqual(path, sot.base_path) + self.assertTrue(sot.allow_create) + self.assertTrue(sot.allow_list) + + def test_make_it(self): + sot = version.Version(**EXAMPLE) + self.assertEqual(EXAMPLE['version'], sot.version) + self.assertEqual(EXAMPLE['description'], sot.description) From 082b6143e92d7f28c9f780fe7add63e202e9bee5 Mon Sep 17 00:00:00 2001 From: anton-sidelnikov Date: Fri, 31 Jan 2025 15:09:21 +0100 Subject: [PATCH 2/5] [Fix] pep --- otcextensions/sdk/function_graph/v2/alias.py | 6 +++--- .../tests/functional/sdk/function_graph/v2/test_alias.py | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/otcextensions/sdk/function_graph/v2/alias.py b/otcextensions/sdk/function_graph/v2/alias.py index 3a01af37b..cc1a503f0 100644 --- a/otcextensions/sdk/function_graph/v2/alias.py +++ b/otcextensions/sdk/function_graph/v2/alias.py @@ -1,11 +1,11 @@ -# Licensed under the Apache License, Version 2.0 (the 'License'); you may +# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. @@ -49,4 +49,4 @@ def _update_alias(self, session, function, alias, **attrs): response = session.put(url, json=attrs) exceptions.raise_from_response(response) self._translate_response(response) - return self \ No newline at end of file + return self diff --git a/otcextensions/tests/functional/sdk/function_graph/v2/test_alias.py b/otcextensions/tests/functional/sdk/function_graph/v2/test_alias.py index 60b96b9c0..d3e3aa17d 100644 --- a/otcextensions/tests/functional/sdk/function_graph/v2/test_alias.py +++ b/otcextensions/tests/functional/sdk/function_graph/v2/test_alias.py @@ -1,11 +1,11 @@ -# Licensed under the Apache License, Version 2.0 (the 'License'); you may +# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. From 3298c27826ab06c0c409220d9fa13010c3140f3d Mon Sep 17 00:00:00 2001 From: anton-sidelnikov Date: Fri, 31 Jan 2025 15:09:33 +0100 Subject: [PATCH 3/5] [Style] rn --- .../notes/fg-aliases-versions-c0ffbc3d9cda043f.yaml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 releasenotes/notes/fg-aliases-versions-c0ffbc3d9cda043f.yaml diff --git a/releasenotes/notes/fg-aliases-versions-c0ffbc3d9cda043f.yaml b/releasenotes/notes/fg-aliases-versions-c0ffbc3d9cda043f.yaml new file mode 100644 index 000000000..9f51b3b5c --- /dev/null +++ b/releasenotes/notes/fg-aliases-versions-c0ffbc3d9cda043f.yaml @@ -0,0 +1,6 @@ +--- +features: + - | + Add FGS versions support. + - | + Add FGS aliases support. From c8b56944028b2fa5ee38cc90c07fee1e0f32194f Mon Sep 17 00:00:00 2001 From: anton-sidelnikov Date: Fri, 31 Jan 2025 15:15:16 +0100 Subject: [PATCH 4/5] [Fix] endline --- doc/source/sdk/proxies/function_graph.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/sdk/proxies/function_graph.rst b/doc/source/sdk/proxies/function_graph.rst index e782f850d..1ab8e7d06 100644 --- a/doc/source/sdk/proxies/function_graph.rst +++ b/doc/source/sdk/proxies/function_graph.rst @@ -64,4 +64,4 @@ Aliases .. autoclass:: otcextensions.sdk.function_graph.v2._proxy.Proxy :noindex: :members: aliases, create_alias, delete_alias, - update_alias, get_alias \ No newline at end of file + update_alias, get_alias From 29e55bf2645553c0e788c0bac41de629cc3bbf62 Mon Sep 17 00:00:00 2001 From: anton-sidelnikov Date: Fri, 31 Jan 2025 15:27:12 +0100 Subject: [PATCH 5/5] [Fix] doc --- doc/source/sdk/guides/function_graph.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/sdk/guides/function_graph.rst b/doc/source/sdk/guides/function_graph.rst index e630263d1..86b9d4968 100644 --- a/doc/source/sdk/guides/function_graph.rst +++ b/doc/source/sdk/guides/function_graph.rst @@ -278,4 +278,4 @@ Querying the Alias of a Function Version This API is used to query the alias of a function version. .. literalinclude:: ../examples/function_graph/get_alias.py - :lines: 16-47 + :lines: 16-42