# exit(1)
+#################
+# Subscription operations
+#################
+
+
+@cli_osm.command(
+ name="subscription-create",
+ short_help="creates a new subscription to a specific event",
+)
+@click.option(
+ "--event_type",
+ # type=click.Choice(['ns', 'nspkg', 'vnfpkg'], case_sensitive=False))
+ type=click.Choice(["ns"], case_sensitive=False),
+ help="event type to be subscribed (for the moment, only ns is supported)",
+)
+@click.option("--event", default=None, help="specific yaml configuration for the event")
+@click.option(
+ "--event_file", default=None, help="specific yaml configuration file for the event"
+)
+@click.pass_context
+def subscription_create(ctx, event_type, event, event_file):
+ """creates a new subscription to a specific event"""
+ logger.debug("")
+ check_client_version(ctx.obj, ctx.command.name)
+ if event_file:
+ if event:
+ raise ClientException(
+ '"--event" option is incompatible with "--event_file" option'
+ )
+ with open(event_file, "r") as cf:
+ event = cf.read()
+ ctx.obj.subscription.create(event_type, event)
+
+
+@cli_osm.command(name="subscription-delete", short_help="deletes a subscription")
+@click.option(
+ "--event_type",
+ # type=click.Choice(['ns', 'nspkg', 'vnfpkg'], case_sensitive=False))
+ type=click.Choice(["ns"], case_sensitive=False),
+ help="event type to be subscribed (for the moment, only ns is supported)",
+)
+@click.argument("subscription_id")
+@click.option(
+ "--force", is_flag=True, help="forces the deletion bypassing pre-conditions"
+)
+@click.pass_context
+def subscription_delete(ctx, event_type, subscription_id, force):
+ """deletes a subscription
+
+ SUBSCRIPTION_ID: ID of the subscription to be deleted
+ """
+ logger.debug("")
+ check_client_version(ctx.obj, ctx.command.name)
+ ctx.obj.subscription.delete(event_type, subscription_id, force)
+
+
+@cli_osm.command(name="subscription-list", short_help="list all subscriptions")
+@click.option(
+ "--event_type",
+ # type=click.Choice(['ns', 'nspkg', 'vnfpkg'], case_sensitive=False))
+ type=click.Choice(["ns"], case_sensitive=False),
+ help="event type to be subscribed (for the moment, only ns is supported)",
+)
+@click.option(
+ "--filter",
+ default=None,
+ multiple=True,
+ help="restricts the list to the subscriptions matching the filter",
+)
+@click.pass_context
+def subscription_list(ctx, event_type, filter):
+ """list all subscriptions"""
+ logger.debug("")
+ check_client_version(ctx.obj, ctx.command.name)
+ if filter:
+ filter = "&".join(filter)
+ resp = ctx.obj.subscription.list(event_type, filter)
+ table = PrettyTable(["id", "filter", "CallbackUri"])
+ for sub in resp:
+ table.add_row(
+ [
+ sub["_id"],
+ wrap_text(text=json.dumps(sub["filter"], indent=2), width=70),
+ sub["CallbackUri"],
+ ]
+ )
+ table.align = "l"
+ print(table)
+
+
+@cli_osm.command(
+ name="subscription-show", short_help="shows the details of a subscription"
+)
+@click.argument("subscription_id")
+@click.option(
+ "--event_type",
+ # type=click.Choice(['ns', 'nspkg', 'vnfpkg'], case_sensitive=False))
+ type=click.Choice(["ns"], case_sensitive=False),
+ help="event type to be subscribed (for the moment, only ns is supported)",
+)
+@click.option(
+ "--filter",
+ multiple=True,
+ help="restricts the information to the fields in the filter",
+)
+@click.pass_context
+def subscription_show(ctx, event_type, subscription_id, filter):
+ """shows the details of a subscription
+
+ SUBSCRIPTION_ID: ID of the subscription
+ """
+ logger.debug("")
+ # try:
+ resp = ctx.obj.subscription.get(subscription_id)
+ table = PrettyTable(["key", "attribute"])
+ for k, v in list(resp.items()):
+ if not filter or k in filter:
+ table.add_row([k, wrap_text(text=json.dumps(v, indent=2), width=100)])
+ table.align = "l"
+ print(table)
+
+
####################
# Other operations
####################
from osmclient.sol005 import vca
from osmclient.sol005 import repo
from osmclient.sol005 import osmrepo
+from osmclient.sol005 import subscription
from osmclient.common import package_tool
import json
import logging
self.repo = repo.Repo(self._http_client, client=self)
self.osmrepo = osmrepo.OSMRepo(self._http_client, client=self)
self.package_tool = package_tool.PackageTool(client=self)
+ self.subscription = subscription.Subscription(self._http_client, client=self)
"""
self.vca = vca.Vca(http_client, client=self, **kwargs)
self.utils = utils.Utils(http_client, **kwargs)
--- /dev/null
+#
+# 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.
+#
+
+"""
+OSM Subscription API handling
+"""
+
+from osmclient.common.exceptions import NotFound
+from osmclient.common.exceptions import ClientException
+import yaml
+import json
+import logging
+
+
+class Subscription(object):
+ def __init__(self, http=None, client=None):
+ self._http = http
+ self._client = client
+ self._logger = logging.getLogger("osmclient")
+ self._apiName = "/nslcm"
+ self._apiVersion = "/v1"
+ self._apiResource = "/subscriptions"
+ self._apiBase = "{}{}{}".format(
+ self._apiName, self._apiVersion, self._apiResource
+ )
+
+ def _rebuild_apibase(self, event_type):
+ self._logger.debug("")
+ if event_type == "ns":
+ self._apiName = "/nslcm"
+ else:
+ raise ClientException("unsupported event_type {}".format(event_type))
+ self._apiBase = "{}{}{}".format(
+ self._apiName, self._apiVersion, self._apiResource
+ )
+
+ def create(self, event_type, event):
+ """
+ Creates a subscription
+ :param event_type: event type to be subscribed (only ns is supported)
+ :param event: yaml string defining the event to be subscribed
+ :return: None. Exception if fail
+ """
+ self._logger.debug("")
+ self._client.get_token()
+ self._rebuild_apibase(event_type)
+
+ subscription_event = yaml.safe_load(event)
+
+ http_code, resp = self._http.post_cmd(
+ endpoint=self._apiBase, postfields_dict=subscription_event
+ )
+ if resp:
+ resp = json.loads(resp)
+ if not resp or "id" not in resp:
+ raise ClientException("unexpected response from server - {}".format(resp))
+ print(resp["id"])
+
+ def delete(self, event_type, subscription_id, force=False):
+ """
+ Deletes a subscription
+ :param event_type: event type to be subscribed (only ns is supported)
+ :param subscription_id: identifier of the subscription
+ :param force: forces deletion
+ :return: None. Exception if fail
+ """
+ self._logger.debug("")
+ self._client.get_token()
+ self._rebuild_apibase(event_type)
+ querystring = ""
+ if force:
+ querystring = "?FORCE=True"
+ http_code, resp = self._http.delete_cmd(
+ "{}/{}{}".format(self._apiBase, subscription_id, querystring)
+ )
+ if http_code == 202:
+ print("Deletion in progress")
+ elif http_code == 204:
+ print("Deleted")
+ else:
+ msg = resp or ""
+ raise ClientException(
+ "failed to delete subscription {} - {}".format(subscription_id, msg)
+ )
+
+ def list(self, event_type, filter=None):
+ """
+ Returns a list of subscriptions
+ :param event_type: event type to be subscribed (only ns is supported)
+ :param filter
+ :return: list of subscriptions
+ """
+ self._logger.debug("")
+ self._client.get_token()
+ self._rebuild_apibase(event_type)
+ filter_string = ""
+ if filter:
+ filter_string = "?{}".format(filter)
+ _, resp = self._http.get2_cmd("{}{}".format(self._apiBase, filter_string))
+ if resp:
+ return json.loads(resp)
+ return list()
+
+ def get(self, event_type, subscription_id):
+ """
+ Returns a subscription from a subscription id
+ :param event_type: event type to be subscribed (only ns is supported)
+ :param subscription_id: identifier of the subscription
+ :return: dict with the subscription
+ """
+ self._logger.debug("")
+ self._client.get_token()
+ self._rebuild_apibase(event_type)
+ try:
+ _, resp = self._http.get2_cmd(
+ "{}/{}".format(self._apiBase, subscription_id)
+ )
+ self._logger.debug(yaml.safe_dump(resp))
+ if resp:
+ return json.loads(resp)
+ if not resp or "id" not in resp:
+ raise ClientException(
+ "failed to get subscription info: {}".format(resp)
+ )
+ return resp
+ except NotFound:
+ raise NotFound("subscription '{}' not found".format(subscription_id))