.mypy_cache
__pycache__
*.egg-info
+*.pyc
+.tox
\ No newline at end of file
FROM python:3.10-slim-buster\r
\r
+RUN apt-get update; apt-get install -y git gcc\r
COPY requirements.txt /tmp/\r
-RUN pip install -r /tmp/requirements.txt\r
+COPY constraints.txt /tmp/\r
+\r
+RUN pip install -r /tmp/requirements.txt -c /tmp/constraints.txt\r
\r
COPY requirements-test.txt /tmp/\r
RUN pip install -r /tmp/requirements-test.txt\r
\r
RUN mkdir -p /src\r
-COPY src/ /src/\r
+COPY o2ims/ /src/o2ims/\r
+COPY o2dms/ /src/o2dms/\r
+COPY o2common/ /src/o2common/\r
+COPY setup.py /src/\r
+\r
RUN pip install -e /src\r
\r
COPY tests/ /tests/\r
--- /dev/null
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
docker-compose build\r
```\r
\r
-\r
-## Creating a local virtualenv (optional)\r
-\r
-```sh\r
-python3.8 -m venv .venv && source .venv/bin/activate\r
-pip install -r requirements.txt\r
-pip install -e src/\r
-```\r
-\r
## Running the tests\r
\r
```sh\r
docker-compose up -d\r
docker-compose run --rm --no-deps --entrypoint=pytest api /tests/unit /tests/integration\r
-pytest tests/unit\r
-pytest tests/integration\r
-pytest tests/e2e\r
```\r
\r
## Tear down containers\r
```sh\r
docker-compose down --remove-orphans\r
```\r
+\r
+## Test with local virtualenv\r
+\r
+```sh\r
+python3.8 -m venv .venv && source .venv/bin/activate\r
+pip install -r requirements.txt -c constraints.txt\r
+pip install -r requirements-test.txt\r
+pip install -e o2ims\r
+# pip install -e o2dms -e o2common\r
+pytest tests/unit\r
+pytest tests/integration\r
+pytest tests/e2e\r
+```\r
--- /dev/null
+# -e git+https://opendev.org/starlingx/distcloud-client.git@master#egg=distributedcloud-client&subdirectory=distributedcloud-client
+# -e git+https://opendev.org/starlingx/config.git@master#egg=cgtsclient&subdirectory=sysinv/cgts-client/cgts-client
+cryptography==3.3.2
+python-keystoneclient==3.21.0
\ No newline at end of file
- REDIS_HOST=redis
- PYTHONDONTWRITEBYTECODE=1
volumes:
- - ./src:/src
+ - ./o2ims:/o2ims
+ - ./o2dms:/o2dms
+ - ./o2common:/o2common
- ./tests:/tests
entrypoint:
- python
- - /src/o2ims/entrypoints/redis_eventconsumer.py
+ - /o2ims/entrypoints/redis_eventconsumer.py
api:
image: o2imsdms-image
- API_HOST=api
- REDIS_HOST=redis
- PYTHONDONTWRITEBYTECODE=1
- - FLASK_APP=o2ims/entrypoints/flask_application.py
+ - FLASK_APP=/o2ims/entrypoints/flask_application.py
- FLASK_DEBUG=1
- PYTHONUNBUFFERED=1
+ - STX_AUTH_URL=http://192.168.204.1:5000/v3
+ - STX_USERNAME=admin
+ - STX_PASSWORD=password1
volumes:
- - ./src:/src
+ - ./o2ims:/o2ims
+ - ./o2dms:/o2dms
+ - ./o2common:/o2common
- ./tests:/tests
entrypoint:
- flask
--- /dev/null
+# Copyright (C) 2021 Wind River Systems, Inc.\r
+#\r
+# Licensed under the Apache License, Version 2.0 (the "License");\r
+# you may not use this file except in compliance with the License.\r
+# You may obtain a copy of the License at\r
+#\r
+# http://www.apache.org/licenses/LICENSE-2.0\r
+#\r
+# Unless required by applicable law or agreed to in writing, software\r
+# distributed under the License is distributed on an "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+# See the License for the specific language governing permissions and\r
+# limitations under the License.\r
+\r
+# client talking to Stx standalone\r
+\r
+from service.client.base_client import BaseClient\r
+from typing import List\r
+# Optional, Set\r
+from o2ims.domain import stx_object as ocloudModel\r
+from o2ims import config\r
+\r
+\r
+class StxSaOcloudClient(BaseClient):\r
+ def __init__(self):\r
+ super().__init__()\r
+ self.driver = StxSaClientImp()\r
+\r
+ # def list(self) -> List[ocloudModel.StxGenericModel]:\r
+ # return self._list()\r
+\r
+ # def get(self, id) -> ocloudModel.StxGenericModel:\r
+ # return self._get(id)\r
+\r
+ def _get(self, id) -> ocloudModel.StxGenericModel:\r
+ raise self.driver.getInstanceInfo()\r
+\r
+ def _list(self):\r
+ return [self.driver.getInstanceInfo()]\r
+\r
+\r
+class StxSaResourcePoolClient(BaseClient):\r
+ def __init__(self):\r
+ super().__init__()\r
+ self.driver = StxSaClientImp()\r
+\r
+ def _get(self, id) -> ocloudModel.StxGenericModel:\r
+ return self.driver.getInstanceInfo()\r
+\r
+ def _list(self):\r
+ return [self.driver.getInstanceInfo()]\r
+\r
+\r
+class StxSaDmsClient(BaseClient):\r
+ def __init__(self):\r
+ super().__init__()\r
+ self.driver = StxSaClientImp()\r
+\r
+ def _get(self, id) -> ocloudModel.StxGenericModel:\r
+ return self.driver.getK8sDetail(id)\r
+\r
+ def _list(self):\r
+ return self.driver.getK8sList()\r
+\r
+# internal driver which implement client call to Stx Standalone instance\r
+\r
+# from keystoneauth1.identity import v3\r
+# from keystoneauth1 import session\r
+# # from keystoneclient.v3 import ksclient\r
+# from starlingxclient.v3 import stxclient\r
+\r
+\r
+class StxSaClientImp(object):\r
+ def __init__(self, access_info=None) -> None:\r
+ super().__init__()\r
+ self.access_info = access_info\r
+ if self.access_info is None:\r
+ self.access_info = config.get_stx_access_info()\r
+ # self.auth = auth = v3.Password(\r
+ # auth_url="http://example.com:5000/v3", username="admin",\r
+ # password="password", project_name="admin",\r
+ # user_domain_id="default", project_domain_id="default")\r
+ # self.session = sess = session.Session(auth=auth)\r
+ # # self.keystone = ksclient.Client(session=sess)\r
+ # self.stx = stxclient.Client(session=sess)\r
+\r
+ def getInstanceInfo(self) -> ocloudModel.StxGenericModel:\r
+ raise NotImplementedError\r
+\r
+ def getK8sList(self) -> List[ocloudModel.StxGenericModel]:\r
+ raise NotImplementedError\r
+\r
+ def getK8sDetail(self, id) -> ocloudModel.StxGenericModel:\r
+ raise NotImplementedError\r
--- /dev/null
+# Copyright (C) 2021 Wind River Systems, Inc.\r
+#\r
+# Licensed under the Apache License, Version 2.0 (the "License");\r
+# you may not use this file except in compliance with the License.\r
+# You may obtain a copy of the License at\r
+#\r
+# http://www.apache.org/licenses/LICENSE-2.0\r
+#\r
+# Unless required by applicable law or agreed to in writing, software\r
+# distributed under the License is distributed on an "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+# See the License for the specific language governing permissions and\r
+# limitations under the License.\r
+\r
+# from datetime import datetime\r
+import logging\r
+\r
+from sqlalchemy import (\r
+ Table,\r
+ MetaData,\r
+ Column,\r
+ # Integer,\r
+ String,\r
+ # Date,\r
+ DateTime,\r
+ # ForeignKey,\r
+ # event,\r
+)\r
+\r
+from sqlalchemy.orm import mapper\r
+# from sqlalchemy.sql.expression import true\r
+\r
+from o2ims.domain import stx_object as ocloudModel\r
+\r
+logger = logging.getLogger(__name__)\r
+\r
+metadata = MetaData()\r
+\r
+stxobject = Table(\r
+ "stxcache",\r
+ metadata,\r
+ Column("id", String(255), primary_key=True),\r
+ Column("name", String(255)),\r
+ Column("lastupdate", DateTime),\r
+ Column("content", String(255))\r
+)\r
+\r
+\r
+def start_o2ims_stx_mappers():\r
+ logger.info("Starting O2 IMS Stx mappers")\r
+ mapper(ocloudModel.StxGenericModel, stxobject)\r
# pylint: disable=too-few-public-methods
import abc
-import smtplib
from o2ims import config
+SMO_O2_ENDPOINT = config.get_smo_o2endpoint()
+
+
class AbstractNotifications(abc.ABC):
@abc.abstractmethod
def send(self, message):
raise NotImplementedError
-SMO_O2_ENDPOINT = config.get_smo_o2endpoint()
-
class SmoO2Notifications(AbstractNotifications):
def __init__(self, smoO2Endpoint=SMO_O2_ENDPOINT):
self.smoO2Endpoint = smoO2Endpoint
import abc
from typing import Set
-from o2ims.adapter import orm
+# from o2ims.adapter import orm
from o2ims.domain import ocloud
+
class OcloudRepository(abc.ABC):
def __init__(self):
self.seen = set() # type: Set[ocloud.Ocloud]
if ocloud:
self.seen.add(ocloud)
return ocloud
-
+
def update(self, ocloud: ocloud.Ocloud):
self._update(ocloud)
# self.session.add_all(ocloud.deploymentManagers)
def _get(self, ocloudid) -> ocloud.Ocloud:
- return self.session.query(ocloud.Ocloud).filter_by(oCloudId=ocloudid).first()
+ return self.session.query(ocloud.Ocloud).filter_by(
+ oCloudId=ocloudid).first()
def _update(self, ocloud: ocloud.Ocloud):
self.session.add(ocloud)
# if dmslist:
# self._update_dms_list(dmslist)
# if updatefields:
- # self.session.query(ocloud.Ocloud).filter_by(oCloudId=ocloudid).update(updatefields)
+ # self.session.query(ocloud.Ocloud).filter_by(
+ # oCloudId=ocloudid).update(updatefields)
# def _update_dms_list(self, dms_list: list):
# for dms in dms_list or []:
- # self.session.query(ocloud.DeploymentManager).filter_by(deploymentManagerId=dms.deploymentManagerId).update(dms)
+ # self.session.query(ocloud.DeploymentManager).filter_by(
+ # deploymentManagerId=dms.deploymentManagerId).update(dms)
Table,\r
MetaData,\r
Column,\r
- Integer,\r
+ # Integer,\r
String,\r
- Date,\r
+ # Date,\r
ForeignKey,\r
- event,\r
+ # event,\r
)\r
\r
from sqlalchemy.orm import mapper, relationship\r
-from sqlalchemy.sql.expression import true\r
+# from sqlalchemy.sql.expression import true\r
\r
from o2ims.domain import ocloud as ocloudModel\r
\r
dm_mapper = mapper(ocloudModel.DeploymentManager, deploymentmanager)\r
resourcepool_mapper = mapper(ocloudModel.ResourcePool, resourcepool)\r
resourcetype_mapper = mapper(ocloudModel.ResourceType, resourcetype)\r
- resource_mapper = mapper(ocloudModel.Resource, resource)\r
- ocloud_mapper = mapper(\r
+ # resource_mapper = mapper(ocloudModel.Resource, resource)\r
+ mapper(\r
ocloudModel.Ocloud,\r
ocloud,\r
properties={\r
import inspect
from typing import Callable
from o2ims.adapter import orm, redis_eventpublisher
-from o2ims.adapter.notifications import AbstractNotifications, SmoO2Notifications
+from o2ims.adapter.notifications import AbstractNotifications,\
+ SmoO2Notifications
from o2ims.service import handlers, messagebus, unit_of_work
if start_orm:
orm.start_o2ims_mappers()
- dependencies = {"uow": uow, "notifications": notifications, "publish": publish}
+ dependencies = {"uow": uow, "notifications": notifications,
+ "publish": publish}
injected_event_handlers = {
event_type: [
inject_dependencies(handler, dependencies)
import os
+
def get_postgres_uri():
host = os.environ.get("DB_HOST", "localhost")
port = 54321 if host == "localhost" else 5432
port = 5005 if host == "localhost" else 80
return f"http://{host}:{port}"
+
def get_o2ims_api_base():
return '/o2ims_infrastructureInventory/v1'
+
def get_redis_host_and_port():
host = os.environ.get("REDIS_HOST", "localhost")
port = 63791 if host == "localhost" else 6379
def get_smo_o2endpoint():
- smo_o2endpoint = os.environ.get("SMO_O2_ENDPOINT", "http://localhost/smo_sim")
+ smo_o2endpoint = os.environ.get(
+ "SMO_O2_ENDPOINT", "http://localhost/smo_sim")
return smo_o2endpoint
+
+
+def get_stx_access_info():
+ authurl = os.environ.get("STX_AUTH_URL", "http://192.168.204.1:5000/v3")
+ username = os.environ.get("STX_USERNAME", "admin")
+ pswd = os.environ.get("STX_PASSWORD", "passwd1")
+ stx_access_info = (authurl, username, pswd)
+ return stx_access_info
# limitations under the License.
# pylint: disable=too-few-public-methods
-from datetime import date
-from typing import Optional
+# from datetime import date
+# from typing import Optional
from dataclasses import dataclass
class Command:
pass
+
+@dataclass
class UpdateDms(Command):
- ref: str
\ No newline at end of file
+ ref: str
# pylint: disable=too-few-public-methods
from dataclasses import dataclass
+
class Event:
pass
+
@dataclass
class OcloudUpdated(Event):
oCloudId: str
# limitations under the License.\r
\r
from __future__ import annotations\r
-from dataclasses import dataclass\r
-from datetime import date\r
-from typing import Optional, List, Set\r
+# from dataclasses import dataclass\r
+# from datetime import date\r
+# from typing import Optional, List, Set\r
from .resource_type import ResourceTypeEnum\r
# from uuid import UUID\r
\r
-class Ocloud:\r
- def __init__(\r
- self, ocloudid: str, name: str, imsendpoint: str,\r
- description: str = '', version_number: int = 0) -> None:\r
-\r
- self.oCloudId = ocloudid\r
- self.version_number = version_number\r
- self.name = name\r
- self.description = description\r
- self.infrastructureManagementServiceEndpoint = imsendpoint\r
- self.resourcePools = []\r
- self.deploymentManagers = []\r
- self.resourceTypes = []\r
- self.extensions = []\r
- self.events = []\r
- \r
- def addDeploymentManager(self, deploymentManager: DeploymentManager) -> None:\r
- deploymentManager.oCloudId = self.oCloudId\r
- old = filter(\r
- lambda x: x.deploymentManagerId == deploymentManager.deploymentManagerId,\r
- self.deploymentManagers)\r
- for o in old or []:\r
- self.deploymentManagers.remove(o)\r
- self.deploymentManagers.append(deploymentManager)\r
\r
class DeploymentManager:\r
- def __init__(self, id: str, name: str, ocloudid: str, dmsendpoint: str) -> None:\r
+ def __init__(self, id: str, name: str, ocloudid: str,\r
+ dmsendpoint: str) -> None:\r
self.deploymentManagerId = id\r
self.name = name\r
self.oCloudId = ocloudid\r
\r
\r
class ResourcePool:\r
- def __init__(self, id: str, name: str, location: str, ocloudid: str) -> None:\r
+ def __init__(self, id: str, name: str, location: str,\r
+ ocloudid: str) -> None:\r
self.resourcePoolId = id\r
self.name = name\r
self.location = location\r
\r
\r
class ResourceType:\r
- def __init__(self, typeid: str, name:str, typeEnum: ResourceTypeEnum, ocloudid: str) -> None:\r
+ def __init__(self, typeid: str, name: str, typeEnum: ResourceTypeEnum,\r
+ ocloudid: str) -> None:\r
self.resourceTypeId = typeid\r
self.resourceTypeEnum = typeEnum.value\r
self.name = name\r
\r
\r
class Resource:\r
- def __init__(self, resourceId:str, resourceTypeId: str, resourcePoolId: str) -> None:\r
+ def __init__(self, resourceId: str, resourceTypeId: str,\r
+ resourcePoolId: str) -> None:\r
self.resourceId = resourceId\r
- self.oCloudId = None # tbd\r
+ self.oCloudId = None # tbd\r
self.resourceTypeId = resourceTypeId\r
self.resourcePoolId = resourcePoolId\r
self.parentId = None\r
self.elements = []\r
self.extensions = []\r
\r
+\r
+class Ocloud:\r
+ def __init__(self, ocloudid: str, name: str, imsendpoint: str,\r
+ description: str = '', version_number: int = 0) -> None:\r
+\r
+ self.oCloudId = ocloudid\r
+ self.version_number = version_number\r
+ self.name = name\r
+ self.description = description\r
+ self.infrastructureManagementServiceEndpoint = imsendpoint\r
+ self.resourcePools = []\r
+ self.deploymentManagers = []\r
+ self.resourceTypes = []\r
+ self.extensions = []\r
+ self.events = []\r
+\r
+ def addDeploymentManager(self,\r
+ deploymentManager: DeploymentManager):\r
+\r
+ deploymentManager.oCloudId = self.oCloudId\r
+ old = filter(\r
+ lambda x: x.deploymentManagerId ==\r
+ deploymentManager.deploymentManagerId,\r
+ self.deploymentManagers)\r
+ for o in old or []:\r
+ self.deploymentManagers.remove(o)\r
+ self.deploymentManagers.append(deploymentManager)\r
from enum import Enum\r
\r
+\r
class ResourceTypeEnum(Enum):\r
PSERVER = 1\r
PSERVER_CPU = 2\r
--- /dev/null
+# Copyright (C) 2021 Wind River Systems, Inc.\r
+#\r
+# Licensed under the Apache License, Version 2.0 (the "License");\r
+# you may not use this file except in compliance with the License.\r
+# You may obtain a copy of the License at\r
+#\r
+# http://www.apache.org/licenses/LICENSE-2.0\r
+#\r
+# Unless required by applicable law or agreed to in writing, software\r
+# distributed under the License is distributed on an "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+# See the License for the specific language governing permissions and\r
+# limitations under the License.\r
+\r
+# from dataclasses import dataclass\r
+import datetime\r
+\r
+\r
+class StxGenericModel:\r
+ def __init__(self, id: str, name: str,\r
+ lastupdate: datetime, content: str) -> None:\r
+ self.id = id\r
+ self.name = name\r
+ self.lastupdate = lastupdate\r
+ self.content = content\r
+\r
+ def isChanged(self, updatetime: datetime) -> bool:\r
+ return True if self.lastupdate > updatetime else False\r
# See the License for the specific language governing permissions and\r
# limitations under the License.\r
\r
-from datetime import datetime\r
-from flask import Flask, jsonify, request\r
-from o2ims.domain import commands\r
-from o2ims.service.handlers import InvalidResourceType\r
+# from datetime import datetime\r
+from flask import Flask, jsonify\r
+# request\r
+# from o2ims.domain import commands\r
+# from o2ims.service.handlers import InvalidResourceType\r
from o2ims import bootstrap, config\r
from o2ims.views import ocloud_view\r
\r
bus = bootstrap.bootstrap()\r
apibase = config.get_o2ims_api_base()\r
\r
+\r
@app.route(apibase, methods=["GET"])\r
def oclouds():\r
result = ocloud_view.oclouds(bus.uow)\r
--- /dev/null
+# Copyright (C) 2021 Wind River Systems, Inc.\r
+#\r
+# Licensed under the Apache License, Version 2.0 (the "License");\r
+# you may not use this file except in compliance with the License.\r
+# You may obtain a copy of the License at\r
+#\r
+# http://www.apache.org/licenses/LICENSE-2.0\r
+#\r
+# Unless required by applicable law or agreed to in writing, software\r
+# distributed under the License is distributed on an "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+# See the License for the specific language governing permissions and\r
+# limitations under the License.\r
--- /dev/null
+# Copyright (C) 2021 Wind River Systems, Inc.\r
+#\r
+# Licensed under the Apache License, Version 2.0 (the "License");\r
+# you may not use this file except in compliance with the License.\r
+# You may obtain a copy of the License at\r
+#\r
+# http://www.apache.org/licenses/LICENSE-2.0\r
+#\r
+# Unless required by applicable law or agreed to in writing, software\r
+# distributed under the License is distributed on an "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+# See the License for the specific language governing permissions and\r
+# limitations under the License.\r
+\r
+import abc\r
+# from typing import Optional, List, Set\r
+from typing import List\r
+from o2ims.domain import stx_object as ocloudModel\r
+\r
+\r
+class BaseClient(abc.ABC):\r
+ def __init__(self):\r
+ pass\r
+\r
+ def list(self) -> List[ocloudModel.StxGenericModel]:\r
+ return self._list()\r
+\r
+ def get(self, id) -> ocloudModel.StxGenericModel:\r
+ return self._get(id)\r
+\r
+ @abc.abstractmethod\r
+ def _get(self, id) -> ocloudModel.StxGenericModel:\r
+ raise NotImplementedError\r
+\r
+ @abc.abstractmethod\r
+ def _list(self):\r
+ raise NotImplementedError\r
# pylint: disable=unused-argument
from __future__ import annotations
-from dataclasses import asdict
-from typing import List, Dict, Callable, Type, TYPE_CHECKING
-from o2ims.domain import commands, events, ocloud
+# from dataclasses import asdict
+from typing import List, Dict, Callable, Type
+# TYPE_CHECKING
+from o2ims.domain import commands, events
+# ocloud
+
+# if TYPE_CHECKING:
+# from . import unit_of_work
-if TYPE_CHECKING:
- from . import unit_of_work
class InvalidResourceType(Exception):
pass
EVENT_HANDLERS = {
} # type: Dict[Type[events.Event], List[Callable]]
+
COMMAND_HANDLERS = {
} # type: Dict[Type[commands.Command], Callable]
def handle_event(self, event: events.Event):
for handler in self.event_handlers[type(event)]:
try:
- logger.debug("handling event %s with handler %s", event, handler)
+ logger.debug("handling event %s with handler %s",
+ event, handler)
handler(event)
self.queue.extend(self.uow.collect_new_events())
except Exception:
from sqlalchemy.orm import sessionmaker
from sqlalchemy.orm.session import Session
-
from o2ims import config
from o2ims.adapter import ocloud_repository
class AbstractUnitOfWork(abc.ABC):
oclouds: ocloud_repository.OcloudRepository
- def __enter__(self) -> AbstractUnitOfWork:
+ def __enter__(self):
return self
def __exit__(self, *args):
def __enter__(self):
self.session = self.session_factory() # type: Session
- self.oclouds = ocloud_repository.OcloudSqlAlchemyRepository(self.session)
+ self.oclouds = ocloud_repository\
+ .OcloudSqlAlchemyRepository(self.session)
return super().__enter__()
def __exit__(self, *args):
+flake8\r
pylint\r
mypy\r
requests\r
+tox\r
\r
pytest\r
pytest-icdiff\r
\r
tenacity\r
+\r
+# -e git+https://opendev.org/starlingx/distcloud-client.git@master#egg=distributedcloud-client&subdirectory=distributedcloud-client\r
+# -e git+https://opendev.org/starlingx/config.git@master#egg=cgtsclient&subdirectory=sysinv/cgts-client/cgts-client\r
sqlalchemy\r
redis\r
psycopg2-binary\r
+\r
+Cython>=3.0a1\r
+\r
+# -e git+https://opendev.org/starlingx/distcloud-client.git@master#egg=distributedcloud-client&subdirectory=distributedcloud-client\r
+# -e git+https://opendev.org/starlingx/config.git@master#egg=cgtsclient&subdirectory=sysinv/cgts-client/cgts-client#\r
--- /dev/null
+from setuptools import setup\r
+from setuptools import find_packages\r
+\r
+setup(\r
+ name="o2imsdms",\r
+ version="1.0",\r
+ packages=find_packages(),\r
+ license="LICENSE",\r
+ description="Represent O2 IMS and O2 DMS",\r
+ install_requires=[\r
+ 'httplib2',\r
+ # 'distributedcloud-client',\r
+ # 'cgtsclient',\r
+ 'babel', # Required by distributedcloud-client\r
+ 'PrettyTable<0.8,>=0.7.2', # Required by distributedcloud-client\r
+ ]\r
+)\r
+++ /dev/null
-from setuptools import setup\r
-\r
-setup(\r
- name="o2common",\r
- version="1.0",\r
- packages=["o2common"],\r
-)\r
-\r
-setup(\r
- name="o2ims",\r
- version="1.0",\r
- packages=["o2ims"],\r
-)\r
-\r
-setup(\r
- name="o2dms",\r
- version="1.0",\r
- packages=["o2dms"],\r
-)\r
+++ /dev/null
-from setuptools import setup\r
-\r
-setup(\r
- name="o2imsdms",\r
- version="1.0",\r
- packages=["o2ims", "o2dms", "o2common"],\r
-)\r
--- /dev/null
+# Copyright (C) 2021 Wind River Systems, Inc.\r
+#\r
+# Licensed under the Apache License, Version 2.0 (the "License");\r
+# you may not use this file except in compliance with the License.\r
+# You may obtain a copy of the License at\r
+#\r
+# http://www.apache.org/licenses/LICENSE-2.0\r
+#\r
+# Unless required by applicable law or agreed to in writing, software\r
+# distributed under the License is distributed on an "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+# See the License for the specific language governing permissions and\r
+# limitations under the License.\r
--- /dev/null
+# content of: tox.ini , put in same dir as setup.py\r
+[tox]\r
+envlist=flake8,code\r
+\r
+minversion = 1.6\r
+skipsdist = True\r
+\r
+[testenv]\r
+basepython =\r
+ code: python3.8\r
+ flake8: python3.8\r
+setenv =\r
+ VIRTUAL_ENV={envdir}\r
+\r
+# NOTE: relative paths were used due to '-w' flag for nosetests util\r
+\r
+usedevelop = True\r
+install_command = pip install -U {opts} {packages}\r
+deps = -r{toxinidir}/requirements.txt\r
+ -r{toxinidir}/requirements-test.txt\r
+whitelist_externals = bash, flake8, pytest\r
+\r
+[testenv:flake8]\r
+commands =\r
+ flake8 o2ims\r
+ flake8 o2dms\r
+ flake8 o2common\r
+\r
+[testenv:code]\r
+commands =\r
+ pytest tests\r
+\r
+[testenv:nosetests]\r
+commands =\r
+ pytest tests\r