...

Source file src/github.com/datawire/ambassador/v2/pkg/api/getambassador.io/v3alpha1/common.go

Documentation: github.com/datawire/ambassador/v2/pkg/api/getambassador.io/v3alpha1

     1  // -*- fill-column: 75 -*-
     2  
     3  // Copyright 2020 Datawire.  All rights reserved
     4  //
     5  // Licensed under the Apache License, Version 2.0 (the "License"); you may
     6  // not use this file except in compliance with the License.  You may obtain
     7  // a copy of the License at
     8  //
     9  //     http://www.apache.org/licenses/LICENSE-2.0
    10  //
    11  // Unless required by applicable law or agreed to in writing, software
    12  // distributed under the License is distributed on an "AS IS" BASIS,
    13  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14  // See the License for the specific language governing permissions and
    15  // limitations under the License.
    16  
    17  // This file deals with common things that are shared between multiple
    18  // CRDs, but are ultimately used by individual CRDs (rather than by the
    19  // apiVersion as a whole).
    20  
    21  package v3alpha1
    22  
    23  import (
    24  	"encoding/json"
    25  	"time"
    26  )
    27  
    28  // V2ExplicitTLS controls some vanity/stylistic elements when converting
    29  // from v3alpha1 to v2.  The values in an V2ExplicitTLS should not in any
    30  // way affect the runtime operation of Emissary; except that it may affect
    31  // internal names in the Envoy config, which may in turn affect stats
    32  // names.  But it should not affect any end-user observable behavior.
    33  type V2ExplicitTLS struct {
    34  	// TLS controls whether and how to represent the "tls" field when
    35  	// its value could be implied by the "service" field.  In v2, there
    36  	// were a lot of different ways to spell an "empty" value, and this
    37  	// field specifies which way to spell it (and will therefore only
    38  	// be used if the value will indeed be empty).
    39  	//
    40  	//  | Value        | Representation                        | Meaning of representation          |
    41  	//  |--------------+---------------------------------------+------------------------------------|
    42  	//  | ""           | omit the field                        | defer to service (no TLSContext)   |
    43  	//  | "null"       | store an explicit "null" in the field | defer to service (no TLSContext)   |
    44  	//  | "string"     | store an empty string in the field    | defer to service (no TLSContext)   |
    45  	//  | "bool:false" | store a Boolean "false" in the field  | defer to service (no TLSContext)   |
    46  	//  | "bool:true"  | store a Boolean "true" in the field   | originate TLS (no TLSContext)      |
    47  	//
    48  	// If the meaning of the representation contradicts anything else
    49  	// (if a TLSContext is to be used, or in the case of "bool:true" if
    50  	// TLS is not to be originated), then this field is ignored.
    51  	//
    52  	// +kubebuilder:validation:Enum={"","null","bool:true","bool:false","string"}
    53  	TLS string `json:"tls,omitempty"`
    54  
    55  	// ServiceScheme specifies how to spell and capitalize the scheme-part of the
    56  	// service URL.
    57  	//
    58  	// Acceptable values are "http://" (case-insensitive), "https://"
    59  	// (case-insensitive), or "".  The value is used if it agrees with
    60  	// whether or not this resource enables TLS origination, or if
    61  	// something else in the resource overrides the scheme.
    62  	//
    63  	// +kubebuilder:validation:Pattern="^([hH][tT][tT][pP][sS]?://)?$"
    64  	ServiceScheme *string `json:"serviceScheme,omitempty"`
    65  }
    66  
    67  type CircuitBreaker struct {
    68  	// +kubebuilder:validation:Enum={"default", "high"}
    69  	Priority           string `json:"priority,omitempty"`
    70  	MaxConnections     *int   `json:"max_connections,omitempty"`
    71  	MaxPendingRequests *int   `json:"max_pending_requests,omitempty"`
    72  	MaxRequests        *int   `json:"max_requests,omitempty"`
    73  	MaxRetries         *int   `json:"max_retries,omitempty"`
    74  }
    75  
    76  // ErrorResponseTextFormatSource specifies a source for an error response body
    77  type ErrorResponseTextFormatSource struct {
    78  	// The name of a file on the Ambassador pod that contains a format text string.
    79  	Filename string `json:"filename"`
    80  }
    81  
    82  // ErorrResponseOverrideBody specifies the body of an error response
    83  type ErrorResponseOverrideBody struct {
    84  	// A format string representing a text response body.
    85  	// Content-Type can be set using the `content_type` field below.
    86  	ErrorResponseTextFormat *string `json:"text_format,omitempty"`
    87  
    88  	// A JSON response with content-type: application/json. The values can
    89  	// contain format text like in text_format.
    90  	ErrorResponseJsonFormat *map[string]string `json:"json_format,omitempty"`
    91  
    92  	// A format string sourced from a file on the Ambassador container.
    93  	// Useful for larger response bodies that should not be placed inline
    94  	// in configuration.
    95  	ErrorResponseTextFormatSource *ErrorResponseTextFormatSource `json:"text_format_source,omitempty"`
    96  
    97  	// The content type to set on the error response body when
    98  	// using text_format or text_format_source. Defaults to 'text/plain'.
    99  	ContentType string `json:"content_type,omitempty"`
   100  }
   101  
   102  // A response rewrite for an HTTP error response
   103  type ErrorResponseOverride struct {
   104  	// The status code to match on -- not a pointer because it's required.
   105  	// +kubebuilder:validation:Required
   106  	// +kubebuilder:validation:Minimum=400
   107  	// +kubebuilder:validation:Maximum=599
   108  	OnStatusCode int `json:"on_status_code,omitempty"`
   109  
   110  	// The new response body
   111  	// +kubebuilder:validation:Required
   112  	Body ErrorResponseOverrideBody `json:"body,omitempty"`
   113  }
   114  
   115  // AmbassadorID declares which Ambassador instances should pay
   116  // attention to this resource. If no value is provided, the default is:
   117  //
   118  //	ambassador_id:
   119  //	- "default"
   120  //
   121  // TODO(lukeshu): In v3alpha2, consider renaming all of the `ambassador_id` (singular) fields to
   122  // `ambassador_ids` (plural).
   123  type AmbassadorID []string
   124  
   125  func (aid AmbassadorID) Matches(envVar string) bool {
   126  	if len(aid) == 0 {
   127  		aid = []string{"default"}
   128  	}
   129  	for _, item := range aid {
   130  		if item == envVar {
   131  			return true
   132  		}
   133  	}
   134  	return false
   135  }
   136  
   137  // TODO(lukeshu): In v3alpha2, change all of the `{foo}_ms`/`MillisecondDuration` fields to
   138  // `{foo}`/`metav1.Duration`.
   139  //
   140  // +kubebuilder:validation:Type="integer"
   141  type MillisecondDuration struct {
   142  	time.Duration `json:"-"`
   143  }
   144  
   145  func (d *MillisecondDuration) UnmarshalJSON(data []byte) error {
   146  	if string(data) == "null" {
   147  		d.Duration = 0
   148  		return nil
   149  	}
   150  
   151  	var intval int64
   152  	if err := json.Unmarshal(data, &intval); err != nil {
   153  		return err
   154  	}
   155  	d.Duration = time.Duration(intval) * time.Millisecond
   156  	return nil
   157  }
   158  
   159  func (d MillisecondDuration) MarshalJSON() ([]byte, error) {
   160  	return json.Marshal(d.Milliseconds())
   161  }
   162  
   163  // TODO(lukeshu): In v3alpha2, change all of the `{foo}s`/`SecondDuration` fields to
   164  // `{foo}`/`metav1.Duration`.
   165  //
   166  // +kubebuilder:validation:Type="integer"
   167  type SecondDuration struct {
   168  	time.Duration `json:"-"`
   169  }
   170  
   171  func (d *SecondDuration) UnmarshalJSON(data []byte) error {
   172  	if string(data) == "null" {
   173  		d.Duration = 0
   174  		return nil
   175  	}
   176  
   177  	var intval int64
   178  	if err := json.Unmarshal(data, &intval); err != nil {
   179  		return err
   180  	}
   181  	d.Duration = time.Duration(intval) * time.Second
   182  	return nil
   183  }
   184  
   185  func (d SecondDuration) MarshalJSON() ([]byte, error) {
   186  	return json.Marshal(int64(d.Seconds()))
   187  }
   188  
   189  // UntypedDict is relatively opaque as a Go type, but it preserves its
   190  // contents in a roundtrippable way.
   191  //
   192  // +kubebuilder:validation:Type="object"
   193  // +kubebuilder:pruning:PreserveUnknownFields
   194  type UntypedDict struct {
   195  	// We have to hide this from controller-gen inside of a struct
   196  	// (instead of just `type UntypedDict map[string]json.RawMessage`)
   197  	// so that controller-gen doesn't generate an `items` field in the
   198  	// schema.
   199  	Values map[string]json.RawMessage `json:"-"`
   200  }
   201  
   202  func (u UntypedDict) MarshalJSON() ([]byte, error) {
   203  	return json.Marshal(u.Values)
   204  }
   205  
   206  func (u *UntypedDict) UnmarshalJSON(data []byte) error {
   207  	return json.Unmarshal(data, &u.Values)
   208  }
   209  

View as plain text