...

Source file src/github.com/chaos-mesh/chaos-mesh/pkg/workflow/controllers/new_node.go

Documentation: github.com/chaos-mesh/chaos-mesh/pkg/workflow/controllers

     1  // Copyright 2021 Chaos Mesh Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  // http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  //
    15  
    16  package controllers
    17  
    18  import (
    19  	"fmt"
    20  	"time"
    21  
    22  	"github.com/pkg/errors"
    23  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    24  
    25  	"github.com/chaos-mesh/chaos-mesh/api/v1alpha1"
    26  )
    27  
    28  var (
    29  	isController       = true
    30  	blockOwnerDeletion = true
    31  	ApiVersion         = v1alpha1.GroupVersion.String()
    32  	KindWorkflow       = "Workflow"
    33  	KindWorkflowNode   = "WorkflowNode"
    34  )
    35  
    36  // renderNodesByTemplates will render the nodes one by one, will setup owner by given parent. If parent is nil, it will use workflow as its owner.
    37  func renderNodesByTemplates(workflow *v1alpha1.Workflow, parent *v1alpha1.WorkflowNode, templates ...string) ([]*v1alpha1.WorkflowNode, error) {
    38  	templateNameSet := make(map[string]v1alpha1.Template)
    39  	for _, template := range workflow.Spec.Templates {
    40  		templateNameSet[template.Name] = template
    41  	}
    42  	var result []*v1alpha1.WorkflowNode
    43  	for _, name := range templates {
    44  		if template, ok := templateNameSet[name]; ok {
    45  
    46  			now := metav1.NewTime(time.Now())
    47  			var deadline *metav1.Time = nil
    48  
    49  			if template.Deadline != nil {
    50  				duration, err := time.ParseDuration(*template.Deadline)
    51  				if err != nil {
    52  					// TODO: logger
    53  					return nil, err
    54  				}
    55  				copiedDuration := metav1.NewTime(now.DeepCopy().Add(duration))
    56  				deadline = &copiedDuration
    57  			}
    58  
    59  			renderedNode := v1alpha1.WorkflowNode{
    60  				ObjectMeta: metav1.ObjectMeta{
    61  					Namespace:    workflow.Namespace,
    62  					GenerateName: fmt.Sprintf("%s-", template.Name),
    63  				},
    64  				Spec: v1alpha1.WorkflowNodeSpec{
    65  					TemplateName:         template.Name,
    66  					WorkflowName:         workflow.Name,
    67  					Type:                 template.Type,
    68  					StartTime:            &now,
    69  					Deadline:             deadline,
    70  					Children:             template.Children,
    71  					Task:                 template.Task,
    72  					ConditionalBranches:  template.ConditionalBranches,
    73  					EmbedChaos:           template.EmbedChaos,
    74  					Schedule:             conversionSchedule(template.Schedule),
    75  					StatusCheck:          template.StatusCheck,
    76  					AbortWithStatusCheck: template.AbortWithStatusCheck,
    77  				},
    78  			}
    79  
    80  			// if parent is specified, use parent as owner, else use workflow as owner.
    81  			if parent != nil {
    82  				renderedNode.OwnerReferences = append(renderedNode.OwnerReferences, metav1.OwnerReference{
    83  					APIVersion:         ApiVersion,
    84  					Kind:               KindWorkflowNode,
    85  					Name:               parent.Name,
    86  					UID:                parent.UID,
    87  					Controller:         &isController,
    88  					BlockOwnerDeletion: &blockOwnerDeletion,
    89  				})
    90  				if renderedNode.Labels == nil {
    91  					renderedNode.Labels = make(map[string]string)
    92  				}
    93  				renderedNode.Labels[v1alpha1.LabelControlledBy] = parent.Name
    94  			} else {
    95  				renderedNode.OwnerReferences = append(renderedNode.OwnerReferences, metav1.OwnerReference{
    96  					APIVersion:         ApiVersion,
    97  					Kind:               KindWorkflow,
    98  					Name:               workflow.Name,
    99  					UID:                workflow.UID,
   100  					Controller:         &isController,
   101  					BlockOwnerDeletion: &blockOwnerDeletion,
   102  				})
   103  				if renderedNode.Labels == nil {
   104  					renderedNode.Labels = make(map[string]string)
   105  				}
   106  				renderedNode.Labels[v1alpha1.LabelControlledBy] = workflow.Name
   107  			}
   108  
   109  			renderedNode.Labels[v1alpha1.LabelWorkflow] = workflow.Name
   110  			renderedNode.Finalizers = append(renderedNode.Finalizers, metav1.FinalizerDeleteDependents)
   111  
   112  			result = append(result, &renderedNode)
   113  			continue
   114  		}
   115  		return nil, errors.Errorf(
   116  			"workflow %s do not contains template called %s",
   117  			workflow.Name,
   118  			name,
   119  		)
   120  	}
   121  	return result, nil
   122  }
   123  
   124  func conversionSchedule(origin *v1alpha1.ChaosOnlyScheduleSpec) *v1alpha1.ScheduleSpec {
   125  	if origin == nil {
   126  		return nil
   127  	}
   128  	return &v1alpha1.ScheduleSpec{
   129  		Schedule:                origin.Schedule,
   130  		StartingDeadlineSeconds: origin.StartingDeadlineSeconds,
   131  		ConcurrencyPolicy:       origin.ConcurrencyPolicy,
   132  		HistoryLimit:            origin.HistoryLimit,
   133  		Type:                    origin.Type,
   134  		ScheduleItem: v1alpha1.ScheduleItem{
   135  			EmbedChaos: v1alpha1.EmbedChaos{
   136  				AWSChaos:             origin.EmbedChaos.AWSChaos,
   137  				DNSChaos:             origin.EmbedChaos.DNSChaos,
   138  				GCPChaos:             origin.EmbedChaos.GCPChaos,
   139  				HTTPChaos:            origin.EmbedChaos.HTTPChaos,
   140  				IOChaos:              origin.EmbedChaos.IOChaos,
   141  				JVMChaos:             origin.EmbedChaos.JVMChaos,
   142  				KernelChaos:          origin.EmbedChaos.KernelChaos,
   143  				NetworkChaos:         origin.EmbedChaos.NetworkChaos,
   144  				PodChaos:             origin.EmbedChaos.PodChaos,
   145  				StressChaos:          origin.EmbedChaos.StressChaos,
   146  				TimeChaos:            origin.EmbedChaos.TimeChaos,
   147  				PhysicalMachineChaos: origin.EmbedChaos.PhysicalMachineChaos,
   148  			},
   149  			Workflow: nil,
   150  		},
   151  	}
   152  }
   153