...

Source file src/github.com/datawire/ambassador/v2/pkg/envoy-control-plane/cache/v3/snapshot.go

Documentation: github.com/datawire/ambassador/v2/pkg/envoy-control-plane/cache/v3

     1  // Code generated by create_version. DO NOT EDIT.
     2  // Copyright 2018 Envoyproxy Authors
     3  //
     4  //   Licensed under the Apache License, Version 2.0 (the "License");
     5  //   you may not use this file except in compliance with the License.
     6  //   You may obtain a copy of the License at
     7  //
     8  //       http://www.apache.org/licenses/LICENSE-2.0
     9  //
    10  //   Unless required by applicable law or agreed to in writing, software
    11  //   distributed under the License is distributed on an "AS IS" BASIS,
    12  //   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  //   See the License for the specific language governing permissions and
    14  //   limitations under the License.
    15  
    16  package cache
    17  
    18  import (
    19  	"errors"
    20  	"fmt"
    21  	"time"
    22  
    23  	"github.com/datawire/ambassador/v2/pkg/envoy-control-plane/cache/types"
    24  )
    25  
    26  // Resources is a versioned group of resources.
    27  type Resources struct {
    28  	// Version information.
    29  	Version string
    30  
    31  	// Items in the group indexed by name.
    32  	Items map[string]types.ResourceWithTtl
    33  }
    34  
    35  // IndexResourcesByName creates a map from the resource name to the resource.
    36  func IndexResourcesByName(items []types.ResourceWithTtl) map[string]types.ResourceWithTtl {
    37  	indexed := make(map[string]types.ResourceWithTtl)
    38  	for _, item := range items {
    39  		indexed[GetResourceName(item.Resource)] = item
    40  	}
    41  	return indexed
    42  }
    43  
    44  // NewResources creates a new resource group.
    45  func NewResources(version string, items []types.Resource) Resources {
    46  	itemsWithTtl := []types.ResourceWithTtl{}
    47  	for _, item := range items {
    48  		itemsWithTtl = append(itemsWithTtl, types.ResourceWithTtl{Resource: item})
    49  	}
    50  	return NewResourcesWithTtl(version, itemsWithTtl)
    51  }
    52  
    53  // NewResources creates a new resource group.
    54  func NewResourcesWithTtl(version string, items []types.ResourceWithTtl) Resources {
    55  	return Resources{
    56  		Version: version,
    57  		Items:   IndexResourcesByName(items),
    58  	}
    59  }
    60  
    61  // Snapshot is an internally consistent snapshot of xDS resources.
    62  // Consistency is important for the convergence as different resource types
    63  // from the snapshot may be delivered to the proxy in arbitrary order.
    64  type Snapshot struct {
    65  	Resources [types.UnknownType]Resources
    66  }
    67  
    68  // NewSnapshot creates a snapshot from response types and a version.
    69  func NewSnapshot(version string,
    70  	endpoints []types.Resource,
    71  	clusters []types.Resource,
    72  	routes []types.Resource,
    73  	listeners []types.Resource,
    74  	runtimes []types.Resource,
    75  	secrets []types.Resource) Snapshot {
    76  	return NewSnapshotWithResources(version, SnapshotResources{
    77  		Endpoints: endpoints,
    78  		Clusters:  clusters,
    79  		Routes:    routes,
    80  		Listeners: listeners,
    81  		Runtimes:  runtimes,
    82  		Secrets:   secrets,
    83  	})
    84  }
    85  
    86  // SnapshotResources contains the resources to construct a snapshot from.
    87  type SnapshotResources struct {
    88  	Endpoints        []types.Resource
    89  	Clusters         []types.Resource
    90  	Routes           []types.Resource
    91  	Listeners        []types.Resource
    92  	Runtimes         []types.Resource
    93  	Secrets          []types.Resource
    94  	ExtensionConfigs []types.Resource
    95  }
    96  
    97  // NewSnapshotWithResources creates a snapshot from response types and a version.
    98  func NewSnapshotWithResources(version string, resources SnapshotResources) Snapshot {
    99  	out := Snapshot{}
   100  	out.Resources[types.Endpoint] = NewResources(version, resources.Endpoints)
   101  	out.Resources[types.Cluster] = NewResources(version, resources.Clusters)
   102  	out.Resources[types.Route] = NewResources(version, resources.Routes)
   103  	out.Resources[types.Listener] = NewResources(version, resources.Listeners)
   104  	out.Resources[types.Runtime] = NewResources(version, resources.Runtimes)
   105  	out.Resources[types.Secret] = NewResources(version, resources.Secrets)
   106  	out.Resources[types.ExtensionConfig] = NewResources(version, resources.ExtensionConfigs)
   107  	return out
   108  }
   109  
   110  type ResourceWithTtl struct {
   111  	Resources []types.Resource
   112  	Ttl       *time.Duration
   113  }
   114  
   115  func NewSnapshotWithTtls(version string,
   116  	endpoints []types.ResourceWithTtl,
   117  	clusters []types.ResourceWithTtl,
   118  	routes []types.ResourceWithTtl,
   119  	listeners []types.ResourceWithTtl,
   120  	runtimes []types.ResourceWithTtl,
   121  	secrets []types.ResourceWithTtl) Snapshot {
   122  	out := Snapshot{}
   123  	out.Resources[types.Endpoint] = NewResourcesWithTtl(version, endpoints)
   124  	out.Resources[types.Cluster] = NewResourcesWithTtl(version, clusters)
   125  	out.Resources[types.Route] = NewResourcesWithTtl(version, routes)
   126  	out.Resources[types.Listener] = NewResourcesWithTtl(version, listeners)
   127  	out.Resources[types.Runtime] = NewResourcesWithTtl(version, runtimes)
   128  	out.Resources[types.Secret] = NewResourcesWithTtl(version, secrets)
   129  	return out
   130  }
   131  
   132  // Consistent check verifies that the dependent resources are exactly listed in the
   133  // snapshot:
   134  // - all EDS resources are listed by name in CDS resources
   135  // - all RDS resources are listed by name in LDS resources
   136  //
   137  // Note that clusters and listeners are requested without name references, so
   138  // Envoy will accept the snapshot list of clusters as-is even if it does not match
   139  // all references found in xDS.
   140  func (s *Snapshot) Consistent() error {
   141  	if s == nil {
   142  		return errors.New("nil snapshot")
   143  	}
   144  	endpoints := GetResourceReferences(s.Resources[types.Cluster].Items)
   145  	if len(endpoints) != len(s.Resources[types.Endpoint].Items) {
   146  		return fmt.Errorf("mismatched endpoint reference and resource lengths: %v != %d", endpoints, len(s.Resources[types.Endpoint].Items))
   147  	}
   148  	if err := superset(endpoints, s.Resources[types.Endpoint].Items); err != nil {
   149  		return err
   150  	}
   151  
   152  	routes := GetResourceReferences(s.Resources[types.Listener].Items)
   153  	if len(routes) != len(s.Resources[types.Route].Items) {
   154  		return fmt.Errorf("mismatched route reference and resource lengths: %v != %d", routes, len(s.Resources[types.Route].Items))
   155  	}
   156  	return superset(routes, s.Resources[types.Route].Items)
   157  }
   158  
   159  // GetResources selects snapshot resources by type, returning the map of resources.
   160  func (s *Snapshot) GetResources(typeURL string) map[string]types.Resource {
   161  	resources := s.GetResourcesAndTtl(typeURL)
   162  	if resources == nil {
   163  		return nil
   164  	}
   165  
   166  	withoutTtl := make(map[string]types.Resource, len(resources))
   167  
   168  	for k, v := range resources {
   169  		withoutTtl[k] = v.Resource
   170  	}
   171  
   172  	return withoutTtl
   173  }
   174  
   175  // GetResourcesAndTtl selects snapshot resources by type, returning the map of resources and the associated TTL.
   176  func (s *Snapshot) GetResourcesAndTtl(typeURL string) map[string]types.ResourceWithTtl {
   177  	if s == nil {
   178  		return nil
   179  	}
   180  	typ := GetResponseType(typeURL)
   181  	if typ == types.UnknownType {
   182  		return nil
   183  	}
   184  	return s.Resources[typ].Items
   185  }
   186  
   187  // GetVersion returns the version for a resource type.
   188  func (s *Snapshot) GetVersion(typeURL string) string {
   189  	if s == nil {
   190  		return ""
   191  	}
   192  	typ := GetResponseType(typeURL)
   193  	if typ == types.UnknownType {
   194  		return ""
   195  	}
   196  	return s.Resources[typ].Version
   197  }
   198  

View as plain text