Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
LSO
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
This is an archived project. Repository and other project resources are read-only.
Show more breadcrumbs
GÉANT Orchestration and Automation Team
GAP
LSO
Commits
b46fd0d5
Verified
Commit
b46fd0d5
authored
1 year ago
by
Karel van Klink
Browse files
Options
Downloads
Patches
Plain Diff
replace PlaybookLaunchResponse with a generic JSONResponse
parent
1278d734
No related branches found
No related tags found
No related merge requests found
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
lso/playbook.py
+17
-44
17 additions, 44 deletions
lso/playbook.py
lso/routes/ip_trunk.py
+8
-17
8 additions, 17 deletions
lso/routes/ip_trunk.py
lso/routes/playbook.py
+5
-6
5 additions, 6 deletions
lso/routes/playbook.py
lso/routes/router.py
+3
-4
3 additions, 4 deletions
lso/routes/router.py
with
33 additions
and
71 deletions
lso/playbook.py
+
17
−
44
View file @
b46fd0d5
...
...
@@ -4,7 +4,6 @@ import json
import
logging
import
threading
import
uuid
from
enum
import
StrEnum
,
auto
from
pathlib
import
Path
from
typing
import
Any
...
...
@@ -12,8 +11,9 @@ import ansible_runner
import
requests
import
xmltodict
from
dictdiffer
import
diff
from
fastapi
import
Response
,
status
from
pydantic
import
BaseModel
,
HttpUrl
from
fastapi
import
status
from
fastapi.responses
import
JSONResponse
from
pydantic
import
HttpUrl
from
lso
import
config
from
lso.config
import
DEFAULT_REQUEST_TIMEOUT
...
...
@@ -21,53 +21,29 @@ from lso.config import DEFAULT_REQUEST_TIMEOUT
logger
=
logging
.
getLogger
(
__name__
)
class
PlaybookJobStatus
(
StrEnum
):
"""
Enumerator for status codes of a playbook job that
'
s running.
"""
#: All is well.
OK
=
auto
()
#: An error has occurred.
ERROR
=
auto
()
class
PlaybookLaunchResponse
(
BaseModel
):
"""
Running a playbook gives this response.
:param PlaybookJobStatus status:
:param job_id:
:type job_id: str, optional
:param info:
:type info: str, optional
"""
#: Status of a Playbook job.
status
:
PlaybookJobStatus
#: The ID assigned to a job.
job_id
:
str
=
""
#: Information on a job.
info
:
str
=
""
def
get_playbook_path
(
playbook_name
:
str
)
->
Path
:
"""
Get the path of a playbook on the local filesystem.
"""
config_params
=
config
.
load
()
return
Path
(
config_params
.
ansible_playbooks_root_dir
)
/
playbook_name
def
playbook_launch_success
(
job_id
:
str
)
->
PlaybookLaunch
Response
:
def
playbook_launch_success
(
job_id
:
str
)
->
JSON
Response
:
"""
Return a :class:`PlaybookLaunchResponse` for the successful start of a playbook execution.
:return
PlaybookLaunch
Response: A playbook launch response that
'
s successful.
:return
JSON
Response: A playbook launch response that
'
s successful.
"""
return
PlaybookLaunchResponse
(
status
=
PlaybookJobStatus
.
OK
,
job_id
=
job_id
)
return
JSONResponse
(
content
=
{
"
job_id
"
:
job_id
},
status_code
=
status
.
HTTP_201_CREATED
)
def
playbook_launch_error
(
reason
:
str
)
->
PlaybookLaunch
Response
:
def
playbook_launch_error
(
reason
:
str
,
status_code
:
int
=
status
.
HTTP_400_BAD_REQUEST
)
->
JSON
Response
:
"""
Return a :class:`PlaybookLaunchResponse` for the erroneous start of a playbook execution.
:return PlaybookLaunchResponse: A playbook launch response that
'
s unsuccessful.
:param str reason: The reason why a request has failed.
:param status status_code: The HTTP status code that should be associated with this request. Defaults to HTTP 400
"
Bad request
"
.
:return JSONResponse: A playbook launch response that
'
s unsuccessful.
"""
return
PlaybookLaunchResponse
(
status
=
PlaybookJobStatus
.
ERROR
,
info
=
reason
)
return
JSONResponse
(
content
=
{
"
error
"
:
reason
},
status_code
=
status_code
)
def
_process_json_output
(
runner
:
ansible_runner
.
Runner
)
->
list
[
dict
[
Any
,
Any
]]:
# ignore: C901
...
...
@@ -151,7 +127,7 @@ def _run_playbook_proc(
:param str job_id: Identifier of the job that
'
s executed.
:param str playbook_path: Ansible playbook to be executed.
:param dict extra_vars: Extra variables passed to the Ansible playbook.
:param str callback: Callback URL to
PUT
to when execution is completed.
:param str callback: Callback URL to
return output
to when execution is completed.
:param dict[str, Any] | str inventory: Ansible inventory to run the playbook against.
"""
ansible_playbook_run
=
ansible_runner
.
run
(
...
...
@@ -181,8 +157,7 @@ def run_playbook(
extra_vars
:
dict
[
str
,
Any
],
inventory
:
dict
[
str
,
Any
]
|
str
,
callback
:
HttpUrl
,
response
:
Response
,
)
->
PlaybookLaunchResponse
:
)
->
JSONResponse
:
"""
Run an Ansible playbook against a specified inventory.
:param Path playbook_path: playbook to be executed.
...
...
@@ -191,17 +166,15 @@ def run_playbook(
:param :class:`HttpUrl` callback: Callback URL where the playbook should send a status update when execution is
completed. This is used for workflow-orchestrator to continue with the next step in a workflow.
:return: Result of playbook launch, this could either be successful or unsuccessful.
:rtype: :class:`
PlaybookLaunch
Response`
:rtype: :class:`
fastapi.responses.JSON
Response`
"""
if
not
Path
.
exists
(
playbook_path
):
response
.
status_code
=
status
.
HTTP_404_NOT_FOUND
msg
=
f
"
Filename
'
{
playbook_path
}
'
does not exist.
"
return
playbook_launch_error
(
msg
)
return
playbook_launch_error
(
reason
=
msg
,
status_code
=
status
.
HTTP_404_NOT_FOUND
)
if
not
ansible_runner
.
utils
.
isinventory
(
inventory
):
response
.
status_code
=
status
.
HTTP_400_BAD_REQUEST
msg
=
"
Invalid inventory provided. Should be a string, or JSON object.
"
return
playbook_launch_error
(
msg
)
return
playbook_launch_error
(
reason
=
msg
,
status_code
=
status
.
HTTP_400_BAD_REQUEST
)
job_id
=
str
(
uuid
.
uuid4
())
thread
=
threading
.
Thread
(
...
...
This diff is collapsed.
Click to expand it.
lso/routes/ip_trunk.py
+
8
−
17
View file @
b46fd0d5
"""
Routes for handling events related to the IP trunk service.
"""
from
fastapi
import
APIRouter
,
Response
from
fastapi
import
APIRouter
from
fastapi.responses
import
JSONResponse
from
pydantic
import
BaseModel
,
HttpUrl
from
lso.playbook
import
PlaybookLaunchResponse
,
get_playbook_path
,
run_playbook
from
lso.playbook
import
get_playbook_path
,
run_playbook
router
=
APIRouter
()
...
...
@@ -72,7 +73,7 @@ class IPTrunkDeleteParams(IPTrunkParams):
@router.post
(
"
/
"
)
def
provision_ip_trunk
(
params
:
IPTrunkProvisioningParams
,
response
:
Response
)
->
PlaybookLaunch
Response
:
def
provision_ip_trunk
(
params
:
IPTrunkProvisioningParams
)
->
JSON
Response
:
"""
Launch a playbook to provision a new IP trunk service.
The response will contain either a job ID, or error information.
...
...
@@ -80,7 +81,6 @@ def provision_ip_trunk(params: IPTrunkProvisioningParams, response: Response) ->
:param params: The parameters that define the new subscription object that
is to be deployed.
:type params: :class:`IPTrunkProvisioningParams`
:param Response response: A FastAPI response used for returning error codes if needed
:return: Response from the Ansible runner, including a run ID.
:rtype: :class:`lso.playbook.PlaybookLaunchResponse`
"""
...
...
@@ -100,17 +100,15 @@ def provision_ip_trunk(params: IPTrunkProvisioningParams, response: Response) ->
f
"
{
params
.
subscription
[
'
iptrunk
'
][
'
iptrunk_sides
'
][
1
][
'
iptrunk_side_node
'
][
'
router_fqdn
'
]
}
\n
"
,
extra_vars
=
extra_vars
,
callback
=
params
.
callback
,
response
=
response
,
)
@router.put
(
"
/
"
)
def
modify_ip_trunk
(
params
:
IPTrunkModifyParams
,
response
:
Response
)
->
PlaybookLaunch
Response
:
def
modify_ip_trunk
(
params
:
IPTrunkModifyParams
)
->
JSON
Response
:
"""
Launch a playbook that modifies an existing IP trunk service.
:param params: The parameters that define the change in configuration.
:type params: :class:`IPTrunkModifyParams`
:param Response response: A FastAPI response used for returning error codes if needed
:return: Response from the Ansible runner, including a run ID.
:rtype: :class:`lso.playbook.PlaybookLaunchResponse`
"""
...
...
@@ -130,18 +128,16 @@ def modify_ip_trunk(params: IPTrunkModifyParams, response: Response) -> Playbook
f
"
{
params
.
subscription
[
'
iptrunk
'
][
'
iptrunk_sides
'
][
1
][
'
iptrunk_side_node
'
][
'
router_fqdn
'
]
}
\n
"
,
extra_vars
=
extra_vars
,
callback
=
params
.
callback
,
response
=
response
,
)
@router.delete
(
"
/
"
)
def
delete_ip_trunk
(
params
:
IPTrunkDeleteParams
,
response
:
Response
)
->
PlaybookLaunch
Response
:
def
delete_ip_trunk
(
params
:
IPTrunkDeleteParams
)
->
JSON
Response
:
"""
Launch a playbook that deletes an existing IP trunk service.
:param params: Parameters that define the subscription that should get
terminated.
:type params: :class:`IPTrunkDeleteParams`
:param Response response: A FastAPI response used for returning error codes if needed
:return: Response from the Ansible runner, including a run ID.
:rtype: :class:`lso.playbook.PlaybookLaunchResponse`
"""
...
...
@@ -161,18 +157,16 @@ def delete_ip_trunk(params: IPTrunkDeleteParams, response: Response) -> Playbook
f
"
{
params
.
subscription
[
'
iptrunk
'
][
'
iptrunk_sides
'
][
1
][
'
iptrunk_side_node
'
][
'
router_fqdn
'
]
}
\n
"
,
extra_vars
=
extra_vars
,
callback
=
params
.
callback
,
response
=
response
,
)
@router.post
(
"
/perform_check
"
)
def
check_ip_trunk
(
params
:
IPTrunkCheckParams
,
response
:
Response
)
->
PlaybookLaunch
Response
:
def
check_ip_trunk
(
params
:
IPTrunkCheckParams
)
->
JSON
Response
:
"""
Launch a playbook that performs a check on an IP trunk service instance.
:param params: Parameters that define the check that is going to be
executed, including on which relevant subscription.
:type params: :class:`IPTrunkCheckParams`
:param Response response: A FastAPI response used for returning error codes if needed
:return: Response from the Ansible runner, including a run ID.
:rtype: :class:`lso.playbook.PlaybookLaunchResponse`
"""
...
...
@@ -184,19 +178,17 @@ def check_ip_trunk(params: IPTrunkCheckParams, response: Response) -> PlaybookLa
inventory
=
params
.
subscription
[
"
iptrunk
"
][
"
iptrunk_sides
"
][
0
][
"
iptrunk_side_node
"
][
"
router_fqdn
"
],
extra_vars
=
extra_vars
,
callback
=
params
.
callback
,
response
=
response
,
)
@router.post
(
"
/migrate
"
)
def
migrate_ip_trunk
(
params
:
IPTrunkMigrationParams
,
response
:
Response
)
->
PlaybookLaunch
Response
:
def
migrate_ip_trunk
(
params
:
IPTrunkMigrationParams
)
->
JSON
Response
:
"""
Launch a playbook to provision a new IP trunk service.
The response will contain either a job ID, or error information.
:param params: The parameters that define the new subscription object that is to be migrated.
:type params: :class:`IPTrunkMigrationParams`
:param Response response: A FastAPI response used for returning error codes if needed
:return: Response from the Ansible runner, including a run ID.
:rtype: :class:`lso.playbook.PlaybookLaunchResponse`
"""
...
...
@@ -220,5 +212,4 @@ def migrate_ip_trunk(params: IPTrunkMigrationParams, response: Response) -> Play
f
"
{
params
.
new_side
[
'
new_node
'
][
'
router
'
][
'
router_fqdn
'
]
}
\n
"
,
extra_vars
=
extra_vars
,
callback
=
params
.
callback
,
response
=
response
,
)
This diff is collapsed.
Click to expand it.
lso/routes/playbook.py
+
5
−
6
View file @
b46fd0d5
...
...
@@ -2,10 +2,11 @@
from
typing
import
Any
from
fastapi
import
APIRouter
,
Response
from
fastapi
import
APIRouter
from
fastapi.responses
import
JSONResponse
from
pydantic
import
BaseModel
,
HttpUrl
from
lso.playbook
import
PlaybookLaunchResponse
,
get_playbook_path
,
run_playbook
from
lso.playbook
import
get_playbook_path
,
run_playbook
router
=
APIRouter
()
...
...
@@ -29,20 +30,18 @@ class PlaybookRunParams(BaseModel):
@router.post
(
"
/
"
)
def
run_playbook_endpoint
(
params
:
PlaybookRunParams
,
response
:
Response
)
->
PlaybookLaunch
Response
:
def
run_playbook_endpoint
(
params
:
PlaybookRunParams
)
->
JSON
Response
:
"""
Launch an Ansible playbook to modify or deploy a subscription instance.
The response will contain either a job ID, or error information.
:param params :class:`PlaybookRunParams`: Parameters for executing a playbook.
:param Response response: A FastAPI response used for returning error codes if needed
:return: Response from the Ansible runner, including a run ID.
:rtype: :class:`
lso.playbook.PlaybookLaunch
Response`
:rtype: :class:`
fastapi.responses.JSON
Response`
"""
return
run_playbook
(
playbook_path
=
get_playbook_path
(
params
.
playbook_name
),
extra_vars
=
params
.
extra_vars
,
inventory
=
params
.
inventory
,
callback
=
params
.
callback
,
response
=
response
,
)
This diff is collapsed.
Click to expand it.
lso/routes/router.py
+
3
−
4
View file @
b46fd0d5
"""
Routes for handling device/base_config-related requests.
"""
from
fastapi
import
APIRouter
,
Response
from
fastapi
import
APIRouter
from
fastapi.responses
import
JSONResponse
from
pydantic
import
BaseModel
,
HttpUrl
from
lso
import
playbook
...
...
@@ -35,12 +36,11 @@ class NodeProvisioningParams(BaseModel):
@router.post
(
"
/
"
)
async
def
provision_node
(
params
:
NodeProvisioningParams
,
response
:
Response
)
->
playbook
.
PlaybookLaunch
Response
:
async
def
provision_node
(
params
:
NodeProvisioningParams
)
->
JSON
Response
:
"""
Launch a playbook to provision a new node. The response will contain either a job id or error information.
:param params: Parameters for provisioning a new node
:type params: :class:`NodeProvisioningParams`
:param Response response: A FastAPI response used for returning error codes if needed
:return: Response from the Ansible runner, including a run ID.
:rtype: :class:`lso.playbook.PlaybookLaunchResponse`
"""
...
...
@@ -56,5 +56,4 @@ async def provision_node(params: NodeProvisioningParams, response: Response) ->
inventory
=
f
"
{
params
.
subscription
[
'
router
'
][
'
router_fqdn
'
]
}
"
,
extra_vars
=
extra_vars
,
callback
=
params
.
callback
,
response
=
response
,
)
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment