istio.io/istio@v0.0.0-20240520182934-d79c90f27776/operator/pkg/validate/validate_test.go (about)

     1  // Copyright Istio 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  package validate
    16  
    17  import (
    18  	"testing"
    19  
    20  	"istio.io/api/operator/v1alpha1"
    21  	"istio.io/istio/operator/pkg/util"
    22  )
    23  
    24  func TestValidate(t *testing.T) {
    25  	tests := []struct {
    26  		desc     string
    27  		yamlStr  string
    28  		wantErrs util.Errors
    29  	}{
    30  		{
    31  			desc: "nil success",
    32  		},
    33  		{
    34  			desc: "complicated k8s overlay",
    35  			yamlStr: `
    36  profile: default
    37  components:
    38    ingressGateways:
    39    - enabled: true
    40      k8s:
    41        affinity:
    42          nodeAffinity:
    43            requiredDuringSchedulingIgnoredDuringExecution:
    44              nodeSelectorTerms:
    45              - matchExpressions:
    46                - key: zone
    47                  operator: In
    48                  values:
    49                  - istio`,
    50  		},
    51  		{
    52  			desc: "CommonConfig",
    53  			yamlStr: `
    54  hub: docker.io/istio
    55  tag: v1.2.3
    56  meshConfig:
    57    rootNamespace: istio-system
    58  values:
    59    global:
    60      proxy:
    61        includeIPRanges: "1.1.0.0/16,2.2.0.0/16"
    62        excludeIPRanges: "3.3.0.0/16,4.4.0.0/16"
    63  
    64  `,
    65  		},
    66  		{
    67  			desc: "BadTag",
    68  			yamlStr: `
    69  hub: ?illegal-tag!
    70  `,
    71  			wantErrs: makeErrors([]string{`invalid value Hub: ?illegal-tag!`}),
    72  		},
    73  		{
    74  			desc: "BadHub",
    75  			yamlStr: `
    76  hub: docker.io:tag/istio
    77  `,
    78  			wantErrs: makeErrors([]string{`invalid value Hub: docker.io:tag/istio`}),
    79  		},
    80  		{
    81  			desc: "GoodURL",
    82  			yamlStr: `
    83  installPackagePath: /local/file/path
    84  `,
    85  		},
    86  		{
    87  			desc: "BadGatewayName",
    88  			yamlStr: `
    89  components:
    90    ingressGateways:
    91    - namespace: istio-ingress-ns2
    92      name: istio@ingress-1
    93      enabled: true
    94  `,
    95  			wantErrs: makeErrors([]string{`invalid value Components.IngressGateways: istio@ingress-1`}),
    96  		},
    97  		{
    98  			desc: "BadValuesIP",
    99  			yamlStr: `
   100  values:
   101    global:
   102      proxy:
   103        includeIPRanges: "1.1.0.300/16,2.2.0.0/16"
   104  `,
   105  			wantErrs: makeErrors([]string{`global.proxy.includeIPRanges netip.ParsePrefix("1.1.0.300/16"): ParseAddr("1.1.0.300"): IPv4 field has value >255`}),
   106  		},
   107  		{
   108  			desc: "EmptyValuesIP",
   109  			yamlStr: `
   110  values:
   111    global:
   112      proxy:
   113        includeIPRanges: ""
   114  `,
   115  		},
   116  		{
   117  			desc: "Bad mesh config",
   118  			yamlStr: `
   119  meshConfig:
   120    defaultConfig:
   121      discoveryAddress: missingport
   122  `,
   123  			wantErrs: makeErrors([]string{`1 error occurred:
   124  	* invalid discovery address: unable to split "missingport": address missingport: missing port in address
   125  
   126  `}),
   127  		},
   128  		{
   129  			desc: "Bad mesh config values",
   130  			yamlStr: `
   131  values:
   132    meshConfig:
   133      defaultConfig:
   134        discoveryAddress: missingport
   135  `,
   136  			wantErrs: makeErrors([]string{`1 error occurred:
   137  	* invalid discovery address: unable to split "missingport": address missingport: missing port in address
   138  
   139  `}),
   140  		},
   141  		{
   142  			desc: "Unknown mesh config",
   143  			yamlStr: `
   144  meshConfig:
   145    foo: bar
   146  `,
   147  			wantErrs: makeErrors([]string{`failed to unmarshall mesh config: unknown field "foo" in istio.mesh.v1alpha1.MeshConfig`}),
   148  		},
   149  		{
   150  			desc: "Unknown mesh config values",
   151  			yamlStr: `
   152  values:
   153    meshConfig:
   154      foo: bar
   155  `,
   156  			wantErrs: makeErrors([]string{`failed to unmarshall mesh config: unknown field "foo" in istio.mesh.v1alpha1.MeshConfig`}),
   157  		},
   158  		{
   159  			desc: "Good mesh config",
   160  			yamlStr: `
   161  meshConfig:
   162    defaultConfig:
   163      discoveryAddress: istiod:15012
   164  `,
   165  		},
   166  		{
   167  			desc: "BadValuesIP with Space start",
   168  			yamlStr: `
   169  values:
   170    global:
   171      proxy:
   172        includeIPRanges: "1.1.0.0/16, 2.2.0.0/16"
   173  `,
   174  			wantErrs: makeErrors([]string{`global.proxy.includeIPRanges netip.ParsePrefix(" 2.2.0.0/16"): ParseAddr(" 2.2.0.0"): unexpected character (at " 2.2.0.0")`}),
   175  		},
   176  		{
   177  			desc: "BadValuesIP with Space end",
   178  			yamlStr: `
   179  values:
   180    global:
   181      proxy:
   182        includeIPRanges: "1.1.0.0/16 ,2.2.0.0/16"
   183  `,
   184  			wantErrs: makeErrors([]string{`global.proxy.includeIPRanges netip.ParsePrefix("1.1.0.0/16 "): bad bits after slash: "16 "`}),
   185  		},
   186  	}
   187  
   188  	for _, tt := range tests {
   189  		t.Run(tt.desc, func(t *testing.T) {
   190  			ispec := &v1alpha1.IstioOperatorSpec{}
   191  			err := util.UnmarshalWithJSONPB(tt.yamlStr, ispec, false)
   192  			if err != nil {
   193  				t.Fatalf("unmarshalWithJSONPB(%s): got error %s", tt.desc, err)
   194  			}
   195  
   196  			errs := CheckIstioOperatorSpec(ispec, false)
   197  			if gotErrs, wantErrs := errs, tt.wantErrs; !util.EqualErrors(gotErrs, wantErrs) {
   198  				t.Errorf("ProtoToValues(%s)(%v): gotErrs:%s, wantErrs:%s", tt.desc, tt.yamlStr, gotErrs, wantErrs)
   199  			}
   200  		})
   201  	}
   202  }