istio.io/istio@v0.0.0-20240520182934-d79c90f27776/pkg/test/framework/components/authz/kubelocal.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 authz
    16  
    17  import (
    18  	"errors"
    19  	"fmt"
    20  	"time"
    21  
    22  	"istio.io/istio/pkg/config/protocol"
    23  	"istio.io/istio/pkg/test/framework/components/echo"
    24  	"istio.io/istio/pkg/test/framework/components/namespace"
    25  	"istio.io/istio/pkg/test/framework/resource"
    26  	"istio.io/istio/pkg/test/framework/resource/config/apply"
    27  	"istio.io/istio/pkg/test/scopes"
    28  	"istio.io/istio/pkg/test/util/tmpl"
    29  )
    30  
    31  const (
    32  	localProviderTemplate = `
    33  extensionProviders:
    34  - name: "{{ .httpName }}"
    35    envoyExtAuthzHttp:
    36      service: "{{ .httpHost }}"
    37      port: {{ .httpPort }}
    38      headersToUpstreamOnAllow: ["x-ext-authz-*"]
    39      headersToDownstreamOnDeny: ["x-ext-authz-*"]
    40      includeRequestHeadersInCheck: ["x-ext-authz"]
    41      includeAdditionalHeadersInCheck:
    42        x-ext-authz-additional-header-new: additional-header-new-value
    43        x-ext-authz-additional-header-override: additional-header-override-value
    44  - name: "{{ .grpcName }}"
    45    envoyExtAuthzGrpc:
    46      service: "{{ .grpcHost }}"
    47      port: {{ .grpcPort }}`
    48  
    49  	localServiceEntryTemplate = `
    50  apiVersion: networking.istio.io/v1beta1
    51  kind: ServiceEntry
    52  metadata:
    53    name: {{ .httpName }}
    54  spec:
    55    hosts:
    56    - "{{ .httpHost }}"
    57    endpoints:
    58    - address: "127.0.0.1"
    59    ports:
    60    - name: http
    61      number: {{ .httpPort }}
    62      protocol: HTTP
    63    resolution: STATIC
    64  ---
    65  apiVersion: networking.istio.io/v1beta1
    66  kind: ServiceEntry
    67  metadata:
    68    name: {{ .grpcName }}
    69  spec:
    70    hosts:
    71    - "{{ .grpcHost }}"
    72    endpoints:
    73    - address: "127.0.0.1"
    74    ports:
    75    - name: grpc
    76      number: {{ .grpcPort }}
    77      protocol: GRPC
    78    resolution: STATIC
    79  ---`
    80  )
    81  
    82  func newLocalKubeServer(ctx resource.Context, ns namespace.Instance) (server *localServerImpl, err error) {
    83  	if ns == nil {
    84  		return nil, errors.New("namespace required for local authz server")
    85  	}
    86  
    87  	start := time.Now()
    88  	scopes.Framework.Infof("=== BEGIN: Deploy local authz server (ns=%s) ===", ns.Name())
    89  	defer func() {
    90  		if err != nil {
    91  			scopes.Framework.Errorf("=== FAILED: Deploy local authz server (ns=%s) ===", ns.Name())
    92  			scopes.Framework.Error(err)
    93  		} else {
    94  			scopes.Framework.Infof("=== SUCCEEDED: Deploy local authz server (ns=%s) in %v ===",
    95  				ns.Name(), time.Since(start))
    96  		}
    97  	}()
    98  
    99  	server = &localServerImpl{
   100  		ns: ns,
   101  	}
   102  
   103  	// Create the providers.
   104  	server.providers = []Provider{
   105  		&providerImpl{
   106  			name: server.httpName(),
   107  			api:  HTTP,
   108  			protocolSupported: func(p protocol.Instance) bool {
   109  				// HTTP protocol doesn't support raw TCP requests.
   110  				return !p.IsTCP()
   111  			},
   112  			targetSupported: func(to echo.Target) bool {
   113  				return to.Config().IncludeExtAuthz
   114  			},
   115  			check: checkHTTP,
   116  		},
   117  		&providerImpl{
   118  			name: server.grpcName(),
   119  			api:  GRPC,
   120  			protocolSupported: func(protocol.Instance) bool {
   121  				return true
   122  			},
   123  			targetSupported: func(to echo.Target) bool {
   124  				return to.Config().IncludeExtAuthz
   125  			},
   126  			check: checkGRPC,
   127  		},
   128  	}
   129  	server.id = ctx.TrackResource(server)
   130  
   131  	// Install the providers in MeshConfig.
   132  	if err = server.installProviders(ctx); err != nil {
   133  		return
   134  	}
   135  
   136  	// Install a ServiceEntry for each provider to configure routing to the local provider host.
   137  	err = server.installServiceEntries(ctx)
   138  	return
   139  }
   140  
   141  type localServerImpl struct {
   142  	id        resource.ID
   143  	ns        namespace.Instance
   144  	providers []Provider
   145  }
   146  
   147  func (s *localServerImpl) ID() resource.ID {
   148  	return s.id
   149  }
   150  
   151  func (s *localServerImpl) Namespace() namespace.Instance {
   152  	return s.ns
   153  }
   154  
   155  func (s *localServerImpl) Providers() []Provider {
   156  	return append([]Provider{}, s.providers...)
   157  }
   158  
   159  func (s *localServerImpl) httpName() string {
   160  	return fmt.Sprintf("%s-%s-local", httpName, s.ns.Prefix())
   161  }
   162  
   163  func (s *localServerImpl) grpcName() string {
   164  	return fmt.Sprintf("%s-%s-local", grpcName, s.ns.Prefix())
   165  }
   166  
   167  func (s *localServerImpl) httpHost() string {
   168  	return fmt.Sprintf("%s.%s.local", httpName, s.ns.Prefix())
   169  }
   170  
   171  func (s *localServerImpl) grpcHost() string {
   172  	return fmt.Sprintf("%s.%s.local", grpcName, s.ns.Prefix())
   173  }
   174  
   175  func (s *localServerImpl) templateArgs() map[string]any {
   176  	return map[string]any{
   177  		"httpName": s.httpName(),
   178  		"grpcName": s.grpcName(),
   179  		"httpHost": s.httpHost(),
   180  		"grpcHost": s.grpcHost(),
   181  		"httpPort": httpPort,
   182  		"grpcPort": grpcPort,
   183  	}
   184  }
   185  
   186  func (s *localServerImpl) installProviders(ctx resource.Context) error {
   187  	// Update the mesh config extension provider for the ext-authz service.
   188  	providerYAML, err := tmpl.Evaluate(localProviderTemplate, s.templateArgs())
   189  	if err != nil {
   190  		return err
   191  	}
   192  
   193  	return installProviders(ctx, providerYAML)
   194  }
   195  
   196  func (s *localServerImpl) installServiceEntries(ctx resource.Context) error {
   197  	return ctx.ConfigIstio().
   198  		Eval(s.ns.Name(), s.templateArgs(), localServiceEntryTemplate).
   199  		Apply(apply.CleanupConditionally)
   200  }