Skip to content

Commit

Permalink
Opera update support.
Browse files Browse the repository at this point in the history
Alpha.
  • Loading branch information
sstanovnik committed May 24, 2021
1 parent 9abb920 commit 647c150
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 3 deletions.
36 changes: 35 additions & 1 deletion openapi-spec.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
openapi: "3.0.0"
info:
version: 0.5.0
version: 0.5.1
title: xOpera API
license:
name: Apache-2.0
Expand Down Expand Up @@ -102,6 +102,26 @@ paths:
$ref: "#/components/schemas/DeploymentOutput"
"404":
description: No outputs exist for this deployment.
/update:
post:
summary: Do an update
operationId: update
requestBody:
description: Update inputs
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/UpdateRequest"
responses:
"202":
description: Update successfully initiated.
content:
application/json:
schema:
$ref: "#/components/schemas/Invocation"
"500":
description: There was an error initiating the update.
/validate:
post:
deprecated: true
Expand Down Expand Up @@ -424,6 +444,7 @@ components:
- deploy
- undeploy
- notify
- update
OperationSuccess:
description: A general success message.
type: object
Expand Down Expand Up @@ -472,3 +493,16 @@ components:
type: string
csar:
type: string
UpdateRequest:
description: Update request.
type: object
required:
- inputs
- newServiceTemplateContents
properties:
inputs:
type: object
newServiceTemplateContents:
description: The contents of the new service template.
type: string
format: bytes
24 changes: 24 additions & 0 deletions src/opera/api/controllers/background_invocation.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,12 @@
from typing import List, Optional

from opera.commands.deploy import deploy_service_template as opera_deploy
from opera.commands.diff import diff_instances as opera_diff_instances
from opera.commands.notify import notify as opera_notify
from opera.commands.undeploy import undeploy as opera_undeploy
from opera.commands.update import update as opera_update
from opera.compare.instance_comparer import InstanceComparer
from opera.compare.template_comparer import TemplateComparer
from opera.storage import Storage

from opera.api.log import get_logger
Expand Down Expand Up @@ -53,6 +57,8 @@ def _run_internal(work_queue: multiprocessing.Queue):
elif inv.operation == OperationType.NOTIFY:
# we abuse service_template and inputs a bit, but they match
InvocationWorkerProcess._notify(inv.service_template, inv.inputs)
elif inv.operation == OperationType.DEPLOY:
InvocationWorkerProcess._update(inv.service_template, inv.inputs, num_workers=1)
else:
raise RuntimeError("Unknown operation type:" + str(inv.operation))

Expand Down Expand Up @@ -95,6 +101,24 @@ def _notify(event_name: str, notification_contents: Optional[str]):
opera_notify(opera_storage, verbose_mode=True,
trigger_name_or_event=event_name, notification_file_contents=notification_contents)

@staticmethod
def _update(service_template: str, inputs: typing.Optional[dict], num_workers: int):
original_storage = Storage.create()

new_storage = Storage.create(instance_path=".opera-api-update")
new_storage.write_json(inputs, "inputs")
new_storage.write(service_template, "root_file")

instance_diff = opera_diff_instances(
original_storage, ".", new_storage, ".",
TemplateComparer(), InstanceComparer(), True
)

opera_update(
original_storage, ".", new_storage, ".",
InstanceComparer(), instance_diff, True, num_workers, overwrite=True
)

@staticmethod
def read_file(filename):
with open(filename, "r") as f:
Expand Down
19 changes: 17 additions & 2 deletions src/opera/api/controllers/default.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import tempfile
import traceback
from datetime import datetime
from pathlib import PurePath

from opera.commands.diff import diff_instances as opera_diff_instances
Expand All @@ -18,7 +19,7 @@
from opera.api.controllers.background_invocation import InvocationService
from opera.api.log import get_logger
from opera.api.openapi.models import ValidationResult, OperationType, CsarInitializationInput, PackagingInput, \
UnpackagingInput, PackagingResult, Info, CsarValidationInput, DiffRequest, Diff
UnpackagingInput, PackagingResult, Info, CsarValidationInput, DiffRequest, Diff, UpdateRequest
from opera.api.openapi.models.deployment_input import DeploymentInput

logger = get_logger(__name__)
Expand All @@ -33,7 +34,7 @@ def deploy(body: DeploymentInput = None):
deployment_input = DeploymentInput.from_dict(body)
result = invocation_service.invoke(OperationType.DEPLOY, deployment_input.service_template,
deployment_input.inputs, deployment_input.clean_state)
return result, 200
return result, 202


def diff(body: dict = None):
Expand Down Expand Up @@ -208,3 +209,17 @@ def unpackage(unpackaging_input: UnpackagingInput):
return {"success": True, "message": ""}, 200
except Exception as e:
return {"success": False, "message": "General error: {}".format(str(e))}, 500


def update(body: dict = None): # noqa: E501
logger.debug("Entry: update")
update_request = UpdateRequest.from_dict(body)

posixnow = int(datetime.utcnow().timestamp())
with open("st-operaapi-update-{}.yml".format(posixnow)) as new_st_file:
new_st_file.write(update_request.new_service_template_contents)
new_st_filename = new_st_file.name

result = invocation_service.invoke(OperationType.UPDATE, new_st_filename, update_request.inputs, False)

return result, 202

0 comments on commit 647c150

Please sign in to comment.