...

Source file src/github.com/chaos-mesh/chaos-mesh/api/v1alpha1/statuscheck_types.go

Documentation: github.com/chaos-mesh/chaos-mesh/api/v1alpha1

     1  // Copyright 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 v1alpha1
    17  
    18  import (
    19  	"net/http"
    20  	"time"
    21  
    22  	"github.com/pkg/errors"
    23  	corev1 "k8s.io/api/core/v1"
    24  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    25  )
    26  
    27  // +kubebuilder:object:root=true
    28  // +kubebuilder:subresource:status
    29  // +chaos-mesh:base
    30  type StatusCheck struct {
    31  	metav1.TypeMeta   `json:",inline"`
    32  	metav1.ObjectMeta `json:"metadata,omitempty"`
    33  
    34  	// Spec defines the behavior of a status check
    35  	Spec StatusCheckSpec `json:"spec"`
    36  
    37  	// +optional
    38  	// Most recently observed status of status check
    39  	Status StatusCheckStatus `json:"status,omitempty"`
    40  }
    41  
    42  type StatusCheckMode string
    43  
    44  const (
    45  	// StatusCheckSynchronous means the status check will exit
    46  	// immediately after success or failure.
    47  	StatusCheckSynchronous StatusCheckMode = "Synchronous"
    48  	// StatusCheckContinuous means the status check will continue to
    49  	// execute until the duration is exceeded or the status check fails.
    50  	StatusCheckContinuous StatusCheckMode = "Continuous"
    51  )
    52  
    53  type StatusCheckType string
    54  
    55  const (
    56  	TypeHTTP StatusCheckType = "HTTP"
    57  )
    58  
    59  type StatusCheckSpec struct {
    60  	// Mode defines the execution mode of the status check.
    61  	// Support type: Synchronous / Continuous
    62  	// +optional
    63  	// +kubebuilder:validation:Enum=Synchronous;Continuous
    64  	Mode StatusCheckMode `json:"mode,omitempty"`
    65  
    66  	// Type defines the specific status check type.
    67  	// Support type: HTTP
    68  	// +kubebuilder:default=HTTP
    69  	// +kubebuilder:validation:Enum=HTTP
    70  	Type StatusCheckType `json:"type"`
    71  
    72  	// Duration defines the duration of the whole status check if the
    73  	// number of failed execution does not exceed the failure threshold.
    74  	// Duration is available to both `Synchronous` and `Continuous` mode.
    75  	// A duration string is a possibly signed sequence of
    76  	// decimal numbers, each with optional fraction and a unit suffix,
    77  	// such as "300ms", "-1.5h" or "2h45m".
    78  	// Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
    79  	// +optional
    80  	Duration *string `json:"duration,omitempty" webhook:"Duration"`
    81  
    82  	// TimeoutSeconds defines the number of seconds after which
    83  	// an execution of status check times out.
    84  	// +optional
    85  	// +kubebuilder:default=1
    86  	// +kubebuilder:validation:Minimum=1
    87  	TimeoutSeconds int `json:"timeoutSeconds,omitempty"`
    88  
    89  	// IntervalSeconds defines how often (in seconds) to perform
    90  	// an execution of status check.
    91  	// +optional
    92  	// +kubebuilder:default=10
    93  	// +kubebuilder:validation:Minimum=1
    94  	IntervalSeconds int `json:"intervalSeconds,omitempty"`
    95  
    96  	// FailureThreshold defines the minimum consecutive failure
    97  	// for the status check to be considered failed.
    98  	// +optional
    99  	// +kubebuilder:default=3
   100  	// +kubebuilder:validation:Minimum=1
   101  	FailureThreshold int `json:"failureThreshold,omitempty"`
   102  
   103  	// SuccessThreshold defines the minimum consecutive successes
   104  	// for the status check to be considered successful.
   105  	// SuccessThreshold only works for `Synchronous` mode.
   106  	// +optional
   107  	// +kubebuilder:default=1
   108  	// +kubebuilder:validation:Minimum=1
   109  	SuccessThreshold int `json:"successThreshold,omitempty"`
   110  
   111  	// RecordsHistoryLimit defines the number of record to retain.
   112  	// +optional
   113  	// +kubebuilder:default=100
   114  	// +kubebuilder:validation:Minimum=1
   115  	// +kubebuilder:validation:Maximum=1000
   116  	RecordsHistoryLimit int `json:"recordsHistoryLimit,omitempty"`
   117  
   118  	// +optional
   119  	*EmbedStatusCheck `json:",inline,omitempty"`
   120  }
   121  
   122  type StatusCheckStatus struct {
   123  	// StartTime represents time when the status check started to execute.
   124  	// +optional
   125  	StartTime *metav1.Time `json:"startTime,omitempty"`
   126  
   127  	// CompletionTime represents time when the status check was completed.
   128  	// +optional
   129  	CompletionTime *metav1.Time `json:"completionTime,omitempty"`
   130  
   131  	// Count represents the total number of the status check executed.
   132  	// +optional
   133  	Count int64 `json:"count,omitempty"`
   134  
   135  	// Conditions represents the latest available observations of a StatusCheck's current state.
   136  	// +optional
   137  	// +patchMergeKey=type
   138  	// +patchStrategy=merge
   139  	Conditions []StatusCheckCondition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
   140  
   141  	// Records contains the history of the execution of StatusCheck.
   142  	// +optional
   143  	Records []StatusCheckRecord `json:"records,omitempty"`
   144  }
   145  
   146  type StatusCheckOutcome string
   147  
   148  const (
   149  	StatusCheckOutcomeSuccess StatusCheckOutcome = "Success"
   150  	StatusCheckOutcomeFailure StatusCheckOutcome = "Failure"
   151  )
   152  
   153  type StatusCheckRecord struct {
   154  	StartTime *metav1.Time       `json:"startTime"`
   155  	Outcome   StatusCheckOutcome `json:"outcome"`
   156  }
   157  
   158  type StatusCheckConditionType string
   159  
   160  const (
   161  	// StatusCheckConditionCompleted means the status check is completed.
   162  	// It will be `True`, in the following scenarios:
   163  	// 1. the duration is exceeded
   164  	// 2. the failure threshold is exceeded
   165  	// 3. the success threshold is exceeded (only the `Synchronous` mode)
   166  	StatusCheckConditionCompleted StatusCheckConditionType = "Completed"
   167  	// StatusCheckConditionDurationExceed means the duration is exceeded.
   168  	StatusCheckConditionDurationExceed StatusCheckConditionType = "DurationExceed"
   169  	// StatusCheckConditionFailureThresholdExceed means the failure threshold is exceeded.
   170  	StatusCheckConditionFailureThresholdExceed StatusCheckConditionType = "FailureThresholdExceed"
   171  	// StatusCheckConditionSuccessThresholdExceed means the success threshold is exceeded.
   172  	StatusCheckConditionSuccessThresholdExceed StatusCheckConditionType = "SuccessThresholdExceed"
   173  )
   174  
   175  type StatusCheckReason string
   176  
   177  const (
   178  	StatusCheckDurationExceed         StatusCheckReason = "StatusCheckDurationExceed"
   179  	StatusCheckFailureThresholdExceed StatusCheckReason = "StatusCheckFailureThresholdExceed"
   180  	StatusCheckSuccessThresholdExceed StatusCheckReason = "StatusCheckSuccessThresholdExceed"
   181  	StatusCheckExecutionFailed        StatusCheckReason = "StatusCheckExecutionFailed"
   182  	StatusCheckExecutionSucceed       StatusCheckReason = "StatusCheckExecutionSucceed"
   183  )
   184  
   185  type StatusCheckCondition struct {
   186  	Type               StatusCheckConditionType `json:"type"`
   187  	Status             corev1.ConditionStatus   `json:"status"`
   188  	Reason             StatusCheckReason        `json:"reason"`
   189  	LastProbeTime      *metav1.Time             `json:"lastProbeTime"`
   190  	LastTransitionTime *metav1.Time             `json:"lastTransitionTime"`
   191  }
   192  
   193  type EmbedStatusCheck struct {
   194  	// +optional
   195  	HTTPStatusCheck *HTTPStatusCheck `json:"http,omitempty"`
   196  }
   197  
   198  type HTTPCriteria struct {
   199  	// StatusCode defines the expected http status code for the request.
   200  	// A statusCode string could be a single code (e.g. 200), or
   201  	// an inclusive range (e.g. 200-400, both `200` and `400` are included).
   202  	StatusCode string `json:"statusCode" webhook:"StatusCode"`
   203  	// TODO: support response body
   204  }
   205  
   206  type HTTPRequestMethod string
   207  
   208  const (
   209  	MethodGet  = "GET"
   210  	MethodPost = "POST"
   211  )
   212  
   213  type HTTPStatusCheck struct {
   214  	RequestUrl string `json:"url"`
   215  
   216  	// +optional
   217  	// +kubebuilder:validation:Enum=GET;POST
   218  	// +kubebuilder:default=GET
   219  	RequestMethod HTTPRequestMethod `json:"method,omitempty"`
   220  	// +optional
   221  	RequestHeaders http.Header `json:"headers,omitempty"`
   222  	// +optional
   223  	RequestBody string `json:"body,omitempty"`
   224  	// Criteria defines how to determine the result of the status check.
   225  	Criteria HTTPCriteria `json:"criteria"`
   226  }
   227  
   228  // StatusCheckList contains a list of StatusCheck
   229  // +kubebuilder:object:root=true
   230  type StatusCheckList struct {
   231  	metav1.TypeMeta `json:",inline"`
   232  	metav1.ListMeta `json:"metadata,omitempty"`
   233  	Items           []StatusCheck `json:"items"`
   234  }
   235  
   236  func (in *StatusCheckSpec) GetDuration() (*time.Duration, error) {
   237  	if in.Duration == nil {
   238  		return nil, nil
   239  	}
   240  	duration, err := time.ParseDuration(*in.Duration)
   241  	if err != nil {
   242  		return nil, errors.Wrapf(err, "parse duration %s", *in.Duration)
   243  	}
   244  	return &duration, nil
   245  }
   246  
   247  func (in *StatusCheck) DurationExceed(now time.Time) (bool, time.Duration, error) {
   248  	if in.Status.StartTime == nil {
   249  		return false, 0, nil
   250  	}
   251  	duration, err := in.Spec.GetDuration()
   252  	if err != nil {
   253  		return false, 0, errors.Wrap(err, "get duration")
   254  	}
   255  
   256  	if duration != nil {
   257  		stopTime := in.Status.StartTime.Add(*duration)
   258  		if stopTime.Before(now) {
   259  			return true, 0, nil
   260  		}
   261  
   262  		return false, stopTime.Sub(now), nil
   263  	}
   264  
   265  	return false, 0, nil
   266  }
   267  
   268  // IsCompleted checks if the status check is completed, according to the StatusCheckConditionCompleted condition.
   269  func (in *StatusCheck) IsCompleted() bool {
   270  	for _, condition := range in.Status.Conditions {
   271  		if condition.Type == StatusCheckConditionCompleted &&
   272  			condition.Status == corev1.ConditionTrue {
   273  			return true
   274  		}
   275  	}
   276  	return false
   277  }
   278