From 503f03cd6c2bcb6148b3535202125a8f2ce5d965 Mon Sep 17 00:00:00 2001 From: Atif Ali Date: Mon, 3 Apr 2023 12:48:52 -0400 Subject: [PATCH] CASMTRIAGE-5124 patch activity doesn't truly work like patch activity (#168) * CASMTRIAGE-5124 patch activity doesn't truly work like patch activity * CASMTRIAGE-5124 update .version * CASMTRIAGE-5124 update stale API doc --- .version | 2 +- charts/v1.0/cray-nls/Chart.yaml | 2 +- charts/v1.0/cray-nls/values.yaml | 2 +- docs/IUF_docs.go | 11 ++++-- docs/IUF_swagger.yaml | 13 +++++-- docs/NLS_docs.go | 6 ++++ docs/NLS_swagger.yaml | 4 +++ src/api/models/iuf/activities.go | 6 ++-- src/api/models/iuf/shared.go | 19 ++++++++-- src/api/services/iuf/activities.go | 47 +++++++++++++++++++++---- src/api/services/iuf/activities_test.go | 7 ++-- src/api/services/iuf/history.go | 15 +++++++- 12 files changed, 113 insertions(+), 21 deletions(-) diff --git a/.version b/.version index 1a46c7f1..f314d020 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -0.10.8 +0.10.9 diff --git a/charts/v1.0/cray-nls/Chart.yaml b/charts/v1.0/cray-nls/Chart.yaml index fa13f689..90457b08 100644 --- a/charts/v1.0/cray-nls/Chart.yaml +++ b/charts/v1.0/cray-nls/Chart.yaml @@ -24,7 +24,7 @@ apiVersion: v2 name: "cray-nls" -version: 1.4.61-debug3 +version: 1.4.65-debug1 description: "Kubernetes resources for cray-nls" home: "https://github.com/Cray-HPE/cray-nls-charts" sources: diff --git a/charts/v1.0/cray-nls/values.yaml b/charts/v1.0/cray-nls/values.yaml index 76dac488..ef6b45dd 100644 --- a/charts/v1.0/cray-nls/values.yaml +++ b/charts/v1.0/cray-nls/values.yaml @@ -104,7 +104,7 @@ cray-service: name: "cray-nls" image: repository: artifactory.algol60.net/csm-docker/stable/cray-nls - tag: 0.10.6-debug3 + tag: 0.10.9-debug1 resources: limits: cpu: 1 diff --git a/docs/IUF_docs.go b/docs/IUF_docs.go index 4f5ae0cf..4c97b980 100644 --- a/docs/IUF_docs.go +++ b/docs/IUF_docs.go @@ -931,14 +931,14 @@ const docTemplateIUF = `{ "type": "boolean" }, "limit_managed_nodes": { - "description": "Each item is the xname of a managed node", + "description": "Anything accepted by BOS v2 as the value to a session's limit parameter.", "type": "array", "items": { "type": "string" } }, "limit_management_nodes": { - "description": "Each item is the xname of a management node", + "description": "Must in the form \u003crole\u003e_\u003csubrole\u003e. E.g. Management_Master, Management_Worker, Management_Storage", "type": "array", "items": { "type": "string" @@ -984,6 +984,9 @@ const docTemplateIUF = `{ "static-parameters" ], "properties": { + "include-default-product-in-site-params": { + "type": "boolean" + }, "name": { "description": "Name of the operation", "type": "string" @@ -1159,6 +1162,10 @@ const docTemplateIUF = `{ "$ref": "#/definitions/iuf.Operations" } }, + "process-product-variants-sequentially": { + "description": "this stage wants to make sure all products with the same name (but different versions) are processed sequentially, not in parallel, to avoid operational race conditions", + "type": "boolean" + }, "type": { "description": "Type of the stage", "type": "string" diff --git a/docs/IUF_swagger.yaml b/docs/IUF_swagger.yaml index 14d46950..1733590b 100644 --- a/docs/IUF_swagger.yaml +++ b/docs/IUF_swagger.yaml @@ -183,12 +183,14 @@ definitions: description: Force re-execution of stage operations type: boolean limit_managed_nodes: - description: Each item is the xname of a managed node + description: Anything accepted by BOS v2 as the value to a session's limit + parameter. items: type: string type: array limit_management_nodes: - description: Each item is the xname of a management node + description: Must in the form _. E.g. Management_Master, Management_Worker, + Management_Storage items: type: string type: array @@ -218,6 +220,8 @@ definitions: type: object iuf.Operations: properties: + include-default-product-in-site-params: + type: boolean name: description: Name of the operation type: string @@ -344,6 +348,11 @@ definitions: items: $ref: '#/definitions/iuf.Operations' type: array + process-product-variants-sequentially: + description: this stage wants to make sure all products with the same name + (but different versions) are processed sequentially, not in parallel, to + avoid operational race conditions + type: boolean type: description: Type of the stage type: string diff --git a/docs/NLS_docs.go b/docs/NLS_docs.go index 0834a571..5798649e 100644 --- a/docs/NLS_docs.go +++ b/docs/NLS_docs.go @@ -420,6 +420,12 @@ const docTemplateNLS = `{ "imageId": { "type": "string" }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, "switchPassword": { "type": "string" }, diff --git a/docs/NLS_swagger.yaml b/docs/NLS_swagger.yaml index 01173d84..8e4df104 100644 --- a/docs/NLS_swagger.yaml +++ b/docs/NLS_swagger.yaml @@ -67,6 +67,10 @@ definitions: type: array imageId: type: string + labels: + additionalProperties: + type: string + type: object switchPassword: type: string workflowType: diff --git a/src/api/models/iuf/activities.go b/src/api/models/iuf/activities.go index 6f69c4f0..b7b432d9 100644 --- a/src/api/models/iuf/activities.go +++ b/src/api/models/iuf/activities.go @@ -41,9 +41,9 @@ type CreateActivityRequest struct { } // @name Activity.CreateActivityRequest type PatchActivityRequest struct { - InputParameters InputParameters `json:"input_parameters"` - SiteParameters SiteParameters `json:"site_parameters"` - ActivityState ActivityState `json:"activity_state" enums:"paused,in_progress,debug,blocked,wait_for_admin"` // State of activity + InputParameters InputParametersPatch `json:"input_parameters"` + SiteParameters SiteParameters `json:"site_parameters"` + ActivityState ActivityState `json:"activity_state" enums:"paused,in_progress,debug,blocked,wait_for_admin"` // State of activity } // @name Activity.PatchActivityRequest type ActivityState string diff --git a/src/api/models/iuf/shared.go b/src/api/models/iuf/shared.go index 519a305b..8b9de1a9 100644 --- a/src/api/models/iuf/shared.go +++ b/src/api/models/iuf/shared.go @@ -36,8 +36,8 @@ type Product struct { type InputParameters struct { MediaDir string `json:"media_dir"` // Location of media SiteParameters string `json:"site_parameters"` // DEPRECATED: use site_parameters at the top level of the activity or session resource. The inline contents of the site_parameters.yaml file. - LimitManagementNodes []string `json:"limit_management_nodes"` // Each item is the xname of a management node - LimitManagedNodes []string `json:"limit_managed_nodes"` // Each item is the xname of a managed node + LimitManagementNodes []string `json:"limit_management_nodes"` // Must in the form _. E.g. Management_Master, Management_Worker, Management_Storage + LimitManagedNodes []string `json:"limit_managed_nodes"` // Anything accepted by BOS v2 as the value to a session's limit parameter. ManagedRolloutStrategy EManagedRolloutStrategy `json:"managed_rollout_strategy" enums:"reboot,stage"` // Whether to use a reboot or staged rollout strategy for managed nodes. Refer to BOS v2 for more details. ConcurrentManagementRolloutPercentage int64 `json:"concurrent_management_rollout_percentage"` // The percentage of management nodes to reboot in parallel before moving on to the next set of management nodes to reboot. MediaHost string `json:"media_host"` // A string containing the hostname of where the media is located @@ -48,6 +48,21 @@ type InputParameters struct { Force bool `json:"force"` // Force re-execution of stage operations } // @name InputParameters +type InputParametersPatch struct { + MediaDir *string `json:"media_dir"` // Location of media + SiteParameters *string `json:"site_parameters"` // DEPRECATED: use site_parameters at the top level of the activity or session resource. The inline contents of the site_parameters.yaml file. + LimitManagementNodes *[]string `json:"limit_management_nodes"` // Must in the form _. E.g. Management_Master, Management_Worker, Management_Storage + LimitManagedNodes *[]string `json:"limit_managed_nodes"` // Anything accepted by BOS v2 as the value to a session's limit parameter. + ManagedRolloutStrategy *EManagedRolloutStrategy `json:"managed_rollout_strategy" enums:"reboot,stage"` // Whether to use a reboot or staged rollout strategy for managed nodes. Refer to BOS v2 for more details. + ConcurrentManagementRolloutPercentage *int64 `json:"concurrent_management_rollout_percentage"` // The percentage of management nodes to reboot in parallel before moving on to the next set of management nodes to reboot. + MediaHost *string `json:"media_host"` // A string containing the hostname of where the media is located + Concurrency *int64 `json:"concurrency"` // An integer defining how many products / operations can we concurrently execute. + BootprepConfigManaged *string `json:"bootprep_config_managed"` // The path to the bootprep config file for managed nodes, relative to the media_dir + BootprepConfigManagement *string `json:"bootprep_config_management"` // The path to the bootprep config file for management nodes, relative to the media_dir + Stages *[]string `json:"stages"` // Stages to execute + Force *bool `json:"force"` // Force re-execution of stage operations +} // @name InputParameters + type EManagedRolloutStrategy string const ( diff --git a/src/api/services/iuf/activities.go b/src/api/services/iuf/activities.go index d0adfcb6..dad6b0d4 100644 --- a/src/api/services/iuf/activities.go +++ b/src/api/services/iuf/activities.go @@ -136,14 +136,49 @@ func (s iufService) GetActivity(name string) (iuf.Activity, error) { func (s iufService) PatchActivity(activity iuf.Activity, patchParams iuf.PatchActivityRequest) (iuf.Activity, error) { s.logger.Infof("Called: PatchActivity(activity: %v, patchParams: %v)", activity, patchParams) - if patchParams.InputParameters.MediaDir != "" { - // input parameters exists - activity.InputParameters = patchParams.InputParameters + if patchParams.InputParameters.MediaDir != nil { + activity.InputParameters.MediaDir = *(patchParams.InputParameters.MediaDir) + } + if patchParams.InputParameters.SiteParameters != nil { + activity.InputParameters.SiteParameters = *(patchParams.InputParameters.SiteParameters) + } + if patchParams.InputParameters.LimitManagementNodes != nil { + activity.InputParameters.LimitManagementNodes = *(patchParams.InputParameters.LimitManagementNodes) + } + if patchParams.InputParameters.LimitManagedNodes != nil { + activity.InputParameters.LimitManagedNodes = *(patchParams.InputParameters.LimitManagedNodes) + } + if patchParams.InputParameters.ManagedRolloutStrategy != nil { + activity.InputParameters.ManagedRolloutStrategy = *(patchParams.InputParameters.ManagedRolloutStrategy) + } + if patchParams.InputParameters.ConcurrentManagementRolloutPercentage != nil { + activity.InputParameters.ConcurrentManagementRolloutPercentage = *(patchParams.InputParameters.ConcurrentManagementRolloutPercentage) + } + if patchParams.InputParameters.MediaHost != nil { + activity.InputParameters.MediaHost = *(patchParams.InputParameters.MediaHost) + } + if patchParams.InputParameters.Concurrency != nil { + activity.InputParameters.Concurrency = *(patchParams.InputParameters.Concurrency) + } + if patchParams.InputParameters.BootprepConfigManaged != nil { + activity.InputParameters.BootprepConfigManaged = *(patchParams.InputParameters.BootprepConfigManaged) + } + if patchParams.InputParameters.BootprepConfigManagement != nil { + activity.InputParameters.BootprepConfigManagement = *(patchParams.InputParameters.BootprepConfigManagement) + } + if patchParams.InputParameters.Stages != nil { + activity.InputParameters.Stages = *(patchParams.InputParameters.Stages) + } + if patchParams.InputParameters.Force != nil { + activity.InputParameters.Force = *(patchParams.InputParameters.Force) } - // patch site parameters - if len(patchParams.SiteParameters.Products) > 0 || len(patchParams.SiteParameters.Global) > 0 { - activity.SiteParameters = patchParams.SiteParameters + // patch site parameters...all or nothing for Products and Global attributes + if len(patchParams.SiteParameters.Products) > 0 { + activity.SiteParameters.Products = patchParams.SiteParameters.Products + } + if len(patchParams.SiteParameters.Global) > 0 { + activity.SiteParameters.Global = patchParams.SiteParameters.Global } // only allow patching activity state in a limited way. diff --git a/src/api/services/iuf/activities_test.go b/src/api/services/iuf/activities_test.go index f5e589c8..ba964b50 100644 --- a/src/api/services/iuf/activities_test.go +++ b/src/api/services/iuf/activities_test.go @@ -176,20 +176,23 @@ func TestPatchActivity(t *testing.T) { Name: "test", InputParameters: iuf.InputParameters{ MediaDir: "/a/b/c", - BootprepConfigManagement: "BootprepConfigManagement", SiteParameters: "deprecated_field", + LimitManagementNodes: []string{"Management_Master"}, + BootprepConfigManagement: "BootprepConfigManagement", }, }, expectActivity: iuf.Activity{ Name: "test", InputParameters: iuf.InputParameters{ MediaDir: "/a/b/c", + SiteParameters: "deprecated_field", + LimitManagementNodes: []string{"Management_Worker"}, BootprepConfigManagement: "BootprepConfigManagement", BootprepConfigManaged: "BootprepConfigManaged", Force: true, }, }, - req: toPatchRequest(`{"input_parameters": {"media_dir": "/a/b/c", "force": true, "bootprep_config_management": "BootprepConfigManagement", "bootprep_config_managed": "BootprepConfigManaged"}}`), + req: toPatchRequest(`{"input_parameters": {"limit_management_nodes": ["Management_Worker"], "force": true, "bootprep_config_managed": "BootprepConfigManaged"}}`), wantErr: false, }, { diff --git a/src/api/services/iuf/history.go b/src/api/services/iuf/history.go index 795a7a5f..4fcc189d 100644 --- a/src/api/services/iuf/history.go +++ b/src/api/services/iuf/history.go @@ -146,10 +146,23 @@ func (s iufService) HistoryRunAction(activityName string, req iuf.HistoryRunActi return iuf.Session{}, err } + inputParamsForPatch := iuf.InputParametersPatch{} + jsonInputParams, err := json.Marshal(req.InputParameters) + if err != nil { + s.logger.Errorf("HistoryRunAction.4: for activity %s, error while parsing input parameters: %#v", activityName, req.InputParameters) + return iuf.Session{}, err + } + err = json.Unmarshal(jsonInputParams, &inputParamsForPatch) + if err != nil { + s.logger.Errorf("HistoryRunAction.5: for activity %s, error while parsing input parameters: %#v", activityName, req.InputParameters) + return iuf.Session{}, err + } + activity, err = s.PatchActivity(activity, iuf.PatchActivityRequest{ - InputParameters: req.InputParameters, + InputParameters: inputParamsForPatch, SiteParameters: req.SiteParameters, }) + if err != nil { s.logger.Error(err) return iuf.Session{}, err