1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-07-24 07:49:41 +02:00

feat(stacks): add support for stack deploy (#1280)

This commit is contained in:
Anthony Lapenna 2017-10-15 19:24:40 +02:00 committed by GitHub
parent 80827935da
commit 587e2fa673
77 changed files with 3219 additions and 702 deletions

View file

@ -10,6 +10,7 @@ const (
// ErrDockerTaskServiceIdentifierNotFound defines an error raised when Portainer is unable to find the service identifier associated to a task
ErrDockerTaskServiceIdentifierNotFound = portainer.Error("Docker task service identifier not found")
taskServiceIdentifier = "ServiceID"
taskLabelForStackIdentifier = "com.docker.stack.namespace"
)
// taskListOperation extracts the response as a JSON object, loop through the tasks array
@ -25,8 +26,7 @@ func taskListOperation(request *http.Request, response *http.Response, executor
}
if !executor.operationContext.isAdmin {
responseArray, err = filterTaskList(responseArray, executor.operationContext.resourceControls,
executor.operationContext.userID, executor.operationContext.userTeamIDs)
responseArray, err = filterTaskList(responseArray, executor.operationContext)
if err != nil {
return err
}
@ -34,3 +34,45 @@ func taskListOperation(request *http.Request, response *http.Response, executor
return rewriteResponse(response, responseArray, http.StatusOK)
}
// extractTaskLabelsFromTaskListObject retrieve the Labels of the task if present.
// Task schema reference: https://docs.docker.com/engine/api/v1.28/#operation/TaskList
func extractTaskLabelsFromTaskListObject(responseObject map[string]interface{}) map[string]interface{} {
// Labels are stored under Spec.ContainerSpec.Labels
taskSpecObject := extractJSONField(responseObject, "Spec")
if taskSpecObject != nil {
containerSpecObject := extractJSONField(taskSpecObject, "ContainerSpec")
if containerSpecObject != nil {
return extractJSONField(containerSpecObject, "Labels")
}
}
return nil
}
// filterTaskList loops through all tasks and filters public tasks (no associated resource control)
// as well as authorized tasks (access granted to the user based on existing resource control).
// Resource controls checks are based on: service identifier, stack identifier (from label).
// Task object schema reference: https://docs.docker.com/engine/api/v1.28/#operation/TaskList
// any resource control giving access to the user based on the associated service identifier.
func filterTaskList(taskData []interface{}, context *restrictedOperationContext) ([]interface{}, error) {
filteredTaskData := make([]interface{}, 0)
for _, task := range taskData {
taskObject := task.(map[string]interface{})
if taskObject[taskServiceIdentifier] == nil {
return nil, ErrDockerTaskServiceIdentifierNotFound
}
serviceID := taskObject[taskServiceIdentifier].(string)
taskObject, access := applyResourceAccessControl(taskObject, serviceID, context)
if access {
taskLabels := extractTaskLabelsFromTaskListObject(taskObject)
taskObject, access = applyResourceAccessControlFromLabel(taskLabels, taskObject, taskLabelForStackIdentifier, context)
if access {
filteredTaskData = append(filteredTaskData, taskObject)
}
}
}
return filteredTaskData, nil
}