...

Source file src/github.com/chaos-mesh/chaos-mesh/cmd/chaos-builder/impl.go

Documentation: github.com/chaos-mesh/chaos-mesh/cmd/chaos-builder

     1  // Copyright 2020 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  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package main
    15  
    16  import (
    17  	"bytes"
    18  	"text/template"
    19  )
    20  
    21  const implImport = `
    22  import (
    23  	"encoding/json"
    24  	"reflect"
    25  	"time"
    26  
    27  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    28  )
    29  `
    30  
    31  const implTemplate = `
    32  const Kind{{.Type}} = "{{.Type}}"
    33  
    34  // IsDeleted returns whether this resource has been deleted
    35  func (in *{{.Type}}) IsDeleted() bool {
    36  	return !in.DeletionTimestamp.IsZero()
    37  }
    38  
    39  // IsPaused returns whether this resource has been paused
    40  func (in *{{.Type}}) IsPaused() bool {
    41  	if in.Annotations == nil || in.Annotations[PauseAnnotationKey] != "true" {
    42  		return false
    43  	}
    44  	return true
    45  }
    46  
    47  // GetDuration would return the duration for chaos
    48  func (in *{{.Type}}) GetDuration() (*time.Duration, error) {
    49  	if in.Spec.Duration == nil {
    50  		return nil, nil
    51  	}
    52  	duration, err := time.ParseDuration(*in.Spec.Duration)
    53  	if err != nil {
    54  		return nil, err
    55  	}
    56  	return &duration, nil
    57  }
    58  
    59  func (in *{{.Type}}) GetNextStart() time.Time {
    60  	if in.Status.Scheduler.NextStart == nil {
    61  		return time.Time{}
    62  	}
    63  	return in.Status.Scheduler.NextStart.Time
    64  }
    65  
    66  func (in *{{.Type}}) SetNextStart(t time.Time) {
    67  	if t.IsZero() {
    68  		in.Status.Scheduler.NextStart = nil
    69  		return
    70  	}
    71  
    72  	if in.Status.Scheduler.NextStart == nil {
    73  		in.Status.Scheduler.NextStart = &metav1.Time{}
    74  	}
    75  	in.Status.Scheduler.NextStart.Time = t
    76  }
    77  
    78  func (in *{{.Type}}) GetNextRecover() time.Time {
    79  	if in.Status.Scheduler.NextRecover == nil {
    80  		return time.Time{}
    81  	}
    82  	return in.Status.Scheduler.NextRecover.Time
    83  }
    84  
    85  func (in *{{.Type}}) SetNextRecover(t time.Time) {
    86  	if t.IsZero() {
    87  		in.Status.Scheduler.NextRecover = nil
    88  		return
    89  	}
    90  
    91  	if in.Status.Scheduler.NextRecover == nil {
    92  		in.Status.Scheduler.NextRecover = &metav1.Time{}
    93  	}
    94  	in.Status.Scheduler.NextRecover.Time = t
    95  }
    96  
    97  // GetScheduler would return the scheduler for chaos
    98  func (in *{{.Type}}) GetScheduler() *SchedulerSpec {
    99  	return in.Spec.Scheduler
   100  }
   101  
   102  // GetChaos would return the a record for chaos
   103  func (in *{{.Type}}) GetChaos() *ChaosInstance {
   104  	instance := &ChaosInstance{
   105  		Name:      in.Name,
   106  		Namespace: in.Namespace,
   107  		Kind:      Kind{{.Type}},
   108  		StartTime: in.CreationTimestamp.Time,
   109  		Action:    "",
   110  		Status:    string(in.Status.Experiment.Phase),
   111  		UID:       string(in.UID),
   112  	}
   113  
   114  	action := reflect.ValueOf(in).Elem().FieldByName("Spec").FieldByName("Action")
   115  	if action.IsValid() {
   116  		instance.Action = action.String()
   117  	}
   118  	if in.Spec.Duration != nil {
   119  		instance.Duration = *in.Spec.Duration
   120  	}
   121  	if in.DeletionTimestamp != nil {
   122  		instance.EndTime = in.DeletionTimestamp.Time
   123  	}
   124  	return instance
   125  }
   126  
   127  // GetStatus returns the status
   128  func (in *{{.Type}}) GetStatus() *ChaosStatus {
   129  	return &in.Status.ChaosStatus
   130  }
   131  
   132  // GetSpecAndMetaString returns a string including the meta and spec field of this chaos object.
   133  func (in *{{.Type}}) GetSpecAndMetaString() (string, error) {
   134  	spec, err := json.Marshal(in.Spec)
   135  	if err != nil {
   136  		return "", err
   137  	}
   138  
   139  	meta := in.ObjectMeta.DeepCopy()
   140  	meta.SetResourceVersion("")
   141  	meta.SetGeneration(0)
   142  
   143  	return string(spec) + meta.String(), nil
   144  }
   145  
   146  // +kubebuilder:object:root=true
   147  
   148  // {{.Type}}List contains a list of {{.Type}}
   149  type {{.Type}}List struct {
   150  	metav1.TypeMeta ` + "`" + `json:",inline"` + "`" + `
   151  	metav1.ListMeta ` + "`" + `json:"metadata,omitempty"` + "`" + `
   152  	Items           []{{.Type}} ` + "`" + `json:"items"` + "`" + `
   153  }
   154  
   155  // ListChaos returns a list of chaos
   156  func (in *{{.Type}}List) ListChaos() []*ChaosInstance {
   157  	res := make([]*ChaosInstance, 0, len(in.Items))
   158  	for _, item := range in.Items {
   159  		res = append(res, item.GetChaos())
   160  	}
   161  	return res
   162  }
   163  `
   164  
   165  func generateImpl(name string) string {
   166  	tmpl, err := template.New("impl").Parse(implTemplate)
   167  	if err != nil {
   168  		log.Error(err, "fail to build template")
   169  		return ""
   170  	}
   171  
   172  	buf := new(bytes.Buffer)
   173  	err = tmpl.Execute(buf, &metadata{
   174  		Type: name,
   175  	})
   176  	if err != nil {
   177  		log.Error(err, "fail to execute template")
   178  		return ""
   179  	}
   180  
   181  	return buf.String()
   182  }
   183