Implement system_config_update orchestration
This commit adds VIM orchestration for system config update to drive the host swact/lock/unlock once these operations are expected to update the system config. CLI: sw-manager kube-rootca-update-strategy apply create delete show Test plan: 1. Create a system config udpate strategy successfully. --passed 2. Create a system config update strategy failed if the host resource doesn't exist. --passed 3. Create a system config update strategy failed if an unexpected alarm exists and the strategy alarm restrictions is set as strict. --passed 4. Create a system config update strategy successfully if an unexpected alarm exists and the strategy alarm restrictions is set as relax. --passed 5. Create a system config update strategy failed if a controller offline in a DX system. --passed 6. Create a system config update strategy failed if a storage offline in a standard system. --passed 7. Create a system config update strategy successfully if a worker offline in a standard system. --passed 8. Apply a system config update strategy successfully. --passed 9. Apply a system config update strategy failed if a host failed to lock. --passed 10. Delete a system config update strategy successful if a the strategy is complete or failed. --passed 11. Create a system config update strategy with strategy not required for the host in k8s, verify the host is excluded from the strategy. Story: 2010719 Task: 47910 Change-Id: I052bc5b2004f17de870a81c523d0a1f4e422a902 Signed-off-by: Yuxing Jiang <Yuxing.Jiang@windriver.com>
This commit is contained in:
parent
3bd5eed446
commit
6dba3df3e3
|
@ -118,6 +118,10 @@ forbidden (403), badMethod (405), overLimit (413), itemNotFound (404)
|
|||
{
|
||||
"href": "http://192.168.204.2:4545/orchestration/fw-update/",
|
||||
"rel": "fw-update"
|
||||
},
|
||||
{
|
||||
"href": "http://192.168.204.2:4545/orchestration/system-config-update/",
|
||||
"rel": "system-config-update"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -223,6 +227,39 @@ forbidden (403), badMethod (405), overLimit (413), itemNotFound (404)
|
|||
|
||||
This operation does not accept a request body.
|
||||
|
||||
*********************************************************************************
|
||||
Lists information about all NFV VIM API orchestration system-config-update links
|
||||
*********************************************************************************
|
||||
|
||||
.. rest_method:: GET /api/orchestration/system-config-update
|
||||
|
||||
**Normal response codes**
|
||||
|
||||
200
|
||||
|
||||
**Error response codes**
|
||||
|
||||
serviceUnavailable (503), badRequest (400), unauthorized (401),
|
||||
forbidden (403), badMethod (405), overLimit (413), itemNotFound (404)
|
||||
|
||||
::
|
||||
|
||||
{
|
||||
"id": "system-config-update",
|
||||
"links": [
|
||||
{
|
||||
"href": "http://192.168.204.2:4545/orchestration/system-config-update/",
|
||||
"rel": "self"
|
||||
},
|
||||
{
|
||||
"href": "http://192.168.204.2:4545/orchestration/system-config-update/strategy/",
|
||||
"rel": "strategy"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
This operation does not accept a request body.
|
||||
|
||||
---------------
|
||||
Patch Strategy
|
||||
---------------
|
||||
|
@ -3095,3 +3132,652 @@ forbidden (403), badMethod (405), overLimit (413)
|
|||
}
|
||||
}
|
||||
|
||||
------------------------------
|
||||
System Config Update Strategy
|
||||
------------------------------
|
||||
|
||||
System config update orchestration is done with a system config update
|
||||
orchestration strategy, or plan, for the automated update procedure which
|
||||
contains a number of parameters for customizing the particular behavior of the
|
||||
system config update orchestration.
|
||||
|
||||
***************************************************************************
|
||||
Shows detailed information about the current system-config-update strategy
|
||||
***************************************************************************
|
||||
|
||||
.. rest_method:: GET /api/orchestration/system-config-update/strategy
|
||||
|
||||
**Normal response codes**
|
||||
|
||||
200
|
||||
|
||||
**Error response codes**
|
||||
|
||||
serviceUnavailable (503), badRequest (400), unauthorized (401),
|
||||
forbidden (403), badMethod (405), overLimit (413), itemNotFound (404)
|
||||
|
||||
::
|
||||
|
||||
{
|
||||
"strategy": {
|
||||
"controller-apply-type": "serial",
|
||||
"swift-apply-type": "ignore",
|
||||
"storage-apply-type": "serial",
|
||||
"worker-apply-type": "parallel",
|
||||
"state": "ready-to-apply",
|
||||
"default-instance-action": "stop-start",
|
||||
"max-parallel-worker-hosts": 4,
|
||||
"alarm-restrictions": "strict",
|
||||
"current-phase-completion-percentage": 100,
|
||||
"uuid": "5dd16d94-dfc5-4029-bfcb-d815e7c2dc3d",
|
||||
"name": "system-config-update",
|
||||
"current-phase": "build",
|
||||
"build-phase": {
|
||||
"phase-name": "build",
|
||||
"current-stage": 1,
|
||||
"total-stages": 1,
|
||||
"completion-percentage": 100,
|
||||
"start-date-time": "",
|
||||
"end-date-time": "",
|
||||
"stop-at-stage": 1,
|
||||
"result": "success",
|
||||
"timeout": 182,
|
||||
"reason": "",
|
||||
"inprogress": false,
|
||||
"stages": [
|
||||
{
|
||||
"stage-id": 0,
|
||||
"total-steps": 3,
|
||||
"stage-name": "system-config-update-hosts-query",
|
||||
"result": "success",
|
||||
"timeout": 181,
|
||||
"inprogress": false,
|
||||
"start-date-time": "",
|
||||
"end-date-time": "",
|
||||
"reason": "",
|
||||
"current-step" : 3,
|
||||
"steps":[
|
||||
{
|
||||
"step-id": 0,
|
||||
"step-name": "query-alarms",
|
||||
"entity-type": "",
|
||||
"entity-names": [],
|
||||
"entity-uuids": [],
|
||||
"start-date-time": "",
|
||||
"end-date-time": "",
|
||||
"timeout": 60,
|
||||
"result": "success",
|
||||
"reason": ""
|
||||
},
|
||||
{
|
||||
"step-id": 1,
|
||||
"step-name": "query-strategy-required",
|
||||
"entity-type": "",
|
||||
"entity-names": [],
|
||||
"entity-uuids": [],
|
||||
"start-date-time": "",
|
||||
"end-date-time": "",
|
||||
"timeout": 60,
|
||||
"result": "success",
|
||||
"reason": ""
|
||||
},
|
||||
{
|
||||
"step-id": 2,
|
||||
"step-name": "query-in-sync",
|
||||
"entity-type": "",
|
||||
"entity-names": [],
|
||||
"entity-uuids": [],
|
||||
"start-date-time": "",
|
||||
"end-date-time": "",
|
||||
"timeout": 60,
|
||||
"result": "success",
|
||||
"reason": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"apply-phase": {
|
||||
"phase-name": "apply",
|
||||
"current-stage": 0,
|
||||
"completion-percentage": 100,
|
||||
"total-stages": 2,
|
||||
"stop-at-stage": 0,
|
||||
"start-date-time": "",
|
||||
"end-date-time": "",
|
||||
"result": "initial",
|
||||
"timeout": 0,
|
||||
"reason": "",
|
||||
"inprogress": false,
|
||||
"stages": [
|
||||
{
|
||||
"stage-id": 0,
|
||||
"stage-name": "system-config-update-controllers",
|
||||
"start-date-time": "",
|
||||
"end-date-time": "",
|
||||
"current-step": 0,
|
||||
"result": "initial",
|
||||
"timeout": 6436,
|
||||
"inprogress": false,
|
||||
"reason": "",
|
||||
"total-steps": 6,
|
||||
"steps": [
|
||||
{
|
||||
"step-id": 0,
|
||||
"step-name": "query-alarms",
|
||||
"entity-type": "",
|
||||
"entity-names": [],
|
||||
"entity-uuids": [],
|
||||
"start-date-time": "",
|
||||
"end-date-time": "",
|
||||
"timeout": 60,
|
||||
"result": "initial",
|
||||
"reason": ""
|
||||
},
|
||||
{
|
||||
"start-date-time": "",
|
||||
"end-date-time": "",
|
||||
"timeout": 900,
|
||||
"entity-type": "hosts",
|
||||
"step-id": 1,
|
||||
"entity-uuids": [
|
||||
"523cbd2d-f7f8-4707-8617-d085386f8711"
|
||||
],
|
||||
"step-name": "swact-hosts",
|
||||
"result": "initial",
|
||||
"entity-names": [
|
||||
"controller-1"
|
||||
],
|
||||
"reason": ""
|
||||
},
|
||||
{
|
||||
"start-date-time": "",
|
||||
"end-date-time": "",
|
||||
"timeout": 900,
|
||||
"entity-type": "hosts",
|
||||
"step-id": 2,
|
||||
"entity-uuids": [
|
||||
"523cbd2d-f7f8-4707-8617-d085386f8711"
|
||||
],
|
||||
"step-name": "lock-hosts",
|
||||
"result": "initial",
|
||||
"entity-names": [
|
||||
"controller-1"
|
||||
],
|
||||
"reason": ""
|
||||
},
|
||||
{
|
||||
"start-date-time": "",
|
||||
"end-date-time": "",
|
||||
"timeout": 1800,
|
||||
"entity-type": "hosts",
|
||||
"step-id": 3,
|
||||
"entity-uuids": [
|
||||
"523cbd2d-f7f8-4707-8617-d085386f8711"
|
||||
],
|
||||
"step-name": "config-disabled-host",
|
||||
"result": "initial",
|
||||
"entity-names": [
|
||||
"controller-1"
|
||||
],
|
||||
"reason": ""
|
||||
},
|
||||
{
|
||||
"start-date-time": "",
|
||||
"end-date-time": "",
|
||||
"timeout": 900,
|
||||
"entity-type": "hosts",
|
||||
"step-id": 4,
|
||||
"entity-uuids": [
|
||||
"523cbd2d-f7f8-4707-8617-d085386f8711"
|
||||
],
|
||||
"step-name": "unlock-hosts",
|
||||
"result": "initial",
|
||||
"entity-names": [
|
||||
"controller-1"
|
||||
],
|
||||
"reason": ""
|
||||
},
|
||||
{
|
||||
"step-id": 5,
|
||||
"entity-type": "",
|
||||
"step-name": "system-stabilize",
|
||||
"entity-names": [],
|
||||
"entity-uuids": [],
|
||||
"start-date-time": "",
|
||||
"end-date-time": "",
|
||||
"timeout": 60,
|
||||
"result": "initial",
|
||||
"reason": ""
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
"stage-id": 1,
|
||||
"total-steps": 6,
|
||||
"stage-name": "system-config-update-controllers",
|
||||
"inprogress": false,
|
||||
"start-date-time": "",
|
||||
"end-date-time": "",
|
||||
"timeout": 6436,
|
||||
"reason": "",
|
||||
"result": "initial",
|
||||
"current-step": 0,
|
||||
"steps":[
|
||||
{
|
||||
"step-id": 0,
|
||||
"step-name": "query-alarms",
|
||||
"entity-type": "",
|
||||
"entity-names": [],
|
||||
"entity-uuids": [],
|
||||
"start-date-time": "",
|
||||
"end-date-time": "",
|
||||
"timeout": 60,
|
||||
"result": "initial",
|
||||
"reason": ""
|
||||
},
|
||||
{
|
||||
"start-date-time": "",
|
||||
"end-date-time": "",
|
||||
"timeout": 900,
|
||||
"entity-type": "hosts",
|
||||
"step-id": 1,
|
||||
"entity-uuids": [
|
||||
"0f3715c0-fecd-46e0-9cd0-4fbb31810393"
|
||||
],
|
||||
"step-name": "swact-hosts",
|
||||
"result": "initial",
|
||||
"entity-names": [
|
||||
"controller-0"
|
||||
],
|
||||
"reason": ""
|
||||
},
|
||||
{
|
||||
"start-date-time": "",
|
||||
"end-date-time": "",
|
||||
"timeout": 900,
|
||||
"entity-type": "hosts",
|
||||
"step-id": 2,
|
||||
"entity-uuids": [
|
||||
"0f3715c0-fecd-46e0-9cd0-4fbb31810393"
|
||||
],
|
||||
"step-name": "lock-hosts",
|
||||
"result": "initial",
|
||||
"entity-names": [
|
||||
"controller-0"
|
||||
],
|
||||
"reason": ""
|
||||
},
|
||||
{
|
||||
"start-date-time": "",
|
||||
"end-date-time": "",
|
||||
"timeout": 1800,
|
||||
"entity-type": "hosts",
|
||||
"step-id": 3,
|
||||
"entity-uuids": [
|
||||
"0f3715c0-fecd-46e0-9cd0-4fbb31810393"
|
||||
],
|
||||
"step-name": "config-disabled-host",
|
||||
"result": "initial",
|
||||
"entity-names": [
|
||||
"controller-0"
|
||||
],
|
||||
"reason": ""
|
||||
},
|
||||
{
|
||||
"start-date-time": "",
|
||||
"end-date-time": "",
|
||||
"timeout": 900,
|
||||
"entity-type": "hosts",
|
||||
"step-id": 4,
|
||||
"entity-uuids": [
|
||||
"0f3715c0-fecd-46e0-9cd0-4fbb31810393"
|
||||
],
|
||||
"step-name": "unlock-hosts",
|
||||
"result": "initial",
|
||||
"entity-names": [
|
||||
"controller-0"
|
||||
],
|
||||
"reason": ""
|
||||
},
|
||||
{
|
||||
"step-id": 5,
|
||||
"entity-type": "",
|
||||
"step-name": "system-stabilize",
|
||||
"entity-names": [],
|
||||
"entity-uuids": [],
|
||||
"start-date-time": "",
|
||||
"end-date-time": "",
|
||||
"timeout": 60,
|
||||
"result": "initial",
|
||||
"reason": ""
|
||||
}
|
||||
],
|
||||
}
|
||||
],
|
||||
},
|
||||
"abort-phase": {
|
||||
"phase-name": "abort",
|
||||
"total-stages": 0,
|
||||
"completion-percentage": 100,
|
||||
"start-date-time": "",
|
||||
"end-date-time": "",
|
||||
"stop-at-stage": 0,
|
||||
"result": "initial",
|
||||
"timeout": 0,
|
||||
"reason": "",
|
||||
"inprogress": false,
|
||||
"stages": [],
|
||||
"current-stage": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
This operation does not accept a request body.
|
||||
|
||||
****************************************
|
||||
Creates a system-config-update strategy
|
||||
****************************************
|
||||
|
||||
.. rest_method:: POST /api/orchestration/system-config-update/strategy
|
||||
|
||||
**Normal response codes**
|
||||
|
||||
200
|
||||
|
||||
**Error response codes**
|
||||
|
||||
serviceUnavailable (503), badRequest (400), unauthorized (401),
|
||||
forbidden (403), badMethod (405), overLimit (413)
|
||||
|
||||
**Request parameters**
|
||||
|
||||
.. csv-table::
|
||||
:header: "Parameter", "Style", "Type", "Description"
|
||||
:widths: 20, 20, 20, 60
|
||||
|
||||
"controller-apply-type", "plain", "xsd:string", "The apply type for controller hosts: ``serial`` or ``ignore``."
|
||||
"storage-apply-type", "plain", "xsd:string", "The apply type for storage hosts: ``serial`` or ``ignore``."
|
||||
"worker-apply-type", "plain", "xsd:string", "The apply type for worker hosts: ``serial``, ``parallel`` or ``ignore``."
|
||||
"max-parallel-worker-hosts (Optional)", "plain", "xsd:integer", "The maximum number of worker hosts to patch in parallel; only applicable if ``worker-apply-type = parallel``. Default value is ``2``."
|
||||
"default-instance-action", "plain", "xsd:string", "The default instance action: ``stop-start`` or ``migrate``."
|
||||
"alarm-restrictions (Optional)", "plain", "xsd:string", "The strictness of alarm checks: ``strict`` or ``relaxed``."
|
||||
|
||||
::
|
||||
|
||||
{
|
||||
"controller-apply-type": "serial",
|
||||
"storage-apply-type": "ignore",
|
||||
"worker-apply-type": "serial",
|
||||
"default-instance-action": "stop-start",
|
||||
"alarm-restrictions": "strict",
|
||||
}
|
||||
|
||||
::
|
||||
|
||||
{
|
||||
"strategy": {
|
||||
"name": "system-config-update",
|
||||
"worker-apply-type": "serial",
|
||||
"controller-apply-type": "serial",
|
||||
"swift-apply-type": "ignore",
|
||||
"storage-apply-type": "ignore",
|
||||
"current-phase-completion-percentage": 0,
|
||||
"uuid": "447c4267-0ecb-48f4-9237-1d747a3e7cca",
|
||||
"default-instance-action": "stop-start",
|
||||
"max-parallel-worker-hosts": 2,
|
||||
"alarm-restrictions": "strict",
|
||||
"state": "building",
|
||||
"build-phase": {
|
||||
"phase-name": "build",
|
||||
"current-stage": 0,
|
||||
"start-date-time": "",
|
||||
"end-date-time": "",
|
||||
"completion-percentage": 0,
|
||||
"stop-at-stage": 3,
|
||||
"result": "inprogress",
|
||||
"timeout": 182,
|
||||
"reason": "",
|
||||
"inprogress": true,
|
||||
"total-stages": 3,
|
||||
"stages": [
|
||||
{
|
||||
"stage-id": 0,
|
||||
"stage-name": "system-config-update-query",
|
||||
"total-steps": 3,
|
||||
"inprogress": true,
|
||||
"start-date-time": "",
|
||||
"end-date-time": "",
|
||||
"reason": "",
|
||||
"current-step": 0,
|
||||
"result": "inprogress",
|
||||
"timeout": 181,
|
||||
"steps": [
|
||||
{
|
||||
"step-id": 0,
|
||||
"step-name": "query-alarms",
|
||||
"entity-type": "",
|
||||
"entity-names": [],
|
||||
"entity-uuids": [],
|
||||
"start-date-time": "",
|
||||
"end-date-time": "",
|
||||
"timeout": 60,
|
||||
"result": "success",
|
||||
"reason": ""
|
||||
},
|
||||
{
|
||||
"step-id": 1,
|
||||
"step-name": "query-strategy-required",
|
||||
"entity-type": "",
|
||||
"entity-names": [],
|
||||
"entity-uuids": [],
|
||||
"start-date-time": "",
|
||||
"end-date-time": "",
|
||||
"timeout": 60,
|
||||
"result": "success",
|
||||
"reason": ""
|
||||
},
|
||||
{
|
||||
"step-id": 2,
|
||||
"step-name": "query-in-sync",
|
||||
"entity-type": "",
|
||||
"entity-names": [],
|
||||
"entity-uuids": [],
|
||||
"start-date-time": "",
|
||||
"end-date-time": "",
|
||||
"timeout": 60,
|
||||
"result": "success",
|
||||
"reason": ""
|
||||
}
|
||||
],
|
||||
}
|
||||
],
|
||||
},
|
||||
"apply-phase": {
|
||||
"start-date-time": "",
|
||||
"end-date-time": "",
|
||||
"phase-name": "apply",
|
||||
"completion-percentage": 100,
|
||||
"total-stages": 0,
|
||||
"stop-at-stage": 0,
|
||||
"result": "initial",
|
||||
"timeout": 0,
|
||||
"reason": "",
|
||||
"inprogress": false,
|
||||
"stages": [],
|
||||
"current-stage": 0
|
||||
},
|
||||
"abort-phase": {
|
||||
"start-date-time": "",
|
||||
"end-date-time": "",
|
||||
"phase-name": "abort",
|
||||
"completion-percentage": 100,
|
||||
"total-stages": 0,
|
||||
"stop-at-stage": 0,
|
||||
"result": "initial",
|
||||
"timeout": 0,
|
||||
"reason": "",
|
||||
"inprogress":false,
|
||||
"stages": [],
|
||||
"current-stage": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
**************************************************
|
||||
Deletes the current system-config-update strategy
|
||||
**************************************************
|
||||
|
||||
.. rest_method:: DELETE /api/orchestration/system-config-update/strategy
|
||||
|
||||
**Normal response codes**
|
||||
|
||||
204
|
||||
|
||||
::
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
**************************************************
|
||||
Applies or aborts a system-config-update strategy
|
||||
**************************************************
|
||||
|
||||
.. rest_method:: POST /api/orchestration/system-config-update/strategy/actions
|
||||
|
||||
**Normal response codes**
|
||||
|
||||
202
|
||||
|
||||
**Error response codes**
|
||||
|
||||
serviceUnavailable (503), badRequest (400), unauthorized (401),
|
||||
forbidden (403), badMethod (405), overLimit (413)
|
||||
|
||||
**Request parameters**
|
||||
|
||||
.. csv-table::
|
||||
:header: "Parameter", "Style", "Type", "Description"
|
||||
:widths: 20, 20, 20, 60
|
||||
|
||||
"action", "plain", "xsd:string", "The action to take: ``apply-all``, ``apply-stage``, ``abort`` or ``abort-stage``."
|
||||
"stage-id (Optional)", "plain", "xsd:string", "The stage-id to apply or abort. Only used with ``apply-stage`` or ``abort-stage`` actions."
|
||||
|
||||
::
|
||||
|
||||
{
|
||||
"action": "apply-all"
|
||||
}
|
||||
|
||||
::
|
||||
|
||||
{
|
||||
"strategy":{
|
||||
"controller-apply-type": "serial",
|
||||
"swift-apply-type": "ignore",
|
||||
"current-phase-completion-percentage": 0,
|
||||
"uuid": "447c4267-0ecb-48f4-9237-1d747a3e7cca",
|
||||
"name": "system-config-update",
|
||||
"current-phase": "build",
|
||||
"storage-apply-type": "ignore",
|
||||
"state":"building",
|
||||
"worker-apply-type": "serial",
|
||||
"default-instance-action": "stop-start",
|
||||
"max-parallel-worker-hosts": 2,
|
||||
"alarm-restrictions": "strict",
|
||||
"build-phase": {
|
||||
"phase-name": "build",
|
||||
"current-stage": 0,
|
||||
"start-date-time": "",
|
||||
"end-date-time": "",
|
||||
"completion-percentage": 0,
|
||||
"stop-at-stage": 3,
|
||||
"result": "inprogress",
|
||||
"timeout": 182,
|
||||
"reason": "",
|
||||
"inprogress": true,
|
||||
"total-stages": 3,
|
||||
"stages": [
|
||||
{
|
||||
"stage-id": 0,
|
||||
"stage-name": "system-config-update-query",
|
||||
"total-steps": 3,
|
||||
"inprogress": true,
|
||||
"start-date-time": "",
|
||||
"end-date-time": "",
|
||||
"reason": "",
|
||||
"current-step": 0,
|
||||
"result": "inprogress",
|
||||
"timeout": 181,
|
||||
"steps": [
|
||||
{
|
||||
"step-id": 0,
|
||||
"step-name": "query-alarms",
|
||||
"entity-type": "",
|
||||
"entity-names": [],
|
||||
"entity-uuids": [],
|
||||
"start-date-time": "",
|
||||
"end-date-time": "",
|
||||
"timeout": 60,
|
||||
"result": "success",
|
||||
"reason": ""
|
||||
},
|
||||
{
|
||||
"step-id": 1,
|
||||
"step-name": "query-strategy-required",
|
||||
"entity-type": "",
|
||||
"entity-names": [],
|
||||
"entity-uuids": [],
|
||||
"start-date-time": "",
|
||||
"end-date-time": "",
|
||||
"timeout": 60,
|
||||
"result": "success",
|
||||
"reason": ""
|
||||
},
|
||||
{
|
||||
"step-id": 2,
|
||||
"step-name": "query-in-sync",
|
||||
"entity-type": "",
|
||||
"entity-names": [],
|
||||
"entity-uuids": [],
|
||||
"start-date-time": "",
|
||||
"end-date-time": "",
|
||||
"timeout": 60,
|
||||
"result": "success",
|
||||
"reason": ""
|
||||
}
|
||||
],
|
||||
}
|
||||
],
|
||||
},
|
||||
"apply-phase": {
|
||||
"start-date-time": "",
|
||||
"end-date-time": "",
|
||||
"phase-name": "apply",
|
||||
"completion-percentage": 100,
|
||||
"total-stages": 0,
|
||||
"stop-at-stage": 0,
|
||||
"result": "initial",
|
||||
"timeout": 0,
|
||||
"reason": "",
|
||||
"inprogress": false,
|
||||
"stages": [],
|
||||
"current-stage": 0
|
||||
},
|
||||
"abort-phase": {
|
||||
"start-date-time": "",
|
||||
"end-date-time": "",
|
||||
"phase-name": "abort",
|
||||
"completion-percentage": 100,
|
||||
"total-stages": 0,
|
||||
"stop-at-stage": 0,
|
||||
"result": "initial",
|
||||
"timeout": 0,
|
||||
"reason": "",
|
||||
"inprogress": false,
|
||||
"stages": [],
|
||||
"current-stage": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2016-2021 Wind River Systems, Inc.
|
||||
# Copyright (c) 2016-2023 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -279,6 +279,9 @@ def create_strategy(token_id,
|
|||
# required: 'to_version' passed to strategy as 'to-version'
|
||||
api_cmd_payload['to-version'] = kwargs['to_version']
|
||||
api_cmd_payload['default-instance-action'] = default_instance_action
|
||||
elif 'system-config-update' == strategy_name:
|
||||
api_cmd_payload['controller-apply-type'] = controller_apply_type
|
||||
api_cmd_payload['default-instance-action'] = default_instance_action
|
||||
elif 'sw-upgrade' == strategy_name:
|
||||
# for upgrade: default-instance-action is hardcoded to MIGRATE
|
||||
if 'start_upgrade' in kwargs and kwargs['start_upgrade']:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2016-2021 Wind River Systems, Inc.
|
||||
# Copyright (c) 2016-2023 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -56,6 +56,9 @@ def get_extra_create_args(cmd_area, args):
|
|||
elif 'fw-update-strategy' == cmd_area:
|
||||
# no additional kwargs for firmware update
|
||||
return {}
|
||||
elif 'system-config-update-strategy' == cmd_area:
|
||||
# no additional kwargs for system config update
|
||||
return {}
|
||||
elif 'kube-rootca-update-strategy' == cmd_area:
|
||||
# kube rootca update supports expiry_date, subject and cert_file
|
||||
return {
|
||||
|
@ -384,6 +387,48 @@ def setup_patch_parser(commands):
|
|||
_ = setup_show_cmd(sub_cmds)
|
||||
|
||||
|
||||
def setup_system_config_update_parser(commands):
|
||||
"""System config update Strategy Commands"""
|
||||
|
||||
cmd_area = 'system-config-update-strategy'
|
||||
register_strategy(cmd_area, sw_update.STRATEGY_NAME_SYSTEM_CONFIG_UPDATE)
|
||||
cmd_parser = commands.add_parser(cmd_area,
|
||||
help='system config update Strategy')
|
||||
cmd_parser.set_defaults(cmd_area=cmd_area)
|
||||
|
||||
sub_cmds = cmd_parser.add_subparsers(title='Sytem Config Update Commands',
|
||||
metavar='')
|
||||
sub_cmds.required = True
|
||||
|
||||
# define the create command
|
||||
# alarm restrictions, defaults to strict
|
||||
_ = setup_create_cmd(
|
||||
sub_cmds,
|
||||
[sw_update.APPLY_TYPE_SERIAL, # controller supports serial only
|
||||
sw_update.APPLY_TYPE_IGNORE],
|
||||
[sw_update.APPLY_TYPE_SERIAL, # storage supports serial only
|
||||
sw_update.APPLY_TYPE_IGNORE],
|
||||
[sw_update.APPLY_TYPE_SERIAL, # worker supports serial and parallel
|
||||
sw_update.APPLY_TYPE_PARALLEL,
|
||||
sw_update.APPLY_TYPE_IGNORE],
|
||||
[sw_update.INSTANCE_ACTION_STOP_START, # instance actions
|
||||
sw_update.INSTANCE_ACTION_MIGRATE],
|
||||
[sw_update.ALARM_RESTRICTIONS_STRICT, # alarm restrictions
|
||||
sw_update.ALARM_RESTRICTIONS_RELAXED],
|
||||
min_parallel=2,
|
||||
max_parallel=100 # config update supports 2..100 workers in parallel
|
||||
)
|
||||
|
||||
# define the delete command
|
||||
_ = setup_delete_cmd(sub_cmds)
|
||||
# define the apply command
|
||||
_ = setup_apply_cmd(sub_cmds)
|
||||
# define the abort command
|
||||
_ = setup_abort_cmd(sub_cmds)
|
||||
# define the show command
|
||||
_ = setup_show_cmd(sub_cmds)
|
||||
|
||||
|
||||
def setup_upgrade_parser(commands):
|
||||
"""Upgrade Strategy Commands"""
|
||||
|
||||
|
@ -468,6 +513,9 @@ def process_main(argv=sys.argv[1:]): # pylint: disable=dangerous-default-value
|
|||
# Add software patch strategy commands
|
||||
setup_patch_parser(commands)
|
||||
|
||||
# Add system config update strategy commands
|
||||
setup_system_config_update_parser(commands)
|
||||
|
||||
# Add software upgrade strategy commands
|
||||
setup_upgrade_parser(commands)
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2016-2021 Wind River Systems, Inc.
|
||||
# Copyright (c) 2016-2023 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -19,3 +19,4 @@ from nfv_client.sw_update._sw_update import STRATEGY_NAME_KUBE_ROOTCA_UPDATE #
|
|||
from nfv_client.sw_update._sw_update import STRATEGY_NAME_KUBE_UPGRADE # noqa: F401
|
||||
from nfv_client.sw_update._sw_update import STRATEGY_NAME_SW_PATCH # noqa: F401
|
||||
from nfv_client.sw_update._sw_update import STRATEGY_NAME_SW_UPGRADE # noqa: F401
|
||||
from nfv_client.sw_update._sw_update import STRATEGY_NAME_SYSTEM_CONFIG_UPDATE # noqa: F401
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2016-2022 Wind River Systems, Inc.
|
||||
# Copyright (c) 2016-2023 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -11,6 +11,7 @@ STRATEGY_NAME_SW_UPGRADE = 'sw-upgrade'
|
|||
STRATEGY_NAME_FW_UPDATE = 'fw-update'
|
||||
STRATEGY_NAME_KUBE_ROOTCA_UPDATE = 'kube-rootca-update'
|
||||
STRATEGY_NAME_KUBE_UPGRADE = 'kube-upgrade'
|
||||
STRATEGY_NAME_SYSTEM_CONFIG_UPDATE = 'system-config-update'
|
||||
|
||||
APPLY_TYPE_SERIAL = 'serial'
|
||||
APPLY_TYPE_PARALLEL = 'parallel'
|
||||
|
@ -130,6 +131,8 @@ def _display_strategy(strategy, details=False, active=False):
|
|||
print("Strategy Kubernetes RootCA Update Strategy:")
|
||||
elif strategy.name == STRATEGY_NAME_KUBE_UPGRADE:
|
||||
print("Strategy Kubernetes Upgrade Strategy:")
|
||||
elif strategy.name == STRATEGY_NAME_SYSTEM_CONFIG_UPDATE:
|
||||
print("Strategy System Config Upgrade Strategy:")
|
||||
else:
|
||||
print("Strategy Unknown Strategy:")
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2016-2021 Wind River Systems, Inc.
|
||||
# Copyright (c) 2016-2023 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -24,6 +24,7 @@ function _swmanager()
|
|||
fw-update-strategy
|
||||
kube-rootca-update-strategy
|
||||
kube-upgrade-strategy
|
||||
system-config-update-strategy
|
||||
"
|
||||
|
||||
if [ $COMP_CWORD -gt 1 ]; then
|
||||
|
@ -252,6 +253,83 @@ function _swmanager()
|
|||
esac
|
||||
fi
|
||||
|
||||
# Provide actions for completion
|
||||
COMPREPLY=($(compgen -W "${actions}" -- ${cur}))
|
||||
return 0
|
||||
;;
|
||||
system-config-update-strategy)
|
||||
local actions="
|
||||
create
|
||||
delete
|
||||
apply
|
||||
abort
|
||||
show
|
||||
"
|
||||
if [ $COMP_CWORD -gt 2 ]; then
|
||||
local action=${COMP_WORDS[2]}
|
||||
#
|
||||
# Complete the arguments for each action
|
||||
#
|
||||
case "$action" in
|
||||
create)
|
||||
local createopts="
|
||||
--controller-apply-type
|
||||
--storage-apply-type
|
||||
--worker-apply-type
|
||||
--max-parallel-worker-hosts
|
||||
--instance-action
|
||||
--alarm-restrictions
|
||||
"
|
||||
local createopt=${prev}
|
||||
case "$createopt" in
|
||||
--controller-apply-type|--storage-apply-type)
|
||||
COMPREPLY=($(compgen -W "serial ignore" -- ${cur}))
|
||||
return 0
|
||||
;;
|
||||
--worker-apply-type)
|
||||
COMPREPLY=($(compgen -W "serial parallel ignore" -- ${cur}))
|
||||
return 0
|
||||
;;
|
||||
--max-parallel-worker-hosts)
|
||||
COMPREPLY=( $(compgen -- ${cur}))
|
||||
return 0
|
||||
;;
|
||||
--instance-action)
|
||||
COMPREPLY=($(compgen -W "migrate stop-start" -- ${cur}))
|
||||
return 0
|
||||
;;
|
||||
--alarm-restrictions)
|
||||
COMPREPLY=($(compgen -W "strict relaxed" -- ${cur}))
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
COMPREPLY=($(compgen -W "${createopts}" -- ${cur}))
|
||||
return 0
|
||||
;;
|
||||
apply|abort)
|
||||
if [ "${prev}" = "${action}" ]; then
|
||||
COMPREPLY=($(compgen -W "--stage-id" -- ${cur}))
|
||||
fi
|
||||
return 0
|
||||
;;
|
||||
show)
|
||||
if [ "${prev}" = "${action}" ]; then
|
||||
COMPREPLY=($(compgen -W "--details --active" -- ${cur}))
|
||||
fi
|
||||
return 0
|
||||
;;
|
||||
delete)
|
||||
# These subcommands have no options/arguments
|
||||
COMPREPLY=( $(compgen -- ${cur}) )
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Provide actions for completion
|
||||
COMPREPLY=($(compgen -W "${actions}" -- ${cur}))
|
||||
return 0
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2015-2021 Wind River Systems, Inc.
|
||||
# Copyright (c) 2015-2023 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -50,6 +50,9 @@ class _AlarmType(Constants):
|
|||
KUBE_UPGRADE_AUTO_APPLY_INPROGRESS = Constant('kube-upgrade-auto-apply-inprogress')
|
||||
KUBE_UPGRADE_AUTO_APPLY_ABORTING = Constant('kube-upgrade-auto-apply-aborting')
|
||||
KUBE_UPGRADE_AUTO_APPLY_FAILED = Constant('kube-upgrade-auto-apply-failed')
|
||||
SYSTEM_CONFIG_UPDATE_AUTO_APPLY_INPROGRESS = Constant('system-config-update-auto-apply-inprogress')
|
||||
SYSTEM_CONFIG_UPDATE_AUTO_APPLY_ABORTING = Constant('system-config-update-auto-apply-aborting')
|
||||
SYSTEM_CONFIG_UPDATE_AUTO_APPLY_FAILED = Constant('system-config-update-auto-apply-failed')
|
||||
|
||||
|
||||
@six.add_metaclass(Singleton)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2015-2021 Wind River Systems, Inc.
|
||||
# Copyright (c) 2015-2023 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -196,6 +196,18 @@ class _EventId(Constants):
|
|||
KUBE_UPGRADE_AUTO_APPLY_ABORT_FAILED = Constant('kube-upgrade-auto-apply-abort-failed')
|
||||
KUBE_UPGRADE_AUTO_APPLY_ABORTED = Constant('kube-upgrade-auto-apply-aborted')
|
||||
|
||||
SYSTEM_CONFIG_UPDATE_AUTO_APPLY_START = Constant('system-config-update-auto-apply-started')
|
||||
SYSTEM_CONFIG_UPDATE_AUTO_APPLY_INPROGRESS = Constant('system-config-update-auto-apply-inprogress')
|
||||
SYSTEM_CONFIG_UPDATE_AUTO_APPLY_REJECTED = Constant('system-config-update-auto-apply-rejected')
|
||||
SYSTEM_CONFIG_UPDATE_AUTO_APPLY_CANCELLED = Constant('system-config-update-auto-apply-cancelled')
|
||||
SYSTEM_CONFIG_UPDATE_AUTO_APPLY_FAILED = Constant('system-config-update-auto-apply-failed')
|
||||
SYSTEM_CONFIG_UPDATE_AUTO_APPLY_COMPLETED = Constant('system-config-update-auto-apply-completed')
|
||||
SYSTEM_CONFIG_UPDATE_AUTO_APPLY_ABORT = Constant('system-config-update-auto-apply-abort')
|
||||
SYSTEM_CONFIG_UPDATE_AUTO_APPLY_ABORTING = Constant('system-config-update-auto-apply-aborting')
|
||||
SYSTEM_CONFIG_UPDATE_AUTO_APPLY_ABORT_REJECTED = Constant('system-config-update-auto-apply-abort-rejected')
|
||||
SYSTEM_CONFIG_UPDATE_AUTO_APPLY_ABORT_FAILED = Constant('system-config-update-auto-apply-abort-failed')
|
||||
SYSTEM_CONFIG_UPDATE_AUTO_APPLY_ABORTED = Constant('system-config-update-auto-apply-aborted')
|
||||
|
||||
|
||||
@six.add_metaclass(Singleton)
|
||||
class _EventType(Constants):
|
||||
|
|
|
@ -97,6 +97,18 @@ _fm_kube_rootca_update_alarm_id_mapping = dict([
|
|||
# Merge the kube rootca update mapping with the entire mapping
|
||||
_fm_alarm_id_mapping.update(_fm_kube_rootca_update_alarm_id_mapping)
|
||||
|
||||
_fm_system_config_update_alarm_id_mapping = dict([
|
||||
(alarm_objects_v1.ALARM_TYPE.SYSTEM_CONFIG_UPDATE_AUTO_APPLY_INPROGRESS,
|
||||
fm_constants.FM_ALARM_ID_SYSTEM_CONFIG_UPDATE_AUTO_APPLY_INPROGRESS),
|
||||
(alarm_objects_v1.ALARM_TYPE.SYSTEM_CONFIG_UPDATE_AUTO_APPLY_ABORTING,
|
||||
fm_constants.FM_ALARM_ID_SYSTEM_CONFIG_UPDATE_AUTO_APPLY_ABORTING),
|
||||
(alarm_objects_v1.ALARM_TYPE.SYSTEM_CONFIG_UPDATE_AUTO_APPLY_FAILED,
|
||||
fm_constants.FM_ALARM_ID_SYSTEM_CONFIG_UPDATE_AUTO_APPLY_FAILED),
|
||||
])
|
||||
|
||||
# Merge the system config update mapping with the entire mapping
|
||||
_fm_alarm_id_mapping.update(_fm_system_config_update_alarm_id_mapping)
|
||||
|
||||
_fm_alarm_type_mapping = dict([
|
||||
(alarm_objects_v1.ALARM_EVENT_TYPE.COMMUNICATIONS_ALARM,
|
||||
fm_constants.FM_ALARM_TYPE_1),
|
||||
|
|
|
@ -386,6 +386,35 @@ _fm_kube_rootca_update_event_id_mapping = dict([
|
|||
# Merge the kube rootca update mapping with the entire mapping
|
||||
_fm_event_id_mapping.update(_fm_kube_rootca_update_event_id_mapping)
|
||||
|
||||
# define system config update event mapping
|
||||
_fm_system_config_update_event_id_mapping = dict([
|
||||
(event_log_objects_v1.EVENT_ID.SYSTEM_CONFIG_UPDATE_AUTO_APPLY_START,
|
||||
fm_constants.FM_LOG_ID_SYSTEM_CONFIG_UPDATE_AUTO_APPLY_START),
|
||||
(event_log_objects_v1.EVENT_ID.SYSTEM_CONFIG_UPDATE_AUTO_APPLY_INPROGRESS,
|
||||
fm_constants.FM_LOG_ID_SYSTEM_CONFIG_UPDATE_AUTO_APPLY_INPROGRESS),
|
||||
(event_log_objects_v1.EVENT_ID.SYSTEM_CONFIG_UPDATE_AUTO_APPLY_REJECTED,
|
||||
fm_constants.FM_LOG_ID_SYSTEM_CONFIG_UPDATE_AUTO_APPLY_REJECTED),
|
||||
(event_log_objects_v1.EVENT_ID.SYSTEM_CONFIG_UPDATE_AUTO_APPLY_CANCELLED,
|
||||
fm_constants.FM_LOG_ID_SYSTEM_CONFIG_UPDATE_AUTO_APPLY_CANCELLED),
|
||||
(event_log_objects_v1.EVENT_ID.SYSTEM_CONFIG_UPDATE_AUTO_APPLY_FAILED,
|
||||
fm_constants.FM_LOG_ID_SYSTEM_CONFIG_UPDATE_AUTO_APPLY_FAILED),
|
||||
(event_log_objects_v1.EVENT_ID.SYSTEM_CONFIG_UPDATE_AUTO_APPLY_COMPLETED,
|
||||
fm_constants.FM_LOG_ID_SYSTEM_CONFIG_UPDATE_AUTO_APPLY_COMPLETED),
|
||||
(event_log_objects_v1.EVENT_ID.SYSTEM_CONFIG_UPDATE_AUTO_APPLY_ABORT,
|
||||
fm_constants.FM_LOG_ID_SYSTEM_CONFIG_UPDATE_AUTO_APPLY_ABORT),
|
||||
(event_log_objects_v1.EVENT_ID.SYSTEM_CONFIG_UPDATE_AUTO_APPLY_ABORTING,
|
||||
fm_constants.FM_LOG_ID_SYSTEM_CONFIG_UPDATE_AUTO_APPLY_ABORTING),
|
||||
(event_log_objects_v1.EVENT_ID.SYSTEM_CONFIG_UPDATE_AUTO_APPLY_ABORT_REJECTED,
|
||||
fm_constants.FM_LOG_ID_SYSTEM_CONFIG_UPDATE_AUTO_APPLY_ABORT_REJECTED),
|
||||
(event_log_objects_v1.EVENT_ID.SYSTEM_CONFIG_UPDATE_AUTO_APPLY_ABORT_FAILED,
|
||||
fm_constants.FM_LOG_ID_SYSTEM_CONFIG_UPDATE_AUTO_APPLY_ABORT_FAILED),
|
||||
(event_log_objects_v1.EVENT_ID.SYSTEM_CONFIG_UPDATE_AUTO_APPLY_ABORTED,
|
||||
fm_constants.FM_LOG_ID_SYSTEM_CONFIG_UPDATE_AUTO_APPLY_ABORTED),
|
||||
])
|
||||
|
||||
# Merge the system config update mapping with the entire mapping
|
||||
_fm_event_id_mapping.update(_fm_system_config_update_event_id_mapping)
|
||||
|
||||
_fm_event_type_mapping = dict([
|
||||
(event_log_objects_v1.EVENT_TYPE.STATE_EVENT,
|
||||
fm_constants.FM_ALARM_TYPE_4),
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2018-2022 Wind River Systems, Inc.
|
||||
# Copyright (c) 2018-2023 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -55,6 +55,28 @@ def get_client():
|
|||
return kubernetes.client.CoreV1Api()
|
||||
|
||||
|
||||
def get_kubertnetes_https_client():
|
||||
"""
|
||||
Get Kubernetes client with HTTPS enabled
|
||||
"""
|
||||
kubernetes.config.load_kube_config('/etc/kubernetes/admin.conf')
|
||||
|
||||
if K8S_MODULE_MAJOR_VERSION < 12:
|
||||
c = kubernetes.client.Configuration()
|
||||
else:
|
||||
c = kubernetes.client.Configuration().get_default_copy()
|
||||
kubernetes.client.Configuration.set_default(c)
|
||||
return kubernetes.client
|
||||
|
||||
|
||||
def get_customobjects_api_instance():
|
||||
"""
|
||||
Get a custom objects API instance
|
||||
"""
|
||||
client = get_kubertnetes_https_client()
|
||||
return client.CustomObjectsApi()
|
||||
|
||||
|
||||
def taint_node(node_name, effect, key, value):
|
||||
"""
|
||||
Apply a taint to a node
|
||||
|
@ -231,3 +253,132 @@ def get_terminating_pods(node_name):
|
|||
terminating_pods.append(pod.metadata.name)
|
||||
|
||||
return Result(','.join(terminating_pods))
|
||||
|
||||
|
||||
def get_namespaced_custom_object(name, plural, group, version, namespace):
|
||||
"""
|
||||
Get a custom resource object in a namespace
|
||||
"""
|
||||
# Get a CustomObjectsApi instance
|
||||
api_instance = get_customobjects_api_instance()
|
||||
|
||||
try:
|
||||
resource = api_instance.get_namespaced_custom_object(
|
||||
group=group,
|
||||
version=version,
|
||||
name=name,
|
||||
namespace=namespace,
|
||||
plural=plural
|
||||
)
|
||||
return Result(resource)
|
||||
except ApiException as e:
|
||||
DLOG.exception(
|
||||
"Failed to get object %s from namespace %s, "
|
||||
"reason: %s" % (name, namespace, e.reason))
|
||||
return None
|
||||
|
||||
|
||||
def get_deployment_host(name):
|
||||
"""
|
||||
Get a host in the deployment namespace
|
||||
"""
|
||||
# Get a CustomObjectsApi instance
|
||||
api_instance = get_customobjects_api_instance()
|
||||
|
||||
try:
|
||||
resource = api_instance.get_namespaced_custom_object(
|
||||
group='starlingx.windriver.com',
|
||||
version='v1',
|
||||
name=name,
|
||||
namespace='deployment',
|
||||
plural='hosts'
|
||||
)
|
||||
unlock_request = resource.get('status').get('strategyRequired')
|
||||
result = {'name': name, 'unlock_request': unlock_request}
|
||||
return Result(result)
|
||||
except ApiException as e:
|
||||
DLOG.exception(
|
||||
"Failed to get object %s from namespace deployment, "
|
||||
"reason: %s" % (name, e.reason))
|
||||
return None
|
||||
|
||||
|
||||
def list_namespaced_custom_objects(plural, group, version, namespace):
|
||||
"""
|
||||
List custom resource objects in a namespace
|
||||
"""
|
||||
# Get a CustomObjectsApi instance
|
||||
api_instance = get_customobjects_api_instance()
|
||||
|
||||
try:
|
||||
resources = api_instance.list_namespaced_custom_object(
|
||||
group=group,
|
||||
version=version,
|
||||
namespace=namespace,
|
||||
plural=plural
|
||||
)
|
||||
return Result(resources)
|
||||
except ApiException as e:
|
||||
DLOG.exception(
|
||||
"Failed to list objects %s from namespace %s, "
|
||||
"reason: %s" % (plural, namespace, e.reason))
|
||||
return None
|
||||
|
||||
|
||||
def list_deployment_hosts():
|
||||
"""
|
||||
List hosts in a deployment namespace
|
||||
"""
|
||||
# Get a CustomObjectsApi instance
|
||||
api_instance = get_customobjects_api_instance()
|
||||
|
||||
try:
|
||||
resources = api_instance.list_namespaced_custom_object(
|
||||
group='starlingx.windriver.com',
|
||||
version='v1',
|
||||
namespace='deployment',
|
||||
plural='hosts'
|
||||
)
|
||||
|
||||
if not resources:
|
||||
return None
|
||||
|
||||
results = list()
|
||||
for resource in resources.get('items'):
|
||||
name = resource.get('metadata').get('name')
|
||||
unlock_request = resource.get('status').get('strategyRequired')
|
||||
results.append({'name': name,
|
||||
'unlock_request': unlock_request})
|
||||
|
||||
return Result(results)
|
||||
except ApiException as e:
|
||||
DLOG.exception(
|
||||
"Failed to list hosts from deployment namespace, "
|
||||
"reason: %s" % e.reason)
|
||||
return None
|
||||
|
||||
|
||||
def get_namespaced_running_pods(namespace, name):
|
||||
"""
|
||||
Get running pods in a namespace
|
||||
"""
|
||||
api_instance = get_client()
|
||||
|
||||
try:
|
||||
response = api_instance.list_namespaced_pod(
|
||||
namespace=namespace,
|
||||
field_selector="status.phase=Running",)
|
||||
except ApiException as e:
|
||||
DLOG.exception(
|
||||
"Failed to list pods from namespace %s, "
|
||||
"reason: %s" % (namespace, e.reason))
|
||||
return None
|
||||
|
||||
pods = response.items
|
||||
found = list()
|
||||
if pods is not None:
|
||||
for pod in pods:
|
||||
if name in pod.metadata.name:
|
||||
found.append(pod.metadata.name)
|
||||
|
||||
return Result(','.join(found))
|
||||
|
|
|
@ -3806,6 +3806,118 @@ class NFVIInfrastructureAPI(nfvi.api.v1.NFVIInfrastructureAPI):
|
|||
callback.send(response)
|
||||
callback.close()
|
||||
|
||||
def get_deployment_host(self, future, host_name, callback):
|
||||
"""
|
||||
Get a host resource from the deployment namespace space
|
||||
"""
|
||||
response = dict()
|
||||
response['completed'] = False
|
||||
response['reason'] = ''
|
||||
|
||||
try:
|
||||
future.set_timeouts(config.CONF.get('nfvi-timeouts', None))
|
||||
|
||||
future.work(kubernetes_client.get_deployment_host, host_name)
|
||||
future.result = (yield)
|
||||
|
||||
if not future.result.is_complete():
|
||||
DLOG.error("Kubernetes get_deployment_host failed, operation "
|
||||
"did not complete, host_name=%s" % host_name)
|
||||
self.set_response_error(response, "Kubernetes get-deployment-host")
|
||||
return
|
||||
|
||||
response['result-data'] = future.result.data
|
||||
response['completed'] = True
|
||||
|
||||
except Exception as e:
|
||||
DLOG.exception("Caught exception while trying to get "
|
||||
"deployment hosts: %s, error=%s." % (host_name, e))
|
||||
|
||||
finally:
|
||||
callback.send(response)
|
||||
callback.close()
|
||||
|
||||
def list_deployment_hosts(self, future, callback):
|
||||
"""
|
||||
List a hosts resource from the deployment namespace space
|
||||
"""
|
||||
response = dict()
|
||||
response['completed'] = False
|
||||
response['reason'] = ''
|
||||
|
||||
try:
|
||||
future.set_timeouts(config.CONF.get('nfvi-timeouts', None))
|
||||
|
||||
future.work(kubernetes_client.list_deployment_hosts)
|
||||
future.result = (yield)
|
||||
|
||||
if not future.result.is_complete() or future.result.data is None:
|
||||
DLOG.error("Kubernetes list_deployment_hosts failed, operation "
|
||||
"did not complete.")
|
||||
self.set_response_error(response, "Kubernetes list-deployment-hosts")
|
||||
return
|
||||
|
||||
hosts = list()
|
||||
for host_data in future.result.data:
|
||||
host = nfvi.objects.v1.HostSystemConfigUpdate(
|
||||
host_data['name'], host_data['unlock_request'])
|
||||
hosts.append(host)
|
||||
|
||||
response['result-data'] = hosts
|
||||
response['completed'] = True
|
||||
|
||||
except Exception as e:
|
||||
DLOG.exception("Caught exception while trying to list "
|
||||
"deployment hosts, error=%s." % (e))
|
||||
|
||||
finally:
|
||||
callback.send(response)
|
||||
callback.close()
|
||||
|
||||
def get_system_config_unlock_request(self, future, host_names, callback):
|
||||
"""
|
||||
Get unlock request from host resource status
|
||||
"""
|
||||
response = dict()
|
||||
response['completed'] = False
|
||||
response['reason'] = ''
|
||||
|
||||
try:
|
||||
future.set_timeouts(config.CONF.get('nfvi-timeouts', None))
|
||||
result = list()
|
||||
for host_name in host_names:
|
||||
future.work(kubernetes_client.get_deployment_host, host_name)
|
||||
future.result = (yield)
|
||||
|
||||
if not future.result.is_complete():
|
||||
DLOG.error("Cannot get resource of host: %s from deployment "
|
||||
"namespace." % host_name)
|
||||
self.set_response_error(response, "Kubernetes get-deployment-host")
|
||||
return
|
||||
|
||||
if future.result.data['unlock_request'] != 'unlock_required':
|
||||
# The host is not ready for unlock, do not update the reason
|
||||
# as the the transitional status is expected.
|
||||
DLOG.debug("Host: %s is not ready for unlock." % host_name)
|
||||
return
|
||||
|
||||
host_resource = nfvi.objects.v1.HostSystemConfigUpdate(
|
||||
future.result.data['name'],
|
||||
future.result.data['unlock_request']
|
||||
)
|
||||
result.append(host_resource)
|
||||
|
||||
response['completed'] = True
|
||||
response['result-data'] = result
|
||||
|
||||
except Exception as e:
|
||||
DLOG.exception("Caught exception while trying to check the unlock "
|
||||
"requst from kubernetes deployment namespace %s, "
|
||||
"error=%s." % (host_name, e))
|
||||
finally:
|
||||
callback.send(response)
|
||||
callback.close()
|
||||
|
||||
def sw_update_rest_api_get_handler(self, request_dispatch):
|
||||
"""
|
||||
Software update Rest-API GET handler callback
|
||||
|
|
|
@ -282,3 +282,10 @@ class TestCLIKubeUpgradeStrategy(TestNFVClientShell,
|
|||
def required_create_fields(self):
|
||||
"""Kube Upgrade requires a to-version for create"""
|
||||
return ['--to-version=1.2.3']
|
||||
|
||||
|
||||
class TestSystemConfigUpdateStrategy(TestNFVClientShell,
|
||||
StrategyMixin):
|
||||
def setUp(self):
|
||||
super(TestSystemConfigUpdateStrategy, self).setUp()
|
||||
self.set_strategy('system-config-update-strategy')
|
||||
|
|
|
@ -434,3 +434,67 @@ class TestNFVPluginsK8SGetTerminatingPods(testcase.NFVTestCase):
|
|||
|
||||
assert result.result_data == \
|
||||
'test-pod-terminating,test-pod-terminating-2'
|
||||
|
||||
|
||||
@mock.patch('kubernetes.config.load_kube_config', mock_load_kube_config)
|
||||
class TestNFVPluginsK8SGetNamespacedRunningPods(testcase.NFVTestCase):
|
||||
|
||||
list_namespaced_pod_result = kubernetes.client.V1PodList(
|
||||
api_version="v1",
|
||||
items=[
|
||||
kubernetes.client.V1Pod(
|
||||
api_version="v1",
|
||||
kind="Pod",
|
||||
metadata=kubernetes.client.V1ObjectMeta(
|
||||
name="test-pod-not-found-1",
|
||||
namespace="test-namespace-1"),
|
||||
),
|
||||
kubernetes.client.V1Pod(
|
||||
api_version="v1",
|
||||
kind="Pod",
|
||||
metadata=kubernetes.client.V1ObjectMeta(
|
||||
name="test-pod-not-found-2",
|
||||
namespace="test-namespace-1"),
|
||||
),
|
||||
kubernetes.client.V1Pod(
|
||||
api_version="v1",
|
||||
kind="Pod",
|
||||
metadata=kubernetes.client.V1ObjectMeta(
|
||||
name="test-pod-found-1",
|
||||
namespace="test-namespace-1"),
|
||||
),
|
||||
kubernetes.client.V1Pod(
|
||||
api_version="v1",
|
||||
kind="Pod",
|
||||
metadata=kubernetes.client.V1ObjectMeta(
|
||||
name="test-pod-found-2",
|
||||
namespace="test-namespace-1"),
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
def setUp(self):
|
||||
super(TestNFVPluginsK8SGetNamespacedRunningPods, self).setUp()
|
||||
|
||||
def mock_list_namespaced_pod(obj, namespace, field_selector=""):
|
||||
return self.list_namespaced_pod_result
|
||||
|
||||
self.mocked_list_namespaced_pod = mock.patch(
|
||||
'kubernetes.client.CoreV1Api.list_namespaced_pod',
|
||||
mock_list_namespaced_pod)
|
||||
self.mocked_list_namespaced_pod.start()
|
||||
|
||||
def tearDown(self):
|
||||
super(TestNFVPluginsK8SGetNamespacedRunningPods, self).tearDown()
|
||||
|
||||
self.mocked_list_namespaced_pod.stop()
|
||||
|
||||
def test_get_terminating_with_two_terminating(self):
|
||||
|
||||
result = kubernetes_client.get_namespaced_running_pods(
|
||||
namespace="test-namespace-1",
|
||||
name="test-pod-found"
|
||||
)
|
||||
|
||||
assert result.result_data == \
|
||||
'test-pod-found-1,test-pod-found-2'
|
||||
|
|
|
@ -0,0 +1,790 @@
|
|||
#
|
||||
# Copyright (c) 2023 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
from unittest import mock
|
||||
import uuid
|
||||
|
||||
from nfv_common import strategy as common_strategy
|
||||
from nfv_vim import nfvi
|
||||
|
||||
from nfv_vim.objects import SW_UPDATE_ALARM_RESTRICTION
|
||||
from nfv_vim.objects import SW_UPDATE_APPLY_TYPE
|
||||
from nfv_vim.objects import SW_UPDATE_INSTANCE_ACTION
|
||||
from nfv_vim.objects import SystemConfigUpdate
|
||||
from nfv_vim.strategy._strategy import SystemConfigUpdateStrategy
|
||||
|
||||
from nfv_unit_tests.tests import sw_update_testcase
|
||||
|
||||
|
||||
@mock.patch('nfv_vim.event_log._instance._event_issue',
|
||||
sw_update_testcase.fake_event_issue)
|
||||
@mock.patch('nfv_vim.objects._sw_update.SwUpdate.save',
|
||||
sw_update_testcase.fake_save)
|
||||
@mock.patch('nfv_vim.objects._sw_update.timers.timers_create_timer',
|
||||
sw_update_testcase.fake_timer)
|
||||
@mock.patch('nfv_vim.nfvi.nfvi_compute_plugin_disabled',
|
||||
sw_update_testcase.fake_nfvi_compute_plugin_disabled)
|
||||
class TestSystemConfigUpdateStrategy(sw_update_testcase.SwUpdateStrategyTestCase):
|
||||
|
||||
def _create_system_config_update_strategy(self,
|
||||
sw_update_obj,
|
||||
controller_apply_type=SW_UPDATE_APPLY_TYPE.SERIAL,
|
||||
storage_apply_type=SW_UPDATE_APPLY_TYPE.SERIAL,
|
||||
worker_apply_type=SW_UPDATE_APPLY_TYPE.SERIAL,
|
||||
max_parallel_worker_hosts=10,
|
||||
default_instance_action=SW_UPDATE_INSTANCE_ACTION.STOP_START,
|
||||
alarm_restrictions=SW_UPDATE_ALARM_RESTRICTION.STRICT,
|
||||
single_controller=False,
|
||||
nfvi_system_config_update_hosts=None):
|
||||
"""
|
||||
Create a system config update strategy
|
||||
"""
|
||||
strategy = SystemConfigUpdateStrategy(
|
||||
uuid=str(uuid.uuid4()),
|
||||
controller_apply_type=controller_apply_type,
|
||||
storage_apply_type=storage_apply_type,
|
||||
worker_apply_type=worker_apply_type,
|
||||
max_parallel_worker_hosts=max_parallel_worker_hosts,
|
||||
default_instance_action=default_instance_action,
|
||||
alarm_restrictions=alarm_restrictions,
|
||||
single_controller=single_controller,
|
||||
ignore_alarms=[])
|
||||
|
||||
strategy.sw_update_obj = sw_update_obj
|
||||
strategy.nfvi_system_config_update_hosts = nfvi_system_config_update_hosts
|
||||
return strategy
|
||||
|
||||
@mock.patch('nfv_common.strategy._strategy.Strategy._build')
|
||||
def test_system_config_update_strategy_build_steps(self, fake_build):
|
||||
"""
|
||||
Verify build phases, etc.. for system config update strategy creation.
|
||||
"""
|
||||
# setup a minimal host environment
|
||||
self.create_host('controller-0', aio=True)
|
||||
|
||||
# construct the strategy. the update_obj MUST be declared here and not
|
||||
# in the create method, because it is a weakref and will be cleaned up
|
||||
# when it goes out of scope.
|
||||
update_obj = SystemConfigUpdate()
|
||||
strategy = self._create_system_config_update_strategy(update_obj)
|
||||
# The 'build' constructs a strategy that includes multiple queries
|
||||
# the results of those queries are not used until build_complete
|
||||
# mock away '_build', which invokes the build steps and their api calls
|
||||
fake_build.return_value = None
|
||||
strategy.build()
|
||||
|
||||
# verify the build phase and steps
|
||||
build_phase = strategy.build_phase.as_dict()
|
||||
|
||||
query_steps = [
|
||||
{'name': 'query-alarms'},
|
||||
{'name': 'query-system-config-update-hosts'},
|
||||
]
|
||||
expected_results = {
|
||||
'total_stages': 1,
|
||||
'stages': [
|
||||
{'name': 'system-config-update-query',
|
||||
'total_steps': len(query_steps),
|
||||
'steps': query_steps,
|
||||
},
|
||||
],
|
||||
}
|
||||
sw_update_testcase.validate_phase(build_phase, expected_results)
|
||||
|
||||
def temp_log(self, txt):
|
||||
with open('./tbd.txt', 'a') as f:
|
||||
f.write(txt + "\n")
|
||||
|
||||
@mock.patch('nfv_common.strategy._strategy.Strategy._build')
|
||||
def test_apply_system_config_update_strategy_simplex(self, fake_build):
|
||||
|
||||
self.create_host('controller-0', aio=True)
|
||||
|
||||
update_obj = SystemConfigUpdate()
|
||||
nfvi_system_config_update_hosts = list()
|
||||
controller_0_resource = nfvi.objects.v1.HostSystemConfigUpdate(
|
||||
'controller-0', 'lock_required')
|
||||
nfvi_system_config_update_hosts.append(controller_0_resource)
|
||||
|
||||
strategy = self._create_system_config_update_strategy(
|
||||
update_obj,
|
||||
single_controller=True,
|
||||
nfvi_system_config_update_hosts=nfvi_system_config_update_hosts)
|
||||
|
||||
strategy.build_complete(common_strategy.STRATEGY_RESULT.SUCCESS, "")
|
||||
self.assertFalse(strategy.is_build_failed())
|
||||
self.assertEqual(strategy.build_phase.result_reason, "")
|
||||
|
||||
apply_phase = strategy.apply_phase.as_dict()
|
||||
|
||||
expected_results = {
|
||||
'total_stages': 1,
|
||||
'stages': [
|
||||
{
|
||||
'name': "system-config-update-worker-hosts",
|
||||
'total_steps': 6,
|
||||
'steps': [
|
||||
{'name': 'query-alarms'},
|
||||
{'name': 'lock-hosts',
|
||||
'entity_names': ['controller-0']},
|
||||
{'name': 'system-config-update-hosts',
|
||||
'entity_names': ['controller-0']},
|
||||
{'name': 'system-stabilize',
|
||||
'timeout': 15},
|
||||
{'name': 'unlock-hosts',
|
||||
'entity_names': ['controller-0']},
|
||||
{'name': 'wait-alarms-clear',
|
||||
'timeout': 1800},
|
||||
]
|
||||
},
|
||||
]
|
||||
}
|
||||
sw_update_testcase.validate_strategy_persists(strategy)
|
||||
sw_update_testcase.validate_phase(apply_phase, expected_results)
|
||||
|
||||
@mock.patch('nfv_common.strategy._strategy.Strategy._build')
|
||||
def test_apply_system_config_update_strategy_duplex(self, fake_build):
|
||||
|
||||
self.create_host('controller-0', aio=True)
|
||||
self.create_host('controller-1', aio=True)
|
||||
|
||||
update_obj = SystemConfigUpdate()
|
||||
nfvi_system_config_update_hosts = list()
|
||||
controller_0_resource = nfvi.objects.v1.HostSystemConfigUpdate(
|
||||
'controller-0', 'lock_required')
|
||||
controller_1_resource = nfvi.objects.v1.HostSystemConfigUpdate(
|
||||
'controller-1', 'lock_required')
|
||||
nfvi_system_config_update_hosts.append(controller_0_resource)
|
||||
nfvi_system_config_update_hosts.append(controller_1_resource)
|
||||
|
||||
strategy = self._create_system_config_update_strategy(
|
||||
update_obj,
|
||||
nfvi_system_config_update_hosts=nfvi_system_config_update_hosts)
|
||||
|
||||
strategy.build_complete(common_strategy.STRATEGY_RESULT.SUCCESS, "")
|
||||
self.assertFalse(strategy.is_build_failed())
|
||||
self.assertEqual(strategy.build_phase.result_reason, "")
|
||||
|
||||
apply_phase = strategy.apply_phase.as_dict()
|
||||
|
||||
expected_results = {
|
||||
'total_stages': 2,
|
||||
'stages': [
|
||||
{
|
||||
'name': "system-config-update-worker-hosts",
|
||||
'total_steps': 7,
|
||||
'steps': [
|
||||
{'name': 'query-alarms'},
|
||||
{'name': 'swact-hosts',
|
||||
'entity_names': ['controller-0']},
|
||||
{'name': 'lock-hosts',
|
||||
'entity_names': ['controller-0']},
|
||||
{'name': 'system-config-update-hosts',
|
||||
'entity_names': ['controller-0']},
|
||||
{'name': 'system-stabilize',
|
||||
'timeout': 15},
|
||||
{'name': 'unlock-hosts',
|
||||
'entity_names': ['controller-0']},
|
||||
{'name': 'wait-alarms-clear',
|
||||
'timeout': 1800},
|
||||
]
|
||||
},
|
||||
{
|
||||
'name': "system-config-update-worker-hosts",
|
||||
'total_steps': 7,
|
||||
'steps': [
|
||||
{'name': 'query-alarms'},
|
||||
{'name': 'swact-hosts',
|
||||
'entity_names': ['controller-1']},
|
||||
{'name': 'lock-hosts',
|
||||
'entity_names': ['controller-1']},
|
||||
{'name': 'system-config-update-hosts',
|
||||
'entity_names': ['controller-1']},
|
||||
{'name': 'system-stabilize',
|
||||
'timeout': 15},
|
||||
{'name': 'unlock-hosts',
|
||||
'entity_names': ['controller-1']},
|
||||
{'name': 'wait-alarms-clear',
|
||||
'timeout': 1800},
|
||||
]
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
sw_update_testcase.validate_strategy_persists(strategy)
|
||||
sw_update_testcase.validate_phase(apply_phase, expected_results)
|
||||
|
||||
@mock.patch('nfv_common.strategy._strategy.Strategy._build')
|
||||
def test_apply_system_config_update_strategy_standard_serial(self, fake_build):
|
||||
|
||||
self.create_host('controller-0')
|
||||
self.create_host('controller-1')
|
||||
self.create_host('storage-0')
|
||||
self.create_host('storage-1')
|
||||
self.create_host('compute-0')
|
||||
self.create_host('compute-1')
|
||||
|
||||
update_obj = SystemConfigUpdate()
|
||||
nfvi_system_config_update_hosts = list()
|
||||
controller_0_resource = nfvi.objects.v1.HostSystemConfigUpdate(
|
||||
'controller-0', 'lock_required')
|
||||
controller_1_resource = nfvi.objects.v1.HostSystemConfigUpdate(
|
||||
'controller-1', 'lock_required')
|
||||
compute_0_resource = nfvi.objects.v1.HostSystemConfigUpdate(
|
||||
'compute-0', 'lock_required')
|
||||
compute_1_resource = nfvi.objects.v1.HostSystemConfigUpdate(
|
||||
'compute-1', 'lock_required')
|
||||
storage_0_resource = nfvi.objects.v1.HostSystemConfigUpdate(
|
||||
'storage-0', 'lock_required')
|
||||
storage_1_resource = nfvi.objects.v1.HostSystemConfigUpdate(
|
||||
'storage-1', 'lock_required')
|
||||
nfvi_system_config_update_hosts.append(controller_0_resource)
|
||||
nfvi_system_config_update_hosts.append(controller_1_resource)
|
||||
nfvi_system_config_update_hosts.append(compute_0_resource)
|
||||
nfvi_system_config_update_hosts.append(compute_1_resource)
|
||||
nfvi_system_config_update_hosts.append(storage_0_resource)
|
||||
nfvi_system_config_update_hosts.append(storage_1_resource)
|
||||
|
||||
strategy = self._create_system_config_update_strategy(
|
||||
update_obj,
|
||||
nfvi_system_config_update_hosts=nfvi_system_config_update_hosts)
|
||||
|
||||
strategy.build_complete(common_strategy.STRATEGY_RESULT.SUCCESS, "")
|
||||
self.assertFalse(strategy.is_build_failed())
|
||||
self.assertEqual(strategy.build_phase.result_reason, "")
|
||||
|
||||
apply_phase = strategy.apply_phase.as_dict()
|
||||
|
||||
expected_results = {
|
||||
'total_stages': 6,
|
||||
'stages': [
|
||||
{
|
||||
'name': "system-config-update-controllers",
|
||||
'total_steps': 7,
|
||||
'steps': [
|
||||
{'name': 'query-alarms'},
|
||||
{'name': 'swact-hosts',
|
||||
'entity_names': ['controller-0']},
|
||||
{'name': 'lock-hosts',
|
||||
'entity_names': ['controller-0']},
|
||||
{'name': 'system-config-update-hosts',
|
||||
'entity_names': ['controller-0']},
|
||||
{'name': 'system-stabilize',
|
||||
'timeout': 15},
|
||||
{'name': 'unlock-hosts',
|
||||
'entity_names': ['controller-0']},
|
||||
{'name': 'wait-alarms-clear',
|
||||
'timeout': 1800},
|
||||
]
|
||||
},
|
||||
{
|
||||
'name': "system-config-update-controllers",
|
||||
'total_steps': 7,
|
||||
'steps': [
|
||||
{'name': 'query-alarms'},
|
||||
{'name': 'swact-hosts',
|
||||
'entity_names': ['controller-1']},
|
||||
{'name': 'lock-hosts',
|
||||
'entity_names': ['controller-1']},
|
||||
{'name': 'system-config-update-hosts',
|
||||
'entity_names': ['controller-1']},
|
||||
{'name': 'system-stabilize',
|
||||
'timeout': 15},
|
||||
{'name': 'unlock-hosts',
|
||||
'entity_names': ['controller-1']},
|
||||
{'name': 'wait-alarms-clear',
|
||||
'timeout': 1800},
|
||||
]
|
||||
},
|
||||
{
|
||||
'name': "system-config-update-storage-hosts",
|
||||
'total_steps': 6,
|
||||
'steps': [
|
||||
{'name': 'query-alarms'},
|
||||
{'name': 'lock-hosts',
|
||||
'entity_names': ['storage-0']},
|
||||
{'name': 'system-config-update-hosts',
|
||||
'entity_names': ['storage-0']},
|
||||
{'name': 'system-stabilize',
|
||||
'timeout': 15},
|
||||
{'name': 'unlock-hosts',
|
||||
'entity_names': ['storage-0']},
|
||||
{'name': 'wait-data-sync',
|
||||
'timeout': 1800},
|
||||
]
|
||||
},
|
||||
{
|
||||
'name': "system-config-update-storage-hosts",
|
||||
'total_steps': 6,
|
||||
'steps': [
|
||||
{'name': 'query-alarms'},
|
||||
{'name': 'lock-hosts',
|
||||
'entity_names': ['storage-1']},
|
||||
{'name': 'system-config-update-hosts',
|
||||
'entity_names': ['storage-1']},
|
||||
{'name': 'system-stabilize',
|
||||
'timeout': 15},
|
||||
{'name': 'unlock-hosts',
|
||||
'entity_names': ['storage-1']},
|
||||
{'name': 'wait-data-sync',
|
||||
'timeout': 1800},
|
||||
]
|
||||
},
|
||||
{
|
||||
'name': "system-config-update-worker-hosts",
|
||||
'total_steps': 6,
|
||||
'steps': [
|
||||
{'name': 'query-alarms'},
|
||||
{'name': 'lock-hosts',
|
||||
'entity_names': ['compute-0']},
|
||||
{'name': 'system-config-update-hosts',
|
||||
'entity_names': ['compute-0']},
|
||||
{'name': 'system-stabilize',
|
||||
'timeout': 15},
|
||||
{'name': 'unlock-hosts',
|
||||
'entity_names': ['compute-0']},
|
||||
{'name': 'wait-alarms-clear',
|
||||
'timeout': 600},
|
||||
]
|
||||
},
|
||||
{
|
||||
'name': "system-config-update-worker-hosts",
|
||||
'total_steps': 6,
|
||||
'steps': [
|
||||
{'name': 'query-alarms'},
|
||||
{'name': 'lock-hosts',
|
||||
'entity_names': ['compute-1']},
|
||||
{'name': 'system-config-update-hosts',
|
||||
'entity_names': ['compute-1']},
|
||||
{'name': 'system-stabilize',
|
||||
'timeout': 15},
|
||||
{'name': 'unlock-hosts',
|
||||
'entity_names': ['compute-1']},
|
||||
{'name': 'wait-alarms-clear',
|
||||
'timeout': 600},
|
||||
]
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
sw_update_testcase.validate_strategy_persists(strategy)
|
||||
sw_update_testcase.validate_phase(apply_phase, expected_results)
|
||||
|
||||
@mock.patch('nfv_common.strategy._strategy.Strategy._build')
|
||||
def test_apply_system_config_update_strategy_standard_parallel_worker(self, fake_build):
|
||||
|
||||
self.create_host('controller-0')
|
||||
self.create_host('controller-1')
|
||||
self.create_host('storage-0')
|
||||
self.create_host('storage-1')
|
||||
self.create_host('compute-0')
|
||||
self.create_host('compute-1')
|
||||
|
||||
update_obj = SystemConfigUpdate()
|
||||
nfvi_system_config_update_hosts = list()
|
||||
controller_0_resource = nfvi.objects.v1.HostSystemConfigUpdate(
|
||||
'controller-0', 'lock_required')
|
||||
controller_1_resource = nfvi.objects.v1.HostSystemConfigUpdate(
|
||||
'controller-1', 'lock_required')
|
||||
compute_0_resource = nfvi.objects.v1.HostSystemConfigUpdate(
|
||||
'compute-0', 'lock_required')
|
||||
compute_1_resource = nfvi.objects.v1.HostSystemConfigUpdate(
|
||||
'compute-1', 'lock_required')
|
||||
storage_0_resource = nfvi.objects.v1.HostSystemConfigUpdate(
|
||||
'storage-0', 'lock_required')
|
||||
storage_1_resource = nfvi.objects.v1.HostSystemConfigUpdate(
|
||||
'storage-1', 'lock_required')
|
||||
nfvi_system_config_update_hosts.append(controller_0_resource)
|
||||
nfvi_system_config_update_hosts.append(controller_1_resource)
|
||||
nfvi_system_config_update_hosts.append(compute_0_resource)
|
||||
nfvi_system_config_update_hosts.append(compute_1_resource)
|
||||
nfvi_system_config_update_hosts.append(storage_0_resource)
|
||||
nfvi_system_config_update_hosts.append(storage_1_resource)
|
||||
|
||||
strategy = self._create_system_config_update_strategy(
|
||||
update_obj,
|
||||
worker_apply_type=SW_UPDATE_APPLY_TYPE.PARALLEL,
|
||||
nfvi_system_config_update_hosts=nfvi_system_config_update_hosts)
|
||||
|
||||
strategy.build_complete(common_strategy.STRATEGY_RESULT.SUCCESS, "")
|
||||
self.assertFalse(strategy.is_build_failed())
|
||||
self.assertEqual(strategy.build_phase.result_reason, "")
|
||||
|
||||
apply_phase = strategy.apply_phase.as_dict()
|
||||
|
||||
expected_results = {
|
||||
'total_stages': 5,
|
||||
'stages': [
|
||||
{
|
||||
'name': "system-config-update-controllers",
|
||||
'total_steps': 7,
|
||||
'steps': [
|
||||
{'name': 'query-alarms'},
|
||||
{'name': 'swact-hosts',
|
||||
'entity_names': ['controller-0']},
|
||||
{'name': 'lock-hosts',
|
||||
'entity_names': ['controller-0']},
|
||||
{'name': 'system-config-update-hosts',
|
||||
'entity_names': ['controller-0']},
|
||||
{'name': 'system-stabilize',
|
||||
'timeout': 15},
|
||||
{'name': 'unlock-hosts',
|
||||
'entity_names': ['controller-0']},
|
||||
{'name': 'wait-alarms-clear',
|
||||
'timeout': 1800},
|
||||
]
|
||||
},
|
||||
{
|
||||
'name': "system-config-update-controllers",
|
||||
'total_steps': 7,
|
||||
'steps': [
|
||||
{'name': 'query-alarms'},
|
||||
{'name': 'swact-hosts',
|
||||
'entity_names': ['controller-1']},
|
||||
{'name': 'lock-hosts',
|
||||
'entity_names': ['controller-1']},
|
||||
{'name': 'system-config-update-hosts',
|
||||
'entity_names': ['controller-1']},
|
||||
{'name': 'system-stabilize',
|
||||
'timeout': 15},
|
||||
{'name': 'unlock-hosts',
|
||||
'entity_names': ['controller-1']},
|
||||
{'name': 'wait-alarms-clear',
|
||||
'timeout': 1800},
|
||||
]
|
||||
},
|
||||
{
|
||||
'name': "system-config-update-storage-hosts",
|
||||
'total_steps': 6,
|
||||
'steps': [
|
||||
{'name': 'query-alarms'},
|
||||
{'name': 'lock-hosts',
|
||||
'entity_names': ['storage-0']},
|
||||
{'name': 'system-config-update-hosts',
|
||||
'entity_names': ['storage-0']},
|
||||
{'name': 'system-stabilize',
|
||||
'timeout': 15},
|
||||
{'name': 'unlock-hosts',
|
||||
'entity_names': ['storage-0']},
|
||||
{'name': 'wait-data-sync',
|
||||
'timeout': 1800},
|
||||
]
|
||||
},
|
||||
{
|
||||
'name': "system-config-update-storage-hosts",
|
||||
'total_steps': 6,
|
||||
'steps': [
|
||||
{'name': 'query-alarms'},
|
||||
{'name': 'lock-hosts',
|
||||
'entity_names': ['storage-1']},
|
||||
{'name': 'system-config-update-hosts',
|
||||
'entity_names': ['storage-1']},
|
||||
{'name': 'system-stabilize',
|
||||
'timeout': 15},
|
||||
{'name': 'unlock-hosts',
|
||||
'entity_names': ['storage-1']},
|
||||
{'name': 'wait-data-sync',
|
||||
'timeout': 1800},
|
||||
]
|
||||
},
|
||||
{
|
||||
'name': "system-config-update-worker-hosts",
|
||||
'total_steps': 6,
|
||||
'steps': [
|
||||
{'name': 'query-alarms'},
|
||||
{'name': 'lock-hosts',
|
||||
'entity_names': ['compute-0', 'compute-1']},
|
||||
{'name': 'system-config-update-hosts',
|
||||
'entity_names': ['compute-0', 'compute-1']},
|
||||
{'name': 'system-stabilize',
|
||||
'timeout': 15},
|
||||
{'name': 'unlock-hosts',
|
||||
'entity_names': ['compute-0', 'compute-1']},
|
||||
{'name': 'wait-alarms-clear',
|
||||
'timeout': 600},
|
||||
]
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
sw_update_testcase.validate_strategy_persists(strategy)
|
||||
sw_update_testcase.validate_phase(apply_phase, expected_results)
|
||||
|
||||
@mock.patch('nfv_common.strategy._strategy.Strategy._build')
|
||||
def test_apply_system_config_update_strategy_host_not_required(self, fake_build):
|
||||
|
||||
self.create_host('controller-0')
|
||||
self.create_host('controller-1')
|
||||
self.create_host('storage-0')
|
||||
self.create_host('storage-1')
|
||||
self.create_host('compute-0')
|
||||
self.create_host('compute-1')
|
||||
|
||||
update_obj = SystemConfigUpdate()
|
||||
nfvi_system_config_update_hosts = list()
|
||||
controller_0_resource = nfvi.objects.v1.HostSystemConfigUpdate(
|
||||
'controller-0', 'lock_required')
|
||||
controller_1_resource = nfvi.objects.v1.HostSystemConfigUpdate(
|
||||
'controller-1', 'not_required')
|
||||
compute_0_resource = nfvi.objects.v1.HostSystemConfigUpdate(
|
||||
'compute-0', 'lock_required')
|
||||
compute_1_resource = nfvi.objects.v1.HostSystemConfigUpdate(
|
||||
'compute-1', 'not_required')
|
||||
storage_0_resource = nfvi.objects.v1.HostSystemConfigUpdate(
|
||||
'storage-0', 'not_required')
|
||||
storage_1_resource = nfvi.objects.v1.HostSystemConfigUpdate(
|
||||
'storage-1', 'lock_required')
|
||||
nfvi_system_config_update_hosts.append(controller_0_resource)
|
||||
nfvi_system_config_update_hosts.append(controller_1_resource)
|
||||
nfvi_system_config_update_hosts.append(compute_0_resource)
|
||||
nfvi_system_config_update_hosts.append(compute_1_resource)
|
||||
nfvi_system_config_update_hosts.append(storage_0_resource)
|
||||
nfvi_system_config_update_hosts.append(storage_1_resource)
|
||||
|
||||
strategy = self._create_system_config_update_strategy(
|
||||
update_obj,
|
||||
worker_apply_type=SW_UPDATE_APPLY_TYPE.PARALLEL,
|
||||
nfvi_system_config_update_hosts=nfvi_system_config_update_hosts)
|
||||
|
||||
strategy.build_complete(common_strategy.STRATEGY_RESULT.SUCCESS, "")
|
||||
self.assertFalse(strategy.is_build_failed())
|
||||
self.assertEqual(strategy.build_phase.result_reason, "")
|
||||
|
||||
apply_phase = strategy.apply_phase.as_dict()
|
||||
|
||||
expected_results = {
|
||||
'total_stages': 3,
|
||||
'stages': [
|
||||
{
|
||||
'name': "system-config-update-controllers",
|
||||
'total_steps': 7,
|
||||
'steps': [
|
||||
{'name': 'query-alarms'},
|
||||
{'name': 'swact-hosts',
|
||||
'entity_names': ['controller-0']},
|
||||
{'name': 'lock-hosts',
|
||||
'entity_names': ['controller-0']},
|
||||
{'name': 'system-config-update-hosts',
|
||||
'entity_names': ['controller-0']},
|
||||
{'name': 'system-stabilize',
|
||||
'timeout': 15},
|
||||
{'name': 'unlock-hosts',
|
||||
'entity_names': ['controller-0']},
|
||||
{'name': 'wait-alarms-clear',
|
||||
'timeout': 1800},
|
||||
]
|
||||
},
|
||||
{
|
||||
'name': "system-config-update-storage-hosts",
|
||||
'total_steps': 6,
|
||||
'steps': [
|
||||
{'name': 'query-alarms'},
|
||||
{'name': 'lock-hosts',
|
||||
'entity_names': ['storage-1']},
|
||||
{'name': 'system-config-update-hosts',
|
||||
'entity_names': ['storage-1']},
|
||||
{'name': 'system-stabilize',
|
||||
'timeout': 15},
|
||||
{'name': 'unlock-hosts',
|
||||
'entity_names': ['storage-1']},
|
||||
{'name': 'wait-data-sync',
|
||||
'timeout': 1800},
|
||||
]
|
||||
},
|
||||
{
|
||||
'name': "system-config-update-worker-hosts",
|
||||
'total_steps': 6,
|
||||
'steps': [
|
||||
{'name': 'query-alarms'},
|
||||
{'name': 'lock-hosts',
|
||||
'entity_names': ['compute-0']},
|
||||
{'name': 'system-config-update-hosts',
|
||||
'entity_names': ['compute-0']},
|
||||
{'name': 'system-stabilize',
|
||||
'timeout': 15},
|
||||
{'name': 'unlock-hosts',
|
||||
'entity_names': ['compute-0']},
|
||||
{'name': 'wait-alarms-clear',
|
||||
'timeout': 600},
|
||||
]
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
sw_update_testcase.validate_strategy_persists(strategy)
|
||||
sw_update_testcase.validate_phase(apply_phase, expected_results)
|
||||
|
||||
@mock.patch('nfv_common.strategy._strategy.Strategy._build')
|
||||
def test_apply_system_config_update_strategy_controller_ignore(self, fake_build):
|
||||
|
||||
self.create_host('controller-0')
|
||||
self.create_host('controller-1')
|
||||
self.create_host('storage-0')
|
||||
self.create_host('storage-1')
|
||||
self.create_host('compute-0')
|
||||
self.create_host('compute-1')
|
||||
|
||||
update_obj = SystemConfigUpdate()
|
||||
nfvi_system_config_update_hosts = list()
|
||||
controller_0_resource = nfvi.objects.v1.HostSystemConfigUpdate(
|
||||
'controller-0', 'lock_required')
|
||||
controller_1_resource = nfvi.objects.v1.HostSystemConfigUpdate(
|
||||
'controller-1', 'not_required')
|
||||
compute_0_resource = nfvi.objects.v1.HostSystemConfigUpdate(
|
||||
'compute-0', 'lock_required')
|
||||
compute_1_resource = nfvi.objects.v1.HostSystemConfigUpdate(
|
||||
'compute-1', 'not_required')
|
||||
storage_0_resource = nfvi.objects.v1.HostSystemConfigUpdate(
|
||||
'storage-0', 'not_required')
|
||||
storage_1_resource = nfvi.objects.v1.HostSystemConfigUpdate(
|
||||
'storage-1', 'lock_required')
|
||||
nfvi_system_config_update_hosts.append(controller_0_resource)
|
||||
nfvi_system_config_update_hosts.append(controller_1_resource)
|
||||
nfvi_system_config_update_hosts.append(compute_0_resource)
|
||||
nfvi_system_config_update_hosts.append(compute_1_resource)
|
||||
nfvi_system_config_update_hosts.append(storage_0_resource)
|
||||
nfvi_system_config_update_hosts.append(storage_1_resource)
|
||||
|
||||
strategy = self._create_system_config_update_strategy(
|
||||
update_obj,
|
||||
controller_apply_type=SW_UPDATE_APPLY_TYPE.IGNORE,
|
||||
worker_apply_type=SW_UPDATE_APPLY_TYPE.PARALLEL,
|
||||
nfvi_system_config_update_hosts=nfvi_system_config_update_hosts)
|
||||
|
||||
strategy.build_complete(common_strategy.STRATEGY_RESULT.SUCCESS, "")
|
||||
self.assertFalse(strategy.is_build_failed())
|
||||
self.assertEqual(strategy.build_phase.result_reason, "")
|
||||
|
||||
apply_phase = strategy.apply_phase.as_dict()
|
||||
|
||||
expected_results = {
|
||||
'total_stages': 2,
|
||||
'stages': [
|
||||
{
|
||||
'name': "system-config-update-storage-hosts",
|
||||
'total_steps': 6,
|
||||
'steps': [
|
||||
{'name': 'query-alarms'},
|
||||
{'name': 'lock-hosts',
|
||||
'entity_names': ['storage-1']},
|
||||
{'name': 'system-config-update-hosts',
|
||||
'entity_names': ['storage-1']},
|
||||
{'name': 'system-stabilize',
|
||||
'timeout': 15},
|
||||
{'name': 'unlock-hosts',
|
||||
'entity_names': ['storage-1']},
|
||||
{'name': 'wait-data-sync',
|
||||
'timeout': 1800},
|
||||
]
|
||||
},
|
||||
{
|
||||
'name': "system-config-update-worker-hosts",
|
||||
'total_steps': 6,
|
||||
'steps': [
|
||||
{'name': 'query-alarms'},
|
||||
{'name': 'lock-hosts',
|
||||
'entity_names': ['compute-0']},
|
||||
{'name': 'system-config-update-hosts',
|
||||
'entity_names': ['compute-0']},
|
||||
{'name': 'system-stabilize',
|
||||
'timeout': 15},
|
||||
{'name': 'unlock-hosts',
|
||||
'entity_names': ['compute-0']},
|
||||
{'name': 'wait-alarms-clear',
|
||||
'timeout': 600},
|
||||
]
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
sw_update_testcase.validate_strategy_persists(strategy)
|
||||
sw_update_testcase.validate_phase(apply_phase, expected_results)
|
||||
|
||||
@mock.patch('nfv_common.strategy._strategy.Strategy._build')
|
||||
def test_apply_system_config_update_strategy_worker_ignore(self, fake_build):
|
||||
|
||||
self.create_host('controller-0')
|
||||
self.create_host('controller-1')
|
||||
self.create_host('storage-0')
|
||||
self.create_host('storage-1')
|
||||
self.create_host('compute-0')
|
||||
self.create_host('compute-1')
|
||||
|
||||
update_obj = SystemConfigUpdate()
|
||||
nfvi_system_config_update_hosts = list()
|
||||
controller_0_resource = nfvi.objects.v1.HostSystemConfigUpdate(
|
||||
'controller-0', 'lock_required')
|
||||
controller_1_resource = nfvi.objects.v1.HostSystemConfigUpdate(
|
||||
'controller-1', 'not_required')
|
||||
compute_0_resource = nfvi.objects.v1.HostSystemConfigUpdate(
|
||||
'compute-0', 'lock_required')
|
||||
compute_1_resource = nfvi.objects.v1.HostSystemConfigUpdate(
|
||||
'compute-1', 'not_required')
|
||||
storage_0_resource = nfvi.objects.v1.HostSystemConfigUpdate(
|
||||
'storage-0', 'not_required')
|
||||
storage_1_resource = nfvi.objects.v1.HostSystemConfigUpdate(
|
||||
'storage-1', 'lock_required')
|
||||
nfvi_system_config_update_hosts.append(controller_0_resource)
|
||||
nfvi_system_config_update_hosts.append(controller_1_resource)
|
||||
nfvi_system_config_update_hosts.append(compute_0_resource)
|
||||
nfvi_system_config_update_hosts.append(compute_1_resource)
|
||||
nfvi_system_config_update_hosts.append(storage_0_resource)
|
||||
nfvi_system_config_update_hosts.append(storage_1_resource)
|
||||
|
||||
strategy = self._create_system_config_update_strategy(
|
||||
update_obj,
|
||||
worker_apply_type=SW_UPDATE_APPLY_TYPE.IGNORE,
|
||||
nfvi_system_config_update_hosts=nfvi_system_config_update_hosts)
|
||||
|
||||
strategy.build_complete(common_strategy.STRATEGY_RESULT.SUCCESS, "")
|
||||
self.assertFalse(strategy.is_build_failed())
|
||||
self.assertEqual(strategy.build_phase.result_reason, "")
|
||||
|
||||
apply_phase = strategy.apply_phase.as_dict()
|
||||
|
||||
expected_results = {
|
||||
'total_stages': 2,
|
||||
'stages': [
|
||||
{
|
||||
'name': "system-config-update-controllers",
|
||||
'total_steps': 7,
|
||||
'steps': [
|
||||
{'name': 'query-alarms'},
|
||||
{'name': 'swact-hosts',
|
||||
'entity_names': ['controller-0']},
|
||||
{'name': 'lock-hosts',
|
||||
'entity_names': ['controller-0']},
|
||||
{'name': 'system-config-update-hosts',
|
||||
'entity_names': ['controller-0']},
|
||||
{'name': 'system-stabilize',
|
||||
'timeout': 15},
|
||||
{'name': 'unlock-hosts',
|
||||
'entity_names': ['controller-0']},
|
||||
{'name': 'wait-alarms-clear',
|
||||
'timeout': 1800},
|
||||
]
|
||||
},
|
||||
{
|
||||
'name': "system-config-update-storage-hosts",
|
||||
'total_steps': 6,
|
||||
'steps': [
|
||||
{'name': 'query-alarms'},
|
||||
{'name': 'lock-hosts',
|
||||
'entity_names': ['storage-1']},
|
||||
{'name': 'system-config-update-hosts',
|
||||
'entity_names': ['storage-1']},
|
||||
{'name': 'system-stabilize',
|
||||
'timeout': 15},
|
||||
{'name': 'unlock-hosts',
|
||||
'entity_names': ['storage-1']},
|
||||
{'name': 'wait-data-sync',
|
||||
'timeout': 1800},
|
||||
]
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
sw_update_testcase.validate_strategy_persists(strategy)
|
||||
sw_update_testcase.validate_phase(apply_phase, expected_results)
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2016-2021 Wind River Systems, Inc.
|
||||
# Copyright (c) 2016-2023 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -188,6 +188,42 @@ _alarm_templates = {
|
|||
"problem persists contact next level of support"),
|
||||
'exclude_alarm_context': [alarm.ALARM_CONTEXT.TENANT],
|
||||
},
|
||||
|
||||
alarm.ALARM_TYPE.SYSTEM_CONFIG_UPDATE_AUTO_APPLY_INPROGRESS: {
|
||||
'entity_type': "orchestration",
|
||||
'entity': "orchestration=system-config-update",
|
||||
'event_type': alarm.ALARM_EVENT_TYPE.EQUIPMENT_ALARM,
|
||||
'severity': alarm.ALARM_SEVERITY.MAJOR,
|
||||
'probable_cause': alarm.ALARM_PROBABLE_CAUSE.UNKNOWN,
|
||||
'reason_text': "System config update auto-apply inprogress",
|
||||
'repair_action': ("Wait for system config update auto-apply to "
|
||||
"complete; if problem persists contact next "
|
||||
"level of support"),
|
||||
'exclude_alarm_context': [alarm.ALARM_CONTEXT.TENANT],
|
||||
},
|
||||
alarm.ALARM_TYPE.SYSTEM_CONFIG_UPDATE_AUTO_APPLY_ABORTING: {
|
||||
'entity_type': "orchestration",
|
||||
'entity': "orchestration=system-config-update",
|
||||
'event_type': alarm.ALARM_EVENT_TYPE.EQUIPMENT_ALARM,
|
||||
'severity': alarm.ALARM_SEVERITY.MAJOR,
|
||||
'probable_cause': alarm.ALARM_PROBABLE_CAUSE.UNKNOWN,
|
||||
'reason_text': "System config update auto-apply aborting",
|
||||
'repair_action': ("Wait for system config update auto-apply abort "
|
||||
"to complete; if problem persists contact next "
|
||||
"level of support"),
|
||||
'exclude_alarm_context': [alarm.ALARM_CONTEXT.TENANT],
|
||||
},
|
||||
alarm.ALARM_TYPE.SYSTEM_CONFIG_UPDATE_AUTO_APPLY_FAILED: {
|
||||
'entity_type': "orchestration",
|
||||
'entity': "orchestration=system-config-update",
|
||||
'event_type': alarm.ALARM_EVENT_TYPE.EQUIPMENT_ALARM,
|
||||
'severity': alarm.ALARM_SEVERITY.CRITICAL,
|
||||
'probable_cause': alarm.ALARM_PROBABLE_CAUSE.UNKNOWN,
|
||||
'reason_text': "System config update auto-apply failed",
|
||||
'repair_action': ("Attempt to apply system config update manually; "
|
||||
"if problem persists contact next level of support"),
|
||||
'exclude_alarm_context': [alarm.ALARM_CONTEXT.TENANT],
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2016-2022 Wind River Systems, Inc.
|
||||
# Copyright (c) 2016-2023 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -13,6 +13,7 @@ from nfv_vim.api.acl.policies import kube_upgrade_strategy_policy
|
|||
from nfv_vim.api.acl.policies import sw_patch_strategy_policy
|
||||
from nfv_vim.api.acl.policies import sw_update_strategy_policy
|
||||
from nfv_vim.api.acl.policies import sw_upgrade_strategy_policy
|
||||
from nfv_vim.api.acl.policies import system_config_update_strategy_policy
|
||||
|
||||
from nfv_vim.api.acl import policy
|
||||
from nfv_vim.api import openstack
|
||||
|
@ -46,7 +47,8 @@ class AuthenticationApplication(object):
|
|||
kube_rootca_update_strategy_policy.list_rules(),
|
||||
kube_upgrade_strategy_policy.list_rules(),
|
||||
sw_patch_strategy_policy.list_rules(),
|
||||
sw_upgrade_strategy_policy.list_rules()
|
||||
sw_upgrade_strategy_policy.list_rules(),
|
||||
system_config_update_strategy_policy.list_rules()
|
||||
)
|
||||
rules = policy.Rules.load_rules(policy_file_contents,
|
||||
default_rule,
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
# Copyright (c) 2023 Wind River Systems, Inc.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
from nfv_vim.api.acl.policies import base
|
||||
|
||||
POLICY_ROOT = 'nfv_api:system_config_update_strategy:%s'
|
||||
|
||||
|
||||
system_config_update_strategy_rules = [
|
||||
base.RuleDefault(
|
||||
name=POLICY_ROOT % 'add',
|
||||
check_str='rule:' + base.ADMIN_IN_SYSTEM_PROJECTS,
|
||||
description="Add a system_config_update_strategy",
|
||||
),
|
||||
base.RuleDefault(
|
||||
name=POLICY_ROOT % 'delete',
|
||||
check_str='rule:' + base.ADMIN_IN_SYSTEM_PROJECTS,
|
||||
description="Delete a system_config_update_strategy",
|
||||
),
|
||||
base.RuleDefault(
|
||||
name=POLICY_ROOT % 'get',
|
||||
check_str='rule:' + base.READER_IN_SYSTEM_PROJECTS,
|
||||
description="Get a system_config_update_strategy",
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
def list_rules():
|
||||
return system_config_update_strategy_rules
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2015-2021 Wind River Systems, Inc.
|
||||
# Copyright (c) 2015-2023 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -15,6 +15,7 @@ from nfv_vim.api.controllers.v1.orchestration.sw_update import KubeRootcaUpdateA
|
|||
from nfv_vim.api.controllers.v1.orchestration.sw_update import KubeUpgradeAPI
|
||||
from nfv_vim.api.controllers.v1.orchestration.sw_update import SwPatchAPI
|
||||
from nfv_vim.api.controllers.v1.orchestration.sw_update import SwUpgradeAPI
|
||||
from nfv_vim.api.controllers.v1.orchestration.sw_update import SystemConfigUpdateAPI
|
||||
|
||||
|
||||
class OrchestrationDescription(wsme_types.Base):
|
||||
|
@ -34,6 +35,8 @@ class OrchestrationDescription(wsme_types.Base):
|
|||
Link.make_link('self', url, 'orchestration'),
|
||||
Link.make_link('sw-patch', url, 'orchestration/sw-patch', ''),
|
||||
Link.make_link('sw-upgrade', url, 'orchestration/sw-upgrade', ''),
|
||||
Link.make_link('system-config-update',
|
||||
url, 'orchestration/system-config-update', ''),
|
||||
Link.make_link('kube-rootca-update',
|
||||
url, 'orchestration/kube-rootca-update', ''),
|
||||
Link.make_link('kube-upgrade',
|
||||
|
@ -52,6 +55,8 @@ class OrchestrationAPI(rest.RestController):
|
|||
return SwPatchAPI(), remainder
|
||||
elif 'sw-upgrade' == key:
|
||||
return SwUpgradeAPI(), remainder
|
||||
elif 'system-config-update' == key:
|
||||
return SystemConfigUpdateAPI(), remainder
|
||||
elif 'fw-update' == key:
|
||||
return FwUpdateAPI(), remainder
|
||||
elif 'kube-rootca-update' == key:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2015-2021 Wind River Systems, Inc.
|
||||
# Copyright (c) 2015-2023 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -8,3 +8,4 @@ from nfv_vim.api.controllers.v1.orchestration.sw_update._kube_rootca_update impo
|
|||
from nfv_vim.api.controllers.v1.orchestration.sw_update._kube_upgrade import KubeUpgradeAPI # noqa: F401
|
||||
from nfv_vim.api.controllers.v1.orchestration.sw_update._sw_patch import SwPatchAPI # noqa: F401
|
||||
from nfv_vim.api.controllers.v1.orchestration.sw_update._sw_upgrade import SwUpgradeAPI # noqa: F401
|
||||
from nfv_vim.api.controllers.v1.orchestration.sw_update._system_config_update import SystemConfigUpdateAPI # noqa: F401
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2015-2021 Wind River Systems, Inc.
|
||||
# Copyright (c) 2015-2023 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -21,6 +21,7 @@ class SwUpdateNames(Constants):
|
|||
KUBE_UPGRADE = Constant('kube-upgrade')
|
||||
SW_PATCH = Constant('sw-patch')
|
||||
SW_UPGRADE = Constant('sw-upgrade')
|
||||
SYSTEM_CONFIG_UPDATE = Constant('system-config-update')
|
||||
|
||||
|
||||
@six.add_metaclass(Singleton)
|
||||
|
@ -76,7 +77,8 @@ SwUpdateNames = wsme_types.Enum(str,
|
|||
SW_UPDATE_NAME.KUBE_ROOTCA_UPDATE,
|
||||
SW_UPDATE_NAME.KUBE_UPGRADE,
|
||||
SW_UPDATE_NAME.SW_PATCH,
|
||||
SW_UPDATE_NAME.SW_UPGRADE)
|
||||
SW_UPDATE_NAME.SW_UPGRADE,
|
||||
SW_UPDATE_NAME.SYSTEM_CONFIG_UPDATE)
|
||||
SwUpdateApplyTypes = wsme_types.Enum(str,
|
||||
SW_UPDATE_APPLY_TYPE.SERIAL,
|
||||
SW_UPDATE_APPLY_TYPE.PARALLEL,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2015-2022 Wind River Systems, Inc.
|
||||
# Copyright (c) 2015-2023 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -19,6 +19,7 @@ from nfv_vim.api.acl.policies import kube_upgrade_strategy_policy
|
|||
from nfv_vim.api.acl.policies import sw_patch_strategy_policy
|
||||
from nfv_vim.api.acl.policies import sw_update_strategy_policy
|
||||
from nfv_vim.api.acl.policies import sw_upgrade_strategy_policy
|
||||
from nfv_vim.api.acl.policies import system_config_update_strategy_policy
|
||||
from nfv_vim.api.acl import policy
|
||||
|
||||
from nfv_vim import rpc
|
||||
|
@ -41,6 +42,7 @@ MAX_PARALLEL_FW_UPDATE_HOSTS = 5
|
|||
MAX_PARALLEL_KUBE_ROOTCA_UPDATE_HOSTS = 10
|
||||
MAX_PARALLEL_KUBE_UPGRADE_HOSTS = 10
|
||||
MAX_PARALLEL_PATCH_HOSTS = 100
|
||||
MAX_PARALLEL_SYSTEM_CONFIG_UPDATE_HOSTS = 100
|
||||
MAX_PARALLEL_UPGRADE_HOSTS = 10
|
||||
|
||||
|
||||
|
@ -50,6 +52,8 @@ def _get_sw_update_type_from_path(path):
|
|||
return SW_UPDATE_NAME.SW_PATCH
|
||||
elif 'sw-upgrade' in split_path:
|
||||
return SW_UPDATE_NAME.SW_UPGRADE
|
||||
elif 'system-config-update' in split_path:
|
||||
return SW_UPDATE_NAME.SYSTEM_CONFIG_UPDATE
|
||||
elif 'fw-update' in split_path:
|
||||
return SW_UPDATE_NAME.FW_UPDATE
|
||||
elif 'kube-rootca-update' in split_path:
|
||||
|
@ -193,6 +197,27 @@ class SwUpdateStrategyDeleteData(wsme_types.Base):
|
|||
default=False)
|
||||
|
||||
|
||||
class SystemConfigUpdateStrategyCreateData(wsme_types.Base):
|
||||
"""
|
||||
System Config Update Strategy - Create Data
|
||||
"""
|
||||
controller_apply_type = wsme_types.wsattr(SwUpdateApplyTypes, mandatory=True,
|
||||
name='controller-apply-type')
|
||||
storage_apply_type = wsme_types.wsattr(SwUpdateApplyTypes, mandatory=True,
|
||||
name='storage-apply-type')
|
||||
worker_apply_type = wsme_types.wsattr(SwUpdateApplyTypes, mandatory=True,
|
||||
name='worker-apply-type')
|
||||
max_parallel_worker_hosts = wsme_types.wsattr(
|
||||
int, mandatory=False, name='max-parallel-worker-hosts')
|
||||
default_instance_action = wsme_types.wsattr(SwUpdateInstanceActionTypes,
|
||||
mandatory=True,
|
||||
name='default-instance-action')
|
||||
alarm_restrictions = wsme_types.wsattr(
|
||||
SwUpdateAlarmRestrictionTypes, mandatory=False,
|
||||
default=SW_UPDATE_ALARM_RESTRICTION_TYPES.STRICT,
|
||||
name='alarm-restrictions')
|
||||
|
||||
|
||||
class FwUpdateStrategyCreateData(wsme_types.Base):
|
||||
"""
|
||||
Firmware Update Strategy - Create Data
|
||||
|
@ -697,6 +722,70 @@ class SwUpgradeStrategyAPI(SwUpdateStrategyAPI):
|
|||
policy.check('admin_in_system_projects', {}, auth_context_dict)
|
||||
|
||||
|
||||
class SystemConfigUpdateStrategyAPI(SwUpdateStrategyAPI):
|
||||
"""
|
||||
System Config Update Strategy Rest API
|
||||
"""
|
||||
@wsme_pecan.wsexpose(SwUpdateStrategyQueryData,
|
||||
body=SystemConfigUpdateStrategyCreateData,
|
||||
status_code=httplib.OK)
|
||||
def post(self, request_data):
|
||||
rpc_request = rpc.APIRequestCreateSwUpdateStrategy()
|
||||
rpc_request.sw_update_type = _get_sw_update_type_from_path(
|
||||
pecan.request.path)
|
||||
rpc_request.controller_apply_type = request_data.controller_apply_type
|
||||
rpc_request.storage_apply_type = request_data.storage_apply_type
|
||||
rpc_request.worker_apply_type = request_data.worker_apply_type
|
||||
if wsme_types.Unset != request_data.max_parallel_worker_hosts:
|
||||
if request_data.max_parallel_worker_hosts < MIN_PARALLEL_HOSTS \
|
||||
or request_data.max_parallel_worker_hosts > \
|
||||
MAX_PARALLEL_SYSTEM_CONFIG_UPDATE_HOSTS:
|
||||
return pecan.abort(
|
||||
httplib.BAD_REQUEST,
|
||||
"Invalid value for max-parallel-worker-hosts")
|
||||
rpc_request.max_parallel_worker_hosts = \
|
||||
request_data.max_parallel_worker_hosts
|
||||
rpc_request.default_instance_action = request_data.default_instance_action
|
||||
rpc_request.alarm_restrictions = request_data.alarm_restrictions
|
||||
vim_connection = pecan.request.vim.open_connection()
|
||||
vim_connection.send(rpc_request.serialize())
|
||||
msg = vim_connection.receive(timeout_in_secs=30)
|
||||
if msg is None:
|
||||
DLOG.error("No response received.")
|
||||
return pecan.abort(httplib.INTERNAL_SERVER_ERROR)
|
||||
|
||||
response = rpc.RPCMessage.deserialize(msg)
|
||||
if rpc.RPC_MSG_TYPE.CREATE_SW_UPDATE_STRATEGY_RESPONSE != response.type:
|
||||
DLOG.error("Unexpected message type received, msg_type=%s."
|
||||
% response.type)
|
||||
return pecan.abort(httplib.INTERNAL_SERVER_ERROR)
|
||||
|
||||
if rpc.RPC_MSG_RESULT.SUCCESS == response.result:
|
||||
strategy = json.loads(response.strategy)
|
||||
query_data = SwUpdateStrategyQueryData()
|
||||
query_data.convert_strategy(strategy)
|
||||
return query_data
|
||||
elif rpc.RPC_MSG_RESULT.CONFLICT == response.result:
|
||||
return pecan.abort(httplib.CONFLICT, response.error_string)
|
||||
|
||||
DLOG.error("Unexpected result received, result=%s." % response.result)
|
||||
return pecan.abort(httplib.INTERNAL_SERVER_ERROR)
|
||||
|
||||
def enforce_policy(self, method_name, auth_context_dict):
|
||||
"""Check policy rules for each action of this controller."""
|
||||
if method_name == "delete":
|
||||
policy.check(system_config_update_strategy_policy.POLICY_ROOT % "delete",
|
||||
{}, auth_context_dict, exc=policy.PolicyForbidden)
|
||||
elif method_name in ["get_all", "get_one"]:
|
||||
policy.check(system_config_update_strategy_policy.POLICY_ROOT % "get",
|
||||
{}, auth_context_dict, exc=policy.PolicyForbidden)
|
||||
elif method_name == "post":
|
||||
policy.check(system_config_update_strategy_policy.POLICY_ROOT % "add",
|
||||
{}, auth_context_dict, exc=policy.PolicyForbidden)
|
||||
else:
|
||||
policy.check('admin_in_system_projects', {}, auth_context_dict)
|
||||
|
||||
|
||||
class FwUpdateStrategyAPI(SwUpdateStrategyAPI):
|
||||
"""
|
||||
Firmware Update Strategy Rest API
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
#
|
||||
# Copyright (c) 2023 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
import pecan
|
||||
from pecan import rest
|
||||
from six.moves import http_client as httplib
|
||||
from wsme import types as wsme_types
|
||||
import wsmeext.pecan as wsme_pecan
|
||||
|
||||
from nfv_common import debug
|
||||
from nfv_vim.api._link import Link
|
||||
from nfv_vim.api.controllers.v1.orchestration.sw_update._sw_update_strategy \
|
||||
import SystemConfigUpdateStrategyAPI
|
||||
|
||||
DLOG = debug.debug_get_logger('nfv_vim.api.system_config_update')
|
||||
|
||||
|
||||
class SystemConfigUpdateDescription(wsme_types.Base):
|
||||
"""
|
||||
System Config Update Description
|
||||
"""
|
||||
id = wsme_types.text
|
||||
links = wsme_types.wsattr([Link], name='links')
|
||||
|
||||
@classmethod
|
||||
def convert(cls):
|
||||
url = pecan.request.host_url
|
||||
|
||||
description = SystemConfigUpdateDescription()
|
||||
description.id = "system-config-update"
|
||||
description.links = [
|
||||
Link.make_link('self',
|
||||
url,
|
||||
'orchestration/system-config-update'),
|
||||
Link.make_link('strategy',
|
||||
url,
|
||||
'orchestration/system-config-update/strategy')]
|
||||
return description
|
||||
|
||||
|
||||
class SystemConfigUpdateAPI(rest.RestController):
|
||||
"""
|
||||
SystemConfigUpdateRest API
|
||||
"""
|
||||
@pecan.expose()
|
||||
def _lookup(self, key, *remainder):
|
||||
if 'strategy' == key:
|
||||
return SystemConfigUpdateStrategyAPI(), remainder
|
||||
else:
|
||||
pecan.abort(httplib.NOT_FOUND)
|
||||
|
||||
@wsme_pecan.wsexpose(SystemConfigUpdateDescription)
|
||||
def get(self):
|
||||
# NOTE: The reason why convert() is being called for every
|
||||
# request is because we need to get the host url from
|
||||
# the request object to make the links.
|
||||
return SystemConfigUpdateDescription.convert()
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2016-2021 Wind River Systems, Inc.
|
||||
# Copyright (c) 2016-2023 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -77,4 +77,8 @@ def database_sw_update_get_list():
|
|||
kube_upgrade_obj = objects.KubeUpgrade(sw_update.uuid,
|
||||
strategy_data)
|
||||
sw_update_objs.append(kube_upgrade_obj)
|
||||
elif objects.SW_UPDATE_TYPE.SYSTEM_CONFIG_UPDATE == sw_update.sw_update_type:
|
||||
system_config_update_obj = objects.SystemConfigUpdate(sw_update.uuid,
|
||||
strategy_data)
|
||||
sw_update_objs.append(system_config_update_obj)
|
||||
return sw_update_objs
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2015-2020 Wind River Systems, Inc.
|
||||
# Copyright (c) 2015-2023 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -127,6 +127,7 @@ nfv_vim.objects.instance_group: debug.level.verbose
|
|||
nfv_vim.objects.fw_update: debug.level.info
|
||||
nfv_vim.objects.kube_rootca_update: debug.level.info
|
||||
nfv_vim.objects.kube_upgrade: debug.level.info
|
||||
nfv_vim.objects.system_config_update: debug.level.info
|
||||
nfv_vim.objects.sw_update: debug.level.verbose
|
||||
nfv_vim.objects.sw_patch: debug.level.verbose
|
||||
nfv_vim.objects.sw_upgrade: debug.level.verbose
|
||||
|
@ -171,6 +172,7 @@ nfv_vim.api.kube_upgrade: debug.level.verbose
|
|||
nfv_vim.api.sw_patch: debug.level.verbose
|
||||
nfv_vim.api.sw_upgrade: debug.level.verbose
|
||||
nfv_vim.api.sw_update.strategy: debug.level.verbose
|
||||
nfv_vim.api.system_config_update: debug.level.verbose
|
||||
nfv_vim.api.image: debug.level.verbose
|
||||
nfv_vim.api.volume: debug.level.verbose
|
||||
nfv_vim.api.virtualised_resources: debug.level.verbose
|
||||
|
|
|
@ -102,6 +102,35 @@ class SwMgmtDirector(object):
|
|||
self._sw_update.strategy)
|
||||
return strategy_uuid, ''
|
||||
|
||||
def create_system_config_update_strategy(self, controller_apply_type,
|
||||
storage_apply_type, worker_apply_type,
|
||||
max_parallel_worker_hosts,
|
||||
default_instance_action,
|
||||
alarm_restrictions, callback):
|
||||
"""
|
||||
Create System Config Update Strategy
|
||||
"""
|
||||
strategy_uuid = str(uuid.uuid4())
|
||||
|
||||
if self._sw_update is not None:
|
||||
# Do not schedule the callback - if creation failed because a
|
||||
# strategy already exists, the callback will attempt to operate
|
||||
# on the old strategy, which is not what we want.
|
||||
reason = "strategy already exists of type:%s" % self._sw_update._sw_update_type
|
||||
return None, reason
|
||||
|
||||
self._sw_update = objects.SystemConfigUpdate()
|
||||
success, reason = self._sw_update.strategy_build(
|
||||
strategy_uuid, controller_apply_type, storage_apply_type,
|
||||
worker_apply_type, max_parallel_worker_hosts,
|
||||
default_instance_action,
|
||||
alarm_restrictions, self._ignore_alarms,
|
||||
self._single_controller)
|
||||
|
||||
schedule.schedule_function_call(callback, success, reason,
|
||||
self._sw_update.strategy)
|
||||
return strategy_uuid, ''
|
||||
|
||||
def create_fw_update_strategy(self,
|
||||
controller_apply_type,
|
||||
storage_apply_type,
|
||||
|
@ -345,6 +374,15 @@ class SwMgmtDirector(object):
|
|||
self._sw_update.handle_event(
|
||||
strategy.STRATEGY_EVENT.HOST_FW_UPDATE_FAILED, host)
|
||||
|
||||
def system_config_update_failed(self, host):
|
||||
"""
|
||||
Called when a system config update for a host phase fails
|
||||
"""
|
||||
if self._sw_update is not None:
|
||||
self._sw_update.handle_event(
|
||||
strategy.STRATEGY_EVENT.SYSTEM_CONFIG_UPDATE_HOST_FAILED,
|
||||
host)
|
||||
|
||||
def kube_host_rootca_update_failed(self, host):
|
||||
"""
|
||||
Called when a kube footca update for a host phase fails
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2015-2021 Wind River Systems, Inc.
|
||||
# Copyright (c) 2015-2023 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -342,6 +342,175 @@ _event_templates = {
|
|||
}
|
||||
}
|
||||
},
|
||||
event_log.EVENT_ID.SYSTEM_CONFIG_UPDATE_AUTO_APPLY_START: {
|
||||
'entity_type': "orchestration",
|
||||
'entity': "orchestration=system-config-update",
|
||||
'event_type': event_log.EVENT_TYPE.ACTION_EVENT,
|
||||
'importance': event_log.EVENT_IMPORTANCE.HIGH,
|
||||
'reason_text': "System config update auto-apply start",
|
||||
'exclude_event_context': [],
|
||||
'event_context_data': {
|
||||
event_log.EVENT_CONTEXT.ADMIN: {
|
||||
'entity_type': "orchestration",
|
||||
'entity': "orchestration=system-config-update",
|
||||
'reason_text': "System config update auto-apply start",
|
||||
}
|
||||
}
|
||||
},
|
||||
event_log.EVENT_ID.SYSTEM_CONFIG_UPDATE_AUTO_APPLY_INPROGRESS: {
|
||||
'entity_type': "orchestration",
|
||||
'entity': "orchestration=system-config-update",
|
||||
'event_type': event_log.EVENT_TYPE.ACTION_EVENT,
|
||||
'importance': event_log.EVENT_IMPORTANCE.HIGH,
|
||||
'reason_text': "System config update auto-apply inprogress",
|
||||
'exclude_event_context': [],
|
||||
'event_context_data': {
|
||||
event_log.EVENT_CONTEXT.ADMIN: {
|
||||
'entity_type': "orchestration",
|
||||
'entity': "orchestration=system-config-update",
|
||||
'reason_text': "System config update auto-apply inprogress",
|
||||
}
|
||||
}
|
||||
},
|
||||
event_log.EVENT_ID.SYSTEM_CONFIG_UPDATE_AUTO_APPLY_REJECTED: {
|
||||
'entity_type': "orchestration",
|
||||
'entity': "orchestration=system-config-update",
|
||||
'event_type': event_log.EVENT_TYPE.ACTION_EVENT,
|
||||
'importance': event_log.EVENT_IMPORTANCE.HIGH,
|
||||
'reason_text': "System config update auto-apply rejected",
|
||||
'exclude_event_context': [],
|
||||
'event_context_data': {
|
||||
event_log.EVENT_CONTEXT.ADMIN: {
|
||||
'entity_type': "orchestration",
|
||||
'entity': "orchestration=system-config-update",
|
||||
'reason_text': "System config update auto-apply rejected%(reason)s",
|
||||
}
|
||||
}
|
||||
},
|
||||
event_log.EVENT_ID.SYSTEM_CONFIG_UPDATE_AUTO_APPLY_CANCELLED: {
|
||||
'entity_type': "orchestration",
|
||||
'entity': "orchestration=system-config-update",
|
||||
'event_type': event_log.EVENT_TYPE.ACTION_EVENT,
|
||||
'importance': event_log.EVENT_IMPORTANCE.HIGH,
|
||||
'reason_text': "System config update auto-apply cancelled",
|
||||
'exclude_event_context': [],
|
||||
'event_context_data': {
|
||||
event_log.EVENT_CONTEXT.ADMIN: {
|
||||
'entity_type': "orchestration",
|
||||
'entity': "orchestration=system-config-update",
|
||||
'reason_text': "System config update auto-apply "
|
||||
"cancelled%(reason)s",
|
||||
}
|
||||
}
|
||||
},
|
||||
event_log.EVENT_ID.SYSTEM_CONFIG_UPDATE_AUTO_APPLY_FAILED: {
|
||||
'entity_type': "orchestration",
|
||||
'entity': "orchestration=system-config-update",
|
||||
'event_type': event_log.EVENT_TYPE.ACTION_EVENT,
|
||||
'importance': event_log.EVENT_IMPORTANCE.HIGH,
|
||||
'reason_text': "System config update auto-apply failed",
|
||||
'exclude_event_context': [],
|
||||
'event_context_data': {
|
||||
event_log.EVENT_CONTEXT.ADMIN: {
|
||||
'entity_type': "orchestration",
|
||||
'entity': "orchestration=system-config-update",
|
||||
'reason_text': "System config update auto-apply "
|
||||
"failed%(reason)s",
|
||||
}
|
||||
}
|
||||
},
|
||||
event_log.EVENT_ID.SYSTEM_CONFIG_UPDATE_AUTO_APPLY_COMPLETED: {
|
||||
'entity_type': "orchestration",
|
||||
'entity': "orchestration=system-config-update",
|
||||
'event_type': event_log.EVENT_TYPE.ACTION_EVENT,
|
||||
'importance': event_log.EVENT_IMPORTANCE.HIGH,
|
||||
'reason_text': "System config update auto-apply completed",
|
||||
'exclude_event_context': [],
|
||||
'event_context_data': {
|
||||
event_log.EVENT_CONTEXT.ADMIN: {
|
||||
'entity_type': "orchestration",
|
||||
'entity': "orchestration=system-config-update",
|
||||
'reason_text': "System config update auto-apply completed",
|
||||
}
|
||||
}
|
||||
},
|
||||
event_log.EVENT_ID.SYSTEM_CONFIG_UPDATE_AUTO_APPLY_ABORT: {
|
||||
'entity_type': "orchestration",
|
||||
'entity': "orchestration=system-config-update",
|
||||
'event_type': event_log.EVENT_TYPE.ACTION_EVENT,
|
||||
'importance': event_log.EVENT_IMPORTANCE.HIGH,
|
||||
'reason_text': "System config update auto-apply abort",
|
||||
'exclude_event_context': [],
|
||||
'event_context_data': {
|
||||
event_log.EVENT_CONTEXT.ADMIN: {
|
||||
'entity_type': "orchestration",
|
||||
'entity': "orchestration=system-config-update",
|
||||
'reason_text': "System config update auto-apply abort",
|
||||
}
|
||||
}
|
||||
},
|
||||
event_log.EVENT_ID.SYSTEM_CONFIG_UPDATE_AUTO_APPLY_ABORTING: {
|
||||
'entity_type': "orchestration",
|
||||
'entity': "orchestration=system-config-update",
|
||||
'event_type': event_log.EVENT_TYPE.ACTION_EVENT,
|
||||
'importance': event_log.EVENT_IMPORTANCE.HIGH,
|
||||
'reason_text': "System config update auto-apply aborting",
|
||||
'exclude_event_context': [],
|
||||
'event_context_data': {
|
||||
event_log.EVENT_CONTEXT.ADMIN: {
|
||||
'entity_type': "orchestration",
|
||||
'entity': "orchestration=system-config-update",
|
||||
'reason_text': "System config update auto-apply aborting",
|
||||
}
|
||||
}
|
||||
},
|
||||
event_log.EVENT_ID.SYSTEM_CONFIG_UPDATE_AUTO_APPLY_ABORT_REJECTED: {
|
||||
'entity_type': "orchestration",
|
||||
'entity': "orchestration=system-config-update",
|
||||
'event_type': event_log.EVENT_TYPE.ACTION_EVENT,
|
||||
'importance': event_log.EVENT_IMPORTANCE.HIGH,
|
||||
'reason_text': "System config update auto-apply abort rejected",
|
||||
'exclude_event_context': [],
|
||||
'event_context_data': {
|
||||
event_log.EVENT_CONTEXT.ADMIN: {
|
||||
'entity_type': "orchestration",
|
||||
'entity': "orchestration=system-config-update",
|
||||
'reason_text': "System config update auto-apply abort "
|
||||
"rejected%(reason)s",
|
||||
}
|
||||
}
|
||||
},
|
||||
event_log.EVENT_ID.SYSTEM_CONFIG_UPDATE_AUTO_APPLY_ABORT_FAILED: {
|
||||
'entity_type': "orchestration",
|
||||
'entity': "orchestration=system-config-update",
|
||||
'event_type': event_log.EVENT_TYPE.ACTION_EVENT,
|
||||
'importance': event_log.EVENT_IMPORTANCE.HIGH,
|
||||
'reason_text': "System config update auto-apply abort failed",
|
||||
'exclude_event_context': [],
|
||||
'event_context_data': {
|
||||
event_log.EVENT_CONTEXT.ADMIN: {
|
||||
'entity_type': "orchestration",
|
||||
'entity': "orchestration=system-config-update",
|
||||
'reason_text': "System config update auto-apply abort "
|
||||
"failed%(reason)s",
|
||||
}
|
||||
}
|
||||
},
|
||||
event_log.EVENT_ID.SYSTEM_CONFIG_UPDATE_AUTO_APPLY_ABORTED: {
|
||||
'entity_type': "orchestration",
|
||||
'entity': "orchestration=system-config-update",
|
||||
'event_type': event_log.EVENT_TYPE.ACTION_EVENT,
|
||||
'importance': event_log.EVENT_IMPORTANCE.HIGH,
|
||||
'reason_text': "System config update auto-apply aborted",
|
||||
'exclude_event_context': [],
|
||||
'event_context_data': {
|
||||
event_log.EVENT_CONTEXT.ADMIN: {
|
||||
'entity_type': "orchestration",
|
||||
'entity': "orchestration=system-config-update",
|
||||
'reason_text': "System config update auto-apply aborted",
|
||||
}
|
||||
}
|
||||
},
|
||||
event_log.EVENT_ID.KUBE_ROOTCA_UPDATE_AUTO_APPLY_START: {
|
||||
'entity_type': "orchestration",
|
||||
'entity': "orchestration=kube-rootca update",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2015-2021 Wind River Systems, Inc.
|
||||
# Copyright (c) 2015-2023 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -196,6 +196,9 @@ def _vim_api_message_handler(connection, msg):
|
|||
elif rpc.RPC_MSG_TYPE.CREATE_SW_UPGRADE_STRATEGY_REQUEST == msg.type:
|
||||
vim_sw_update_api_create_strategy(connection, msg)
|
||||
|
||||
elif rpc.RPC_MSG_TYPE.CREATE_SYSTEM_CONFIG_UPDATE_STRATEGY_REQUEST == msg.type:
|
||||
vim_sw_update_api_create_strategy(connection, msg)
|
||||
|
||||
elif rpc.RPC_MSG_TYPE.APPLY_SW_UPDATE_STRATEGY_REQUEST == msg.type:
|
||||
vim_sw_update_api_apply_strategy(connection, msg)
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2015-2021 Wind River Systems, Inc.
|
||||
# Copyright (c) 2015-2023 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -122,6 +122,8 @@ def _nfvi_sw_update_get_callback():
|
|||
sw_update_type = 'sw-patch'
|
||||
elif sw_update.sw_update_type == objects.SW_UPDATE_TYPE.SW_UPGRADE:
|
||||
sw_update_type = 'sw-upgrade'
|
||||
elif sw_update.sw_update_type == objects.SW_UPDATE_TYPE.SYSTEM_CONFIG_UPDATE:
|
||||
sw_update_type = 'system-config-update'
|
||||
elif sw_update.sw_update_type == objects.SW_UPDATE_TYPE.FW_UPDATE:
|
||||
sw_update_type = 'fw-update'
|
||||
elif sw_update.sw_update_type == objects.SW_UPDATE_TYPE.KUBE_ROOTCA_UPDATE:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2015-2021 Wind River Systems, Inc.
|
||||
# Copyright (c) 2015-2023 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -139,6 +139,13 @@ def vim_sw_update_api_create_strategy(connection, msg):
|
|||
alarm_restrictions,
|
||||
to_version,
|
||||
_vim_sw_update_api_create_strategy_callback)
|
||||
elif 'system-config-update' == msg.sw_update_type:
|
||||
uuid, reason = sw_mgmt_director.create_system_config_update_strategy(
|
||||
controller_apply_type, storage_apply_type,
|
||||
worker_apply_type, max_parallel_worker_hosts,
|
||||
default_instance_action,
|
||||
alarm_restrictions,
|
||||
_vim_sw_update_api_create_strategy_callback)
|
||||
else:
|
||||
DLOG.error("Invalid message name: %s" % msg.sw_update_type)
|
||||
response = rpc.APIResponseCreateSwUpdateStrategy()
|
||||
|
@ -205,6 +212,8 @@ def vim_sw_update_api_apply_strategy(connection, msg):
|
|||
sw_update_type = objects.SW_UPDATE_TYPE.KUBE_ROOTCA_UPDATE
|
||||
elif 'kube-upgrade' == msg.sw_update_type:
|
||||
sw_update_type = objects.SW_UPDATE_TYPE.KUBE_UPGRADE
|
||||
elif 'system-config-update' == msg.sw_update_type:
|
||||
sw_update_type = objects.SW_UPDATE_TYPE.SYSTEM_CONFIG_UPDATE
|
||||
else:
|
||||
DLOG.error("Invalid message name: %s" % msg.sw_update_type)
|
||||
sw_update_type = 'unknown'
|
||||
|
@ -264,6 +273,8 @@ def vim_sw_update_api_abort_strategy(connection, msg):
|
|||
sw_update_type = objects.SW_UPDATE_TYPE.KUBE_ROOTCA_UPDATE
|
||||
elif 'kube-upgrade' == msg.sw_update_type:
|
||||
sw_update_type = objects.SW_UPDATE_TYPE.KUBE_UPGRADE
|
||||
elif 'system-config-update' == msg.sw_update_type:
|
||||
sw_update_type = objects.SW_UPDATE_TYPE.SYSTEM_CONFIG_UPDATE
|
||||
else:
|
||||
DLOG.error("Invalid message name: %s" % msg.sw_update_type)
|
||||
sw_update_type = 'unknown'
|
||||
|
@ -320,6 +331,8 @@ def vim_sw_update_api_delete_strategy(connection, msg):
|
|||
sw_update_type = objects.SW_UPDATE_TYPE.KUBE_ROOTCA_UPDATE
|
||||
elif 'kube-upgrade' == msg.sw_update_type:
|
||||
sw_update_type = objects.SW_UPDATE_TYPE.KUBE_UPGRADE
|
||||
elif 'system-config-update' == msg.sw_update_type:
|
||||
sw_update_type = objects.SW_UPDATE_TYPE.SYSTEM_CONFIG_UPDATE
|
||||
else:
|
||||
DLOG.error("Invalid message name: %s" % msg.sw_update_type)
|
||||
sw_update_type = 'unknown'
|
||||
|
@ -355,6 +368,8 @@ def vim_sw_update_api_get_strategy(connection, msg):
|
|||
sw_update_type = objects.SW_UPDATE_TYPE.KUBE_ROOTCA_UPDATE
|
||||
elif 'kube-upgrade' == msg.sw_update_type:
|
||||
sw_update_type = objects.SW_UPDATE_TYPE.KUBE_UPGRADE
|
||||
elif 'system-config-update' == msg.sw_update_type:
|
||||
sw_update_type = objects.SW_UPDATE_TYPE.SYSTEM_CONFIG_UPDATE
|
||||
else:
|
||||
DLOG.error("Invalid message name: %s" % msg.sw_update_type)
|
||||
sw_update_type = 'unknown'
|
||||
|
|
|
@ -106,6 +106,7 @@ from nfv_vim.nfvi._nfvi_infrastructure_module import nfvi_get_kube_rootca_update
|
|||
from nfv_vim.nfvi._nfvi_infrastructure_module import nfvi_get_kube_upgrade # noqa: F401
|
||||
from nfv_vim.nfvi._nfvi_infrastructure_module import nfvi_get_kube_version_list # noqa: F401
|
||||
from nfv_vim.nfvi._nfvi_infrastructure_module import nfvi_get_logs # noqa: F401
|
||||
from nfv_vim.nfvi._nfvi_infrastructure_module import nfvi_get_system_config_unlock_request # noqa: F401
|
||||
from nfv_vim.nfvi._nfvi_infrastructure_module import nfvi_get_system_info # noqa: F401
|
||||
from nfv_vim.nfvi._nfvi_infrastructure_module import nfvi_get_system_state # noqa: F401
|
||||
from nfv_vim.nfvi._nfvi_infrastructure_module import nfvi_get_terminating_pods # noqa: F401
|
||||
|
@ -129,6 +130,7 @@ from nfv_vim.nfvi._nfvi_infrastructure_module import nfvi_kube_upgrade_complete
|
|||
from nfv_vim.nfvi._nfvi_infrastructure_module import nfvi_kube_upgrade_download_images # noqa: F401
|
||||
from nfv_vim.nfvi._nfvi_infrastructure_module import nfvi_kube_upgrade_networking # noqa: F401
|
||||
from nfv_vim.nfvi._nfvi_infrastructure_module import nfvi_kube_upgrade_start # noqa: F401
|
||||
from nfv_vim.nfvi._nfvi_infrastructure_module import nfvi_list_deployment_hosts # noqa: F401
|
||||
from nfv_vim.nfvi._nfvi_infrastructure_module import nfvi_lock_host # noqa: F401
|
||||
from nfv_vim.nfvi._nfvi_infrastructure_module import nfvi_notify_host_failed # noqa: F401
|
||||
from nfv_vim.nfvi._nfvi_infrastructure_module import nfvi_notify_host_services_delete_failed # noqa: F401
|
||||
|
|
|
@ -59,6 +59,35 @@ def nfvi_get_host(host_uuid, host_name, callback):
|
|||
return cmd_id
|
||||
|
||||
|
||||
def nfvi_get_deployment_host(host_name, callback):
|
||||
"""
|
||||
Get host resource from deployment namespace
|
||||
"""
|
||||
cmd_id = _infrastructure_plugin.invoke_plugin('get_deployment_host',
|
||||
host_name,
|
||||
callback=callback)
|
||||
return cmd_id
|
||||
|
||||
|
||||
def nfvi_list_deployment_hosts(callback):
|
||||
"""
|
||||
Get host resource from deployment namespace
|
||||
"""
|
||||
cmd_id = _infrastructure_plugin.invoke_plugin('list_deployment_hosts',
|
||||
callback=callback)
|
||||
return cmd_id
|
||||
|
||||
|
||||
def nfvi_get_system_config_unlock_request(host_names, callback):
|
||||
"""
|
||||
Get host unlock request from deployment namespace
|
||||
"""
|
||||
cmd_id = _infrastructure_plugin.invoke_plugin('get_system_config_unlock_request',
|
||||
host_names,
|
||||
callback=callback)
|
||||
return cmd_id
|
||||
|
||||
|
||||
def nfvi_get_host_devices(host_uuid, host_name, callback):
|
||||
"""
|
||||
Get host device list details
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2015-2021 Wind River Systems, Inc.
|
||||
# Copyright (c) 2015-2023 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -22,6 +22,7 @@ from nfv_vim.nfvi.objects.v1._host_fw_update import HostFwUpdate # noqa: F401
|
|||
from nfv_vim.nfvi.objects.v1._host_group import HOST_GROUP_POLICY # noqa: F401
|
||||
from nfv_vim.nfvi.objects.v1._host_group import HostGroup # noqa: F401
|
||||
from nfv_vim.nfvi.objects.v1._host_sw_patch import HostSwPatch # noqa: F401
|
||||
from nfv_vim.nfvi.objects.v1._host_system_config_update import HostSystemConfigUpdate # noqa: F401
|
||||
from nfv_vim.nfvi.objects.v1._hypervisor import Hypervisor # noqa: F401
|
||||
from nfv_vim.nfvi.objects.v1._hypervisor import HYPERVISOR_ADMIN_STATE # noqa: F401
|
||||
from nfv_vim.nfvi.objects.v1._hypervisor import HYPERVISOR_OPER_STATE # noqa: F401
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
#
|
||||
# Copyright (c) 2023 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
from nfv_vim.nfvi.objects.v1._object import ObjectData
|
||||
|
||||
|
||||
class HostSystemConfigUpdate(ObjectData):
|
||||
"""
|
||||
NFVI Host System Config Update Object
|
||||
"""
|
||||
def __init__(self, name, unlock_request):
|
||||
super(HostSystemConfigUpdate, self).__init__('1.0.0')
|
||||
self.update(dict(name=name,
|
||||
unlock_request=unlock_request))
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2015-2021 Wind River Systems, Inc.
|
||||
# Copyright (c) 2015-2023 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -40,6 +40,7 @@ from nfv_vim.objects._sw_update import SW_UPDATE_TYPE # noqa: F401
|
|||
from nfv_vim.objects._sw_update import SwUpdate # noqa: F401
|
||||
from nfv_vim.objects._sw_upgrade import SwUpgrade # noqa: F401
|
||||
from nfv_vim.objects._system import System # noqa: F401
|
||||
from nfv_vim.objects._system_config_update import SystemConfigUpdate # noqa: F401
|
||||
from nfv_vim.objects._tenant import Tenant # noqa: F401
|
||||
from nfv_vim.objects._volume import Volume # noqa: F401
|
||||
from nfv_vim.objects._volume_snapshot import VolumeSnapshot # noqa: F401
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2016-2021 Wind River Systems, Inc.
|
||||
# Copyright (c) 2016-2023 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -29,6 +29,7 @@ class SwUpdateTypes(Constants):
|
|||
"""
|
||||
SW_PATCH = Constant('sw-patch')
|
||||
SW_UPGRADE = Constant('sw-upgrade')
|
||||
SYSTEM_CONFIG_UPDATE = Constant('system-config-update')
|
||||
FW_UPDATE = Constant('fw-update')
|
||||
KUBE_ROOTCA_UPDATE = Constant('kube-rootca-update')
|
||||
KUBE_UPGRADE = Constant('kube-upgrade')
|
||||
|
|
|
@ -0,0 +1,197 @@
|
|||
#
|
||||
# Copyright (c) 2023 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
from nfv_common import debug
|
||||
from nfv_common import timers
|
||||
|
||||
from nfv_common.helpers import coroutine
|
||||
|
||||
from nfv_vim import alarm
|
||||
from nfv_vim import event_log
|
||||
from nfv_vim import nfvi
|
||||
|
||||
from nfv_vim.objects._sw_update import SW_UPDATE_ALARM_TYPES
|
||||
from nfv_vim.objects._sw_update import SW_UPDATE_EVENT_IDS
|
||||
from nfv_vim.objects._sw_update import SW_UPDATE_TYPE
|
||||
from nfv_vim.objects._sw_update import SwUpdate
|
||||
|
||||
DLOG = debug.debug_get_logger('nfv_vim.objects.system_config_update')
|
||||
|
||||
|
||||
class SystemConfigUpdate(SwUpdate):
|
||||
"""
|
||||
System config update Object
|
||||
"""
|
||||
def __init__(self, sw_update_uuid=None, strategy_data=None):
|
||||
super(SystemConfigUpdate, self).__init__(
|
||||
sw_update_type=SW_UPDATE_TYPE.SYSTEM_CONFIG_UPDATE,
|
||||
sw_update_uuid=sw_update_uuid,
|
||||
strategy_data=strategy_data)
|
||||
|
||||
self._system_config_update_hosts = list()
|
||||
|
||||
def strategy_build(self,
|
||||
strategy_uuid,
|
||||
controller_apply_type,
|
||||
storage_apply_type,
|
||||
worker_apply_type,
|
||||
max_parallel_worker_hosts,
|
||||
default_instance_action,
|
||||
alarm_restrictions,
|
||||
ignore_alarms,
|
||||
single_controller):
|
||||
"""
|
||||
Create a system config update strategy
|
||||
"""
|
||||
from nfv_vim import strategy
|
||||
|
||||
if self._strategy:
|
||||
reason = "strategy already exists of type:%s" % self._sw_update_type
|
||||
return False, reason
|
||||
|
||||
self._strategy = \
|
||||
strategy.SystemConfigUpdateStrategy(strategy_uuid,
|
||||
controller_apply_type,
|
||||
storage_apply_type,
|
||||
worker_apply_type,
|
||||
max_parallel_worker_hosts,
|
||||
default_instance_action,
|
||||
alarm_restrictions,
|
||||
ignore_alarms,
|
||||
single_controller)
|
||||
self._strategy.sw_update_obj = self
|
||||
self._strategy.build()
|
||||
self._persist()
|
||||
return True, ''
|
||||
|
||||
def strategy_build_complete(self, success, reason):
|
||||
"""
|
||||
Creation of a system config update strategy complete
|
||||
"""
|
||||
DLOG.info("System config update strategy build complete.")
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def alarm_type(alarm_type):
|
||||
"""
|
||||
Returns ALARM_TYPE corresponding to SW_UPDATE_ALARM_TYPES
|
||||
"""
|
||||
ALARM_TYPE_MAPPING = {
|
||||
SW_UPDATE_ALARM_TYPES.APPLY_INPROGRESS:
|
||||
alarm.ALARM_TYPE.SYSTEM_CONFIG_UPDATE_AUTO_APPLY_INPROGRESS,
|
||||
SW_UPDATE_ALARM_TYPES.APPLY_ABORTING:
|
||||
alarm.ALARM_TYPE.SYSTEM_CONFIG_UPDATE_AUTO_APPLY_ABORTING,
|
||||
SW_UPDATE_ALARM_TYPES.APPLY_FAILED:
|
||||
alarm.ALARM_TYPE.SYSTEM_CONFIG_UPDATE_AUTO_APPLY_FAILED,
|
||||
}
|
||||
return ALARM_TYPE_MAPPING[alarm_type]
|
||||
|
||||
@staticmethod
|
||||
def event_id(event_id):
|
||||
"""
|
||||
Returns EVENT_ID corresponding to SW_UPDATE_EVENT_IDS
|
||||
"""
|
||||
EVENT_ID_MAPPING = {
|
||||
SW_UPDATE_EVENT_IDS.APPLY_START:
|
||||
event_log.EVENT_ID.SYSTEM_CONFIG_UPDATE_AUTO_APPLY_START,
|
||||
SW_UPDATE_EVENT_IDS.APPLY_INPROGRESS:
|
||||
event_log.EVENT_ID.SYSTEM_CONFIG_UPDATE_AUTO_APPLY_INPROGRESS,
|
||||
SW_UPDATE_EVENT_IDS.APPLY_REJECTED:
|
||||
event_log.EVENT_ID.SYSTEM_CONFIG_UPDATE_AUTO_APPLY_REJECTED,
|
||||
SW_UPDATE_EVENT_IDS.APPLY_CANCELLED:
|
||||
event_log.EVENT_ID.SYSTEM_CONFIG_UPDATE_AUTO_APPLY_CANCELLED,
|
||||
SW_UPDATE_EVENT_IDS.APPLY_FAILED:
|
||||
event_log.EVENT_ID.SYSTEM_CONFIG_UPDATE_AUTO_APPLY_FAILED,
|
||||
SW_UPDATE_EVENT_IDS.APPLY_COMPLETED:
|
||||
event_log.EVENT_ID.SYSTEM_CONFIG_UPDATE_AUTO_APPLY_COMPLETED,
|
||||
SW_UPDATE_EVENT_IDS.APPLY_ABORT:
|
||||
event_log.EVENT_ID.SYSTEM_CONFIG_UPDATE_AUTO_APPLY_ABORT,
|
||||
SW_UPDATE_EVENT_IDS.APPLY_ABORTING:
|
||||
event_log.EVENT_ID.SYSTEM_CONFIG_UPDATE_AUTO_APPLY_ABORTING,
|
||||
SW_UPDATE_EVENT_IDS.APPLY_ABORT_REJECTED:
|
||||
event_log.EVENT_ID.SYSTEM_CONFIG_UPDATE_AUTO_APPLY_ABORT_REJECTED,
|
||||
SW_UPDATE_EVENT_IDS.APPLY_ABORT_FAILED:
|
||||
event_log.EVENT_ID.SYSTEM_CONFIG_UPDATE_AUTO_APPLY_ABORT_FAILED,
|
||||
SW_UPDATE_EVENT_IDS.APPLY_ABORTED:
|
||||
event_log.EVENT_ID.SYSTEM_CONFIG_UPDATE_AUTO_APPLY_ABORTED,
|
||||
}
|
||||
return EVENT_ID_MAPPING[event_id]
|
||||
|
||||
def nfvi_update(self):
|
||||
"""
|
||||
NFVI Update
|
||||
"""
|
||||
if self._strategy is None:
|
||||
if self._alarms:
|
||||
alarm.clear_sw_update_alarm(self._alarms)
|
||||
return False
|
||||
|
||||
if self.strategy.is_applying():
|
||||
if not self._alarms:
|
||||
self._alarms = alarm.raise_sw_update_alarm(
|
||||
self.alarm_type(SW_UPDATE_ALARM_TYPES.APPLY_INPROGRESS))
|
||||
event_log.sw_update_issue_log(
|
||||
self.event_id(SW_UPDATE_EVENT_IDS.APPLY_INPROGRESS))
|
||||
|
||||
elif (self.strategy.is_apply_failed() or
|
||||
self.strategy.is_apply_timed_out()):
|
||||
for system_config_update_host in self._system_config_update_hosts:
|
||||
if not self._alarms:
|
||||
self._alarms = \
|
||||
alarm.raise_sw_update_alarm(
|
||||
self.alarm_type(SW_UPDATE_ALARM_TYPES.APPLY_FAILED))
|
||||
|
||||
event_log.sw_update_issue_log(
|
||||
self.event_id(SW_UPDATE_EVENT_IDS.APPLY_FAILED))
|
||||
break
|
||||
|
||||
else:
|
||||
if self._alarms:
|
||||
alarm.clear_sw_update_alarm(self._alarms)
|
||||
return False
|
||||
|
||||
elif self.strategy.is_aborting():
|
||||
if not self._alarms:
|
||||
self._alarms = alarm.raise_sw_update_alarm(
|
||||
self.alarm_type(SW_UPDATE_ALARM_TYPES.APPLY_ABORTING))
|
||||
event_log.sw_update_issue_log(
|
||||
self.event_id(SW_UPDATE_EVENT_IDS.APPLY_ABORTING))
|
||||
|
||||
else:
|
||||
if self._alarms:
|
||||
alarm.clear_sw_update_alarm(self._alarms)
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
@coroutine
|
||||
def nfvi_audit(self):
|
||||
"""
|
||||
Audit NFVI layer
|
||||
"""
|
||||
while True:
|
||||
timer_id = (yield)
|
||||
|
||||
DLOG.debug("Audit alarms, timer_id=%s." % timer_id)
|
||||
self.nfvi_alarms_clear()
|
||||
nfvi.nfvi_get_alarms(self.nfvi_alarms_callback(timer_id))
|
||||
if not nfvi.nfvi_fault_mgmt_plugin_disabled():
|
||||
nfvi.nfvi_get_openstack_alarms(
|
||||
self.nfvi_alarms_callback(timer_id))
|
||||
self._nfvi_audit_inprogress = True
|
||||
while self._nfvi_audit_inprogress:
|
||||
timer_id = (yield)
|
||||
|
||||
# nfvi_alarms_callback sets timer to 2 seconds. reset back to 30
|
||||
timers.timers_reschedule_timer(timer_id, 30)
|
||||
|
||||
if not self.nfvi_update():
|
||||
DLOG.info("Audit no longer needed.")
|
||||
break
|
||||
|
||||
DLOG.verbose("Audit system config update still running, timer_id=%s."
|
||||
% timer_id)
|
||||
|
||||
self._nfvi_timer_id = None
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2015-2021 Wind River Systems, Inc.
|
||||
# Copyright (c) 2015-2023 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -77,6 +77,7 @@ from nfv_vim.rpc._rpc_message_sw_update import APIRequestCreateKubeRootcaUpdateS
|
|||
from nfv_vim.rpc._rpc_message_sw_update import APIRequestCreateKubeUpgradeStrategy # noqa: F401
|
||||
from nfv_vim.rpc._rpc_message_sw_update import APIRequestCreateSwUpdateStrategy # noqa: F401
|
||||
from nfv_vim.rpc._rpc_message_sw_update import APIRequestCreateSwUpgradeStrategy # noqa: F401
|
||||
from nfv_vim.rpc._rpc_message_sw_update import APIRequestCreateSystemConfigUpdateStrategy # noqa: F401
|
||||
from nfv_vim.rpc._rpc_message_sw_update import APIRequestDeleteSwUpdateStrategy # noqa: F401
|
||||
from nfv_vim.rpc._rpc_message_sw_update import APIRequestGetSwUpdateStrategy # noqa: F401
|
||||
from nfv_vim.rpc._rpc_message_sw_update import APIResponseAbortSwUpdateStrategy # noqa: F401
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2015-2021 Wind River Systems, Inc.
|
||||
# Copyright (c) 2015-2023 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -99,6 +99,7 @@ class _RPCMessageType(Constants):
|
|||
CREATE_KUBE_ROOTCA_UPDATE_STRATEGY_REQUEST = Constant('create-kube-rootca-update-strategy-request')
|
||||
CREATE_KUBE_UPGRADE_STRATEGY_REQUEST = Constant('create-kube-upgrade-strategy-request')
|
||||
CREATE_SW_UPGRADE_STRATEGY_REQUEST = Constant('create-sw-upgrade-strategy-request')
|
||||
CREATE_SYSTEM_CONFIG_UPDATE_STRATEGY_REQUEST = Constant('create-system-config-update-strategy-request')
|
||||
CREATE_SW_UPDATE_STRATEGY_RESPONSE = Constant('create-sw-update-strategy-response')
|
||||
APPLY_SW_UPDATE_STRATEGY_REQUEST = Constant('apply-sw-update-strategy-request')
|
||||
APPLY_SW_UPDATE_STRATEGY_RESPONSE = Constant('apply-sw-update-strategy-response')
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2015-2021 Wind River Systems, Inc.
|
||||
# Copyright (c) 2015-2023 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -147,6 +147,7 @@ class RPCMessageFactory(object):
|
|||
from nfv_vim.rpc._rpc_message_sw_update import APIRequestCreateKubeUpgradeStrategy
|
||||
from nfv_vim.rpc._rpc_message_sw_update import APIRequestCreateSwUpdateStrategy
|
||||
from nfv_vim.rpc._rpc_message_sw_update import APIRequestCreateSwUpgradeStrategy
|
||||
from nfv_vim.rpc._rpc_message_sw_update import APIRequestCreateSystemConfigUpdateStrategy
|
||||
from nfv_vim.rpc._rpc_message_sw_update import APIRequestDeleteSwUpdateStrategy
|
||||
from nfv_vim.rpc._rpc_message_sw_update import APIRequestGetSwUpdateStrategy
|
||||
from nfv_vim.rpc._rpc_message_sw_update import APIResponseAbortSwUpdateStrategy
|
||||
|
@ -230,6 +231,7 @@ class RPCMessageFactory(object):
|
|||
RPC_MSG_TYPE.CREATE_KUBE_UPGRADE_STRATEGY_REQUEST: APIRequestCreateKubeUpgradeStrategy,
|
||||
RPC_MSG_TYPE.CREATE_SW_UPGRADE_STRATEGY_REQUEST: APIRequestCreateSwUpgradeStrategy,
|
||||
RPC_MSG_TYPE.CREATE_SW_UPDATE_STRATEGY_RESPONSE: APIResponseCreateSwUpdateStrategy,
|
||||
RPC_MSG_TYPE.CREATE_SYSTEM_CONFIG_UPDATE_STRATEGY_REQUEST: APIRequestCreateSystemConfigUpdateStrategy,
|
||||
RPC_MSG_TYPE.APPLY_SW_UPDATE_STRATEGY_REQUEST: APIRequestApplySwUpdateStrategy,
|
||||
RPC_MSG_TYPE.APPLY_SW_UPDATE_STRATEGY_RESPONSE: APIResponseApplySwUpdateStrategy,
|
||||
RPC_MSG_TYPE.ABORT_SW_UPDATE_STRATEGY_REQUEST: APIRequestAbortSwUpdateStrategy,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2015-2021 Wind River Systems, Inc.
|
||||
# Copyright (c) 2015-2023 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -138,6 +138,21 @@ class APIRequestCreateKubeUpgradeStrategy(APIRequestCreateSwUpdateStrategy):
|
|||
return "create-kube-upgrade-strategy request: %s" % self.deserialize_payload
|
||||
|
||||
|
||||
class APIRequestCreateSystemConfigUpdateStrategy(APIRequestCreateSwUpdateStrategy):
|
||||
"""
|
||||
RPC API Request Message - Create System Config Update Strategy
|
||||
"""
|
||||
def __init__(self, msg_version=RPC_MSG_VERSION.VERSION_1_0,
|
||||
msg_type=RPC_MSG_TYPE.CREATE_SYSTEM_CONFIG_UPDATE_STRATEGY_REQUEST,
|
||||
msg_result=RPC_MSG_RESULT.SUCCESS):
|
||||
super(APIRequestCreateSystemConfigUpdateStrategy, self).__init__(
|
||||
msg_version, msg_type, msg_result)
|
||||
|
||||
def __str__(self):
|
||||
return "create-system-config-update-strategy request: %s" % \
|
||||
self.deserialize_payload
|
||||
|
||||
|
||||
class APIResponseCreateSwUpdateStrategy(RPCMessage):
|
||||
"""
|
||||
RPC API Response Message - Create Software Update Strategy
|
||||
|
|
|
@ -10,6 +10,7 @@ from nfv_vim.strategy._strategy import KubeUpgradeStrategy # noqa: F401
|
|||
from nfv_vim.strategy._strategy import strategy_rebuild_from_dict # noqa: F401
|
||||
from nfv_vim.strategy._strategy import SwPatchStrategy # noqa: F401
|
||||
from nfv_vim.strategy._strategy import SwUpgradeStrategy # noqa: F401
|
||||
from nfv_vim.strategy._strategy import SystemConfigUpdateStrategy # noqa: F401
|
||||
from nfv_vim.strategy._strategy_defs import STRATEGY_EVENT # noqa: F401
|
||||
from nfv_vim.strategy._strategy_stages import STRATEGY_STAGE_NAME # noqa: F401
|
||||
from nfv_vim.strategy._strategy_steps import ApplySwPatchesStep # noqa: F401
|
||||
|
@ -47,6 +48,7 @@ from nfv_vim.strategy._strategy_steps import QueryKubeUpgradeStep # noqa: F401
|
|||
from nfv_vim.strategy._strategy_steps import QueryKubeVersionsStep # noqa: F401
|
||||
from nfv_vim.strategy._strategy_steps import QuerySwPatchesStep # noqa: F401
|
||||
from nfv_vim.strategy._strategy_steps import QuerySwPatchHostsStep # noqa: F401
|
||||
from nfv_vim.strategy._strategy_steps import QuerySystemConfigUpdateHostsStep # noqa: F401
|
||||
from nfv_vim.strategy._strategy_steps import QueryUpgradeStep # noqa: F401
|
||||
from nfv_vim.strategy._strategy_steps import RebootHostsStep # noqa: F401
|
||||
from nfv_vim.strategy._strategy_steps import StartInstancesStep # noqa: F401
|
||||
|
@ -54,6 +56,7 @@ from nfv_vim.strategy._strategy_steps import StopInstancesStep # noqa: F401
|
|||
from nfv_vim.strategy._strategy_steps import STRATEGY_STEP_NAME # noqa: F401
|
||||
from nfv_vim.strategy._strategy_steps import SwactHostsStep # noqa: F401
|
||||
from nfv_vim.strategy._strategy_steps import SwPatchHostsStep # noqa: F401
|
||||
from nfv_vim.strategy._strategy_steps import SystemConfigUpdateHostsStep # noqa: F401
|
||||
from nfv_vim.strategy._strategy_steps import SystemStabilizeStep # noqa: F401
|
||||
from nfv_vim.strategy._strategy_steps import UnlockHostsStep # noqa: F401
|
||||
from nfv_vim.strategy._strategy_steps import UpgradeActivateStep # noqa: F401
|
||||
|
|
|
@ -36,6 +36,7 @@ class StrategyNames(Constants):
|
|||
FW_UPDATE = Constant('fw-update')
|
||||
KUBE_ROOTCA_UPDATE = Constant('kube-rootca-update')
|
||||
KUBE_UPGRADE = Constant('kube-upgrade')
|
||||
SYSYTEM_CONFIG_UPDATE = Constant('system-config-update')
|
||||
|
||||
|
||||
# Constant Instantiation
|
||||
|
@ -433,6 +434,21 @@ class SwUpdateStrategy(strategy.Strategy):
|
|||
self.sw_update_obj.strategy_abort_complete(
|
||||
False, self.abort_phase.result_reason)
|
||||
|
||||
def report_build_failure(self, reason):
|
||||
"""
|
||||
Report a build failure for the strategy
|
||||
|
||||
todo(yuxing): report all build failure use this method
|
||||
"""
|
||||
DLOG.warn("Strategy Build Failed: %s" % reason)
|
||||
self._state = strategy.STRATEGY_STATE.BUILD_FAILED
|
||||
self.build_phase.result = strategy.STRATEGY_PHASE_RESULT.FAILED
|
||||
self.build_phase.result_reason = reason
|
||||
self.sw_update_obj.strategy_build_complete(
|
||||
False,
|
||||
self.build_phase.result_reason)
|
||||
self.save()
|
||||
|
||||
def from_dict(self, data, build_phase=None, apply_phase=None, abort_phase=None):
|
||||
"""
|
||||
Initializes a software update strategy object using the given dictionary
|
||||
|
@ -863,6 +879,54 @@ class QueryKubeVersionsMixin(QueryMixinBase):
|
|||
data['nfvi_kube_versions_list_data'] = mixin_data
|
||||
|
||||
|
||||
class QuerySystemConfigUpdateHostsMixin(QueryMixinBase):
|
||||
"""This mixin is used through the QuerySystemConfigUpdateHostsMixin class"""
|
||||
|
||||
def initialize_mixin(self):
|
||||
super(QuerySystemConfigUpdateHostsMixin, self).initialize_mixin()
|
||||
self._nfvi_system_config_update_hosts = list()
|
||||
|
||||
@property
|
||||
def nfvi_system_config_update_hosts(self):
|
||||
"""
|
||||
Returns the System Config Update hosts from the NFVI layer
|
||||
"""
|
||||
return self._nfvi_system_config_update_hosts
|
||||
|
||||
@nfvi_system_config_update_hosts.setter
|
||||
def nfvi_system_config_update_hosts(self, nfvi_system_config_update_hosts):
|
||||
"""
|
||||
Save the System Config Update hosts from the NFVI Layer
|
||||
"""
|
||||
self._nfvi_system_config_update_hosts = nfvi_system_config_update_hosts
|
||||
|
||||
def mixin_from_dict(self, data):
|
||||
"""
|
||||
Extracts this mixin data from a dictionary
|
||||
"""
|
||||
super(QuerySystemConfigUpdateHostsMixin, self).mixin_from_dict(data)
|
||||
|
||||
from nfv_vim import nfvi
|
||||
|
||||
mixin_data = list()
|
||||
for host_data in data['nfvi_system_config_update_hosts_data']:
|
||||
host = nfvi.objects.v1.HostSystemConfigUpdate(
|
||||
host_data['name'],
|
||||
host_data['unlock_request'])
|
||||
mixin_data.append(host)
|
||||
self._nfvi_system_config_update_hosts = mixin_data
|
||||
|
||||
def mixin_as_dict(self, data):
|
||||
"""
|
||||
Updates the dictionary with this mixin data
|
||||
"""
|
||||
super(QuerySystemConfigUpdateHostsMixin, self).mixin_as_dict(data)
|
||||
mixin_data = list()
|
||||
for host in self._nfvi_system_config_update_hosts:
|
||||
mixin_data.append(host.as_dict())
|
||||
data['nfvi_system_config_update_hosts_data'] = mixin_data
|
||||
|
||||
|
||||
class UpdateControllerHostsMixin(object):
|
||||
|
||||
def _add_update_controller_strategy_stages(self,
|
||||
|
@ -990,6 +1054,19 @@ class PatchControllerHostsMixin(UpdateControllerHostsMixin):
|
|||
strategy.SwPatchHostsStep)
|
||||
|
||||
|
||||
class UpdateSystemConfigControllerHostsMixin(UpdateControllerHostsMixin):
|
||||
def _add_system_config_controller_strategy_stages(self, controllers):
|
||||
"""
|
||||
Add controller system config update stages to a strategy
|
||||
"""
|
||||
from nfv_vim import strategy
|
||||
return self._add_update_controller_strategy_stages(
|
||||
controllers,
|
||||
True,
|
||||
strategy.STRATEGY_STAGE_NAME.SYSTEM_CONFIG_UPDATE_CONTROLLERS,
|
||||
strategy.SystemConfigUpdateHostsStep)
|
||||
|
||||
|
||||
class UpgradeKubeletControllerHostsMixin(UpdateControllerHostsMixin):
|
||||
def _add_kubelet_controller_strategy_stages(self, controllers, to_version, reboot, stage_name):
|
||||
from nfv_vim import strategy
|
||||
|
@ -1064,6 +1141,19 @@ class PatchStorageHostsMixin(UpdateStorageHostsMixin):
|
|||
strategy.SwPatchHostsStep)
|
||||
|
||||
|
||||
class UpdateSystemConfigStorageHostsMixin(UpdateStorageHostsMixin):
|
||||
def _add_system_config_storage_strategy_stages(self, storage_hosts):
|
||||
"""
|
||||
Add storage system config update stages to a strategy
|
||||
"""
|
||||
from nfv_vim import strategy
|
||||
return self._add_update_storage_strategy_stages(
|
||||
storage_hosts,
|
||||
True,
|
||||
strategy.STRATEGY_STAGE_NAME.SYSTEM_CONFIG_UPDATE_STORAGE_HOSTS,
|
||||
strategy.SystemConfigUpdateHostsStep)
|
||||
|
||||
|
||||
class UpdateWorkerHostsMixin(object):
|
||||
"""
|
||||
Adds the ability to add update steps for worker hosts to a strategy.
|
||||
|
@ -1248,6 +1338,19 @@ class UpgradeKubeletWorkerHostsMixin(UpdateWorkerHostsMixin):
|
|||
extra_args=to_version)
|
||||
|
||||
|
||||
class UpdateSystemConfigWorkerHostsMixin(UpdateWorkerHostsMixin):
|
||||
def _add_system_config_worker_strategy_stages(self, worker_hosts):
|
||||
"""
|
||||
Add worker system config update stages to a strategy
|
||||
"""
|
||||
from nfv_vim import strategy
|
||||
return self._add_update_worker_strategy_stages(
|
||||
worker_hosts,
|
||||
True,
|
||||
strategy.STRATEGY_STAGE_NAME.SYSTEM_CONFIG_UPDATE_WORKER_HOSTS,
|
||||
strategy.SystemConfigUpdateHostsStep)
|
||||
|
||||
|
||||
###################################################################
|
||||
#
|
||||
# The Software Patch Strategy
|
||||
|
@ -2198,6 +2301,199 @@ class SwUpgradeStrategy(SwUpdateStrategy):
|
|||
return data
|
||||
|
||||
|
||||
###################################################################
|
||||
#
|
||||
# The System Config Update Strategy
|
||||
#
|
||||
###################################################################
|
||||
class SystemConfigUpdateStrategy(SwUpdateStrategy,
|
||||
QuerySystemConfigUpdateHostsMixin,
|
||||
UpdateSystemConfigControllerHostsMixin,
|
||||
UpdateSystemConfigStorageHostsMixin,
|
||||
UpdateSystemConfigWorkerHostsMixin):
|
||||
"""
|
||||
System Config Update - Strategy
|
||||
"""
|
||||
def __init__(self, uuid, controller_apply_type, storage_apply_type,
|
||||
worker_apply_type, max_parallel_worker_hosts,
|
||||
default_instance_action, alarm_restrictions,
|
||||
ignore_alarms, single_controller):
|
||||
super(SystemConfigUpdateStrategy, self).__init__(
|
||||
uuid,
|
||||
STRATEGY_NAME.SYSYTEM_CONFIG_UPDATE,
|
||||
controller_apply_type,
|
||||
storage_apply_type,
|
||||
SW_UPDATE_APPLY_TYPE.IGNORE,
|
||||
worker_apply_type,
|
||||
max_parallel_worker_hosts,
|
||||
default_instance_action,
|
||||
alarm_restrictions,
|
||||
ignore_alarms)
|
||||
|
||||
# The following alarms will not prevent a system config update operation
|
||||
IGNORE_ALARMS = ['100.103', # Memory threshold exceeded
|
||||
'200.001', # Locked Host
|
||||
'250.001', # System Config out of date
|
||||
'260.001', # Unreconciled resource
|
||||
'260.002', # Unsynchronized resource
|
||||
'280.001', # Subcloud resource off-line
|
||||
'280.002', # Subcloud resource out-of-sync
|
||||
'280.003', # Subcloud backup failed
|
||||
'500.200', # Certificate expiring soon
|
||||
'700.004', # VM stopped
|
||||
'750.006', # Configuration change requires reapply of an application
|
||||
'900.010', # System Config Update in progress
|
||||
'900.601', # System Config Update Auto Apply in progress
|
||||
]
|
||||
self._ignore_alarms += IGNORE_ALARMS
|
||||
self._single_controller = single_controller
|
||||
|
||||
# initialize the variables required by the mixins
|
||||
self.initialize_mixin()
|
||||
|
||||
def build(self):
|
||||
"""
|
||||
Build the strategy
|
||||
"""
|
||||
from nfv_vim import strategy
|
||||
|
||||
stage = strategy.StrategyStage(
|
||||
strategy.STRATEGY_STAGE_NAME.SYSTEM_CONFIG_UPDATE_QUERY)
|
||||
stage.add_step(strategy.QueryAlarmsStep(
|
||||
ignore_alarms=self._ignore_alarms))
|
||||
stage.add_step(strategy.QuerySystemConfigUpdateHostsStep())
|
||||
self.build_phase.add_stage(stage)
|
||||
super(SystemConfigUpdateStrategy, self).build()
|
||||
|
||||
def build_complete(self, result, result_reason):
|
||||
"""
|
||||
Strategy Build Complete
|
||||
"""
|
||||
from nfv_vim import strategy
|
||||
from nfv_vim import tables
|
||||
|
||||
result, result_reason = \
|
||||
super(SystemConfigUpdateStrategy, self).build_complete(result, result_reason)
|
||||
|
||||
DLOG.info("Build Complete Callback, result=%s, reason=%s."
|
||||
% (result, result_reason))
|
||||
|
||||
if result in [strategy.STRATEGY_RESULT.SUCCESS,
|
||||
strategy.STRATEGY_RESULT.DEGRADED]:
|
||||
|
||||
if self._nfvi_alarms:
|
||||
alarm_id_set = set()
|
||||
for alarm_data in self._nfvi_alarms:
|
||||
alarm_id_set.add(alarm_data['alarm_id'])
|
||||
alarm_id_list = ", ".join(sorted(alarm_id_set))
|
||||
DLOG.warn("System config update: Active alarms present [ %s ]"
|
||||
% alarm_id_list)
|
||||
self.report_build_failure("active alarms present [ %s ]"
|
||||
% alarm_id_list)
|
||||
|
||||
return
|
||||
|
||||
host_table = tables.tables_get_host_table()
|
||||
for host in list(host_table.values()):
|
||||
if HOST_PERSONALITY.WORKER in host.personality and \
|
||||
HOST_PERSONALITY.CONTROLLER not in host.personality:
|
||||
# Allow system config update orchestration when worker
|
||||
# hosts are available, locked or powered down.
|
||||
if not ((host.is_unlocked() and host.is_enabled() and
|
||||
host.is_available()) or
|
||||
(host.is_locked() and host.is_disabled() and
|
||||
host.is_offline()) or
|
||||
(host.is_locked() and host.is_disabled() and
|
||||
host.is_online())):
|
||||
self.report_build_failure(
|
||||
"all worker hosts must be unlocked-enabled-available, "
|
||||
"locked-disabled-online or locked-disabled-offline")
|
||||
return
|
||||
else:
|
||||
# Only allow system config update orchestration when all
|
||||
# controller and storage hosts are available. The config
|
||||
# update wil be blocked when we do not have full redundancy.
|
||||
if not (host.is_unlocked() and host.is_enabled() and
|
||||
host.is_available()):
|
||||
self.report_build_failure(
|
||||
"all %s hosts must be unlocked-enabled-available, "
|
||||
% host.personality)
|
||||
return
|
||||
|
||||
controller_hosts = list()
|
||||
storage_hosts = list()
|
||||
worker_hosts = list()
|
||||
host_list = list(host_table.values())
|
||||
|
||||
for host_resource in self.nfvi_system_config_update_hosts:
|
||||
for host in host_list:
|
||||
if host_resource.name == host.name:
|
||||
if HOST_PERSONALITY.CONTROLLER in host.personality and \
|
||||
host_resource.unlock_request != 'not_required':
|
||||
controller_hosts.append(host)
|
||||
|
||||
elif HOST_PERSONALITY.STORAGE in host.personality and \
|
||||
host_resource.unlock_request != 'not_required':
|
||||
storage_hosts.append(host)
|
||||
|
||||
if HOST_PERSONALITY.WORKER in host.personality and \
|
||||
host_resource.unlock_request != 'not_required':
|
||||
worker_hosts.append(host)
|
||||
|
||||
host_list.remove(host)
|
||||
break
|
||||
|
||||
STRATEGY_CREATION_COMMANDS = [
|
||||
(self._add_system_config_controller_strategy_stages,
|
||||
controller_hosts),
|
||||
(self._add_system_config_storage_strategy_stages,
|
||||
storage_hosts),
|
||||
(self._add_system_config_worker_strategy_stages,
|
||||
worker_hosts)
|
||||
]
|
||||
|
||||
for add_strategy_stages_function, host_list in \
|
||||
STRATEGY_CREATION_COMMANDS:
|
||||
if host_list:
|
||||
success, reason = add_strategy_stages_function(host_list)
|
||||
if not success:
|
||||
self.report_build_failure(reason)
|
||||
return
|
||||
|
||||
if 0 == len(self.apply_phase.stages):
|
||||
self.report_build_failure(
|
||||
"no system config updates need to be applied")
|
||||
return
|
||||
else:
|
||||
self.sw_update_obj.strategy_build_complete( # pylint: disable=no-member
|
||||
False, self.build_phase.result_reason)
|
||||
|
||||
self.sw_update_obj.strategy_build_complete(True, '') # pylint: disable=no-member
|
||||
self.save()
|
||||
|
||||
def from_dict(self, data, build_phase=None, apply_phase=None, abort_phase=None):
|
||||
"""
|
||||
Initializes a system config update strategy object using the given
|
||||
dictionary
|
||||
"""
|
||||
super(SystemConfigUpdateStrategy, self).from_dict(
|
||||
data, build_phase, apply_phase, abort_phase)
|
||||
self._single_controller = data['single_controller']
|
||||
|
||||
self.mixin_from_dict(data)
|
||||
return self
|
||||
|
||||
def as_dict(self):
|
||||
"""
|
||||
Represent the software upgrade strategy as a dictionary
|
||||
"""
|
||||
data = super(SystemConfigUpdateStrategy, self).as_dict()
|
||||
data['single_controller'] = self._single_controller
|
||||
|
||||
self.mixin_as_dict(data)
|
||||
return data
|
||||
|
||||
|
||||
###################################################################
|
||||
#
|
||||
# The Firmware Update Strategy
|
||||
|
@ -2610,21 +2906,6 @@ class KubeRootcaUpdateStrategy(SwUpdateStrategy,
|
|||
# initialize the variables required by the mixins
|
||||
self.initialize_mixin()
|
||||
|
||||
def report_build_failure(self, reason):
|
||||
"""
|
||||
Report a build failure for the strategy
|
||||
|
||||
todo(abailey): this should be in the superclass
|
||||
"""
|
||||
DLOG.warn("Strategy Build Failed: %s" % reason)
|
||||
self._state = strategy.STRATEGY_STATE.BUILD_FAILED
|
||||
self.build_phase.result = strategy.STRATEGY_PHASE_RESULT.FAILED
|
||||
self.build_phase.result_reason = reason
|
||||
self.sw_update_obj.strategy_build_complete(
|
||||
False,
|
||||
self.build_phase.result_reason)
|
||||
self.save()
|
||||
|
||||
def build(self):
|
||||
"""Build the strategy"""
|
||||
from nfv_vim import strategy
|
||||
|
@ -3444,16 +3725,6 @@ class KubeUpgradeStrategy(SwUpdateStrategy,
|
|||
stage.add_step(strategy.KubeUpgradeCleanupStep())
|
||||
self.apply_phase.add_stage(stage)
|
||||
|
||||
def report_build_failure(self, reason):
|
||||
DLOG.warn("Strategy Build Failed: %s" % reason)
|
||||
self._state = strategy.STRATEGY_STATE.BUILD_FAILED
|
||||
self.build_phase.result = strategy.STRATEGY_PHASE_RESULT.FAILED
|
||||
self.build_phase.result_reason = reason
|
||||
self.sw_update_obj.strategy_build_complete(
|
||||
False,
|
||||
self.build_phase.result_reason)
|
||||
self.save()
|
||||
|
||||
def get_first_host(self):
|
||||
"""
|
||||
This corresponds to the first host that should be updated.
|
||||
|
@ -3685,6 +3956,8 @@ def strategy_rebuild_from_dict(data):
|
|||
strategy_obj = object.__new__(SwPatchStrategy)
|
||||
elif STRATEGY_NAME.SW_UPGRADE == data['name']:
|
||||
strategy_obj = object.__new__(SwUpgradeStrategy)
|
||||
elif STRATEGY_NAME.SYSYTEM_CONFIG_UPDATE == data['name']:
|
||||
strategy_obj = object.__new__(SystemConfigUpdateStrategy)
|
||||
elif STRATEGY_NAME.FW_UPDATE == data['name']:
|
||||
strategy_obj = object.__new__(FwUpdateStrategy)
|
||||
elif STRATEGY_NAME.KUBE_ROOTCA_UPDATE == data['name']:
|
||||
|
|
|
@ -37,6 +37,11 @@ class StrategyStageNames(Constants):
|
|||
FW_UPDATE_HOSTS_QUERY = Constant('fw-update-hosts-query')
|
||||
FW_UPDATE_HOST_QUERY = Constant('fw-update-host-query')
|
||||
FW_UPDATE_WORKER_HOSTS = Constant('fw-update-worker-hosts')
|
||||
# system config update stages
|
||||
SYSTEM_CONFIG_UPDATE_QUERY = Constant('system-config-update-query')
|
||||
SYSTEM_CONFIG_UPDATE_CONTROLLERS = Constant('system-config-update-controllers')
|
||||
SYSTEM_CONFIG_UPDATE_STORAGE_HOSTS = Constant('system-config-update-storage-hosts')
|
||||
SYSTEM_CONFIG_UPDATE_WORKER_HOSTS = Constant('system-config-update-worker-hosts')
|
||||
# kube root ca update stages
|
||||
KUBE_ROOTCA_UPDATE_CERT = Constant('kube-rootca-update-cert')
|
||||
KUBE_ROOTCA_UPDATE_COMPLETE = Constant('kube-rootca-update-complete')
|
||||
|
|
|
@ -86,6 +86,9 @@ class StrategyStepNames(Constants):
|
|||
KUBE_HOST_UPGRADE_CONTROL_PLANE = \
|
||||
Constant('kube-host-upgrade-control-plane')
|
||||
KUBE_HOST_UPGRADE_KUBELET = Constant('kube-host-upgrade-kubelet')
|
||||
# system config update specific steps
|
||||
QUERY_SYSTEM_CONFIG_UPDATE_HOSTS = Constant('query-system-config-update-hosts')
|
||||
SYSTEM_CONFIG_UPDATE_HOSTS = Constant('system-config-update-hosts')
|
||||
|
||||
|
||||
# Constant Instantiation
|
||||
|
@ -809,6 +812,108 @@ class SwPatchHostsStep(strategy.StrategyStep):
|
|||
return data
|
||||
|
||||
|
||||
class SystemConfigUpdateHostsStep(strategy.StrategyStep):
|
||||
"""
|
||||
System Config Update Hosts - Strategy Step
|
||||
"""
|
||||
def __init__(self, hosts):
|
||||
super(SystemConfigUpdateHostsStep, self).__init__(
|
||||
STRATEGY_STEP_NAME.SYSTEM_CONFIG_UPDATE_HOSTS, timeout_in_secs=1800)
|
||||
self._hosts = hosts
|
||||
self._wait_time = 0
|
||||
self._host_names = list()
|
||||
self._host_uuids = list()
|
||||
self._query_inprogress = False
|
||||
|
||||
for host in hosts:
|
||||
self._host_names.append(host.name)
|
||||
self._host_uuids.append(host.uuid)
|
||||
|
||||
@coroutine
|
||||
def _query_hosts_callback(self):
|
||||
"""
|
||||
Query System Config Update Hosts Callback
|
||||
"""
|
||||
response = (yield)
|
||||
DLOG.debug("Query-Hosts callback response=%s." % response)
|
||||
|
||||
self._query_inprogress = False
|
||||
|
||||
if response['completed']:
|
||||
for host in response['result-data']:
|
||||
if host.unlock_request != 'unlock_required':
|
||||
# Keep waiting for the hosts to reach the unlock required
|
||||
# status
|
||||
pass
|
||||
|
||||
# Ready to unlock the hosts
|
||||
result = strategy.STRATEGY_STEP_RESULT.SUCCESS
|
||||
self.stage.step_complete(result, "")
|
||||
|
||||
def apply(self):
|
||||
"""
|
||||
System Config Update Hosts
|
||||
"""
|
||||
DLOG.info("Step (%s) apply for hosts %s." % (self._name,
|
||||
self._host_names))
|
||||
# Do nothing, wait for the callback to check the unlock request status
|
||||
return strategy.STRATEGY_STEP_RESULT.WAIT, ""
|
||||
|
||||
def handle_event(self, event, event_data=None):
|
||||
"""
|
||||
Handle Host events
|
||||
"""
|
||||
from nfv_vim import nfvi
|
||||
|
||||
DLOG.debug("Step (%s) handle event (%s)." % (self._name, event))
|
||||
|
||||
if event == STRATEGY_EVENT.HOST_AUDIT:
|
||||
if 0 == self._wait_time:
|
||||
self._wait_time = timers.get_monotonic_timestamp_in_ms()
|
||||
|
||||
now_ms = timers.get_monotonic_timestamp_in_ms()
|
||||
secs_expired = (now_ms - self._wait_time) // 1000
|
||||
# Wait at least 30 seconds before checking the unlock status for
|
||||
# first time
|
||||
if 30 <= secs_expired and not self._query_inprogress:
|
||||
self._query_inprogress = True
|
||||
nfvi.nfvi_get_system_config_unlock_request(
|
||||
self._host_names, self._query_hosts_callback())
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def from_dict(self, data):
|
||||
"""
|
||||
Returns the system config update hosts step object initialized using
|
||||
the given dictionary
|
||||
"""
|
||||
super(SystemConfigUpdateHostsStep, self).from_dict(data)
|
||||
self._hosts = list()
|
||||
self._wait_time = 0
|
||||
self._host_uuids = list()
|
||||
self._query_inprogress = False
|
||||
|
||||
self._host_names = data['entity_names']
|
||||
host_table = tables.tables_get_host_table()
|
||||
for host_name in self._host_names:
|
||||
host = host_table.get(host_name, None)
|
||||
if host is not None:
|
||||
self._hosts.append(host)
|
||||
self._host_uuids.append(host.uuid)
|
||||
return self
|
||||
|
||||
def as_dict(self):
|
||||
"""
|
||||
Represent the system config update hosts step as a dictionary
|
||||
"""
|
||||
data = super(SystemConfigUpdateHostsStep, self).as_dict()
|
||||
data['entity_type'] = 'hosts'
|
||||
data['entity_names'] = self._host_names
|
||||
data['entity_uuids'] = self._host_uuids
|
||||
return data
|
||||
|
||||
|
||||
class UpgradeHostsStep(strategy.StrategyStep):
|
||||
"""
|
||||
Upgrade Hosts - Strategy Step
|
||||
|
@ -2197,6 +2302,45 @@ class QuerySwPatchHostsStep(strategy.StrategyStep):
|
|||
return data
|
||||
|
||||
|
||||
class QuerySystemConfigUpdateHostsStep(AbstractStrategyStep):
|
||||
"""
|
||||
Query System Config Update Hosts - Strategy Step
|
||||
"""
|
||||
def __init__(self):
|
||||
super(QuerySystemConfigUpdateHostsStep, self).__init__(
|
||||
STRATEGY_STEP_NAME.QUERY_SYSTEM_CONFIG_UPDATE_HOSTS,
|
||||
timeout_in_secs=60)
|
||||
|
||||
@coroutine
|
||||
def _query_hosts_callback(self):
|
||||
"""
|
||||
Query System Config Update Hosts Callback
|
||||
"""
|
||||
response = (yield)
|
||||
DLOG.debug("Query-Hosts callback response=%s." % response)
|
||||
|
||||
if response['completed']:
|
||||
if self.strategy is not None:
|
||||
self.strategy.nfvi_system_config_update_hosts = \
|
||||
response['result-data']
|
||||
|
||||
result = strategy.STRATEGY_STEP_RESULT.SUCCESS
|
||||
self.stage.step_complete(result, "")
|
||||
else:
|
||||
result = strategy.STRATEGY_STEP_RESULT.FAILED
|
||||
self.stage.step_complete(result, "")
|
||||
|
||||
def apply(self):
|
||||
"""
|
||||
Query System Config Update Hosts
|
||||
"""
|
||||
from nfv_vim import nfvi
|
||||
|
||||
DLOG.info("Step (%s) apply." % self._name)
|
||||
nfvi.nfvi_list_deployment_hosts(self._query_hosts_callback())
|
||||
return strategy.STRATEGY_STEP_RESULT.WAIT, ""
|
||||
|
||||
|
||||
class QueryFwUpdateHostStep(strategy.StrategyStep):
|
||||
"""
|
||||
Query Host
|
||||
|
@ -4711,6 +4855,13 @@ def strategy_step_rebuild_from_dict(data):
|
|||
STRATEGY_STEP_NAME.QUERY_KUBE_HOST_UPGRADE: QueryKubeHostUpgradeStep,
|
||||
STRATEGY_STEP_NAME.QUERY_KUBE_UPGRADE: QueryKubeUpgradeStep,
|
||||
STRATEGY_STEP_NAME.QUERY_KUBE_VERSIONS: QueryKubeVersionsStep,
|
||||
#
|
||||
# system config update steps
|
||||
#
|
||||
STRATEGY_STEP_NAME.QUERY_SYSTEM_CONFIG_UPDATE_HOSTS:
|
||||
QuerySystemConfigUpdateHostsStep,
|
||||
STRATEGY_STEP_NAME.SYSTEM_CONFIG_UPDATE_HOSTS:
|
||||
SystemConfigUpdateHostsStep,
|
||||
}
|
||||
obj_type = rebuild_map.get(data['name'])
|
||||
if obj_type is not None:
|
||||
|
|
Loading…
Reference in New Issue