1// Copyright 2020 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
15package gateway
16
17import (
18	"fmt"
19
20	"k8s.io/client-go/kubernetes"
21	svc "sigs.k8s.io/service-apis/api/v1alpha1"
22
23	"istio.io/istio/pkg/config/schema/collection"
24	"istio.io/istio/pkg/config/schema/collections"
25	"istio.io/istio/pkg/config/schema/resource"
26	"istio.io/pkg/ledger"
27
28	"istio.io/istio/pilot/pkg/model"
29)
30
31var (
32	vsType      = collections.IstioNetworkingV1Alpha3Virtualservices.Resource()
33	gatewayType = collections.IstioNetworkingV1Alpha3Gateways.Resource()
34)
35
36type controller struct {
37	client kubernetes.Interface
38	cache  model.ConfigStoreCache
39}
40
41func (c *controller) GetLedger() ledger.Ledger {
42	return c.cache.GetLedger()
43}
44
45func (c *controller) SetLedger(l ledger.Ledger) error {
46	return c.cache.SetLedger(l)
47}
48
49func (c *controller) Schemas() collection.Schemas {
50	return collection.SchemasFor(
51		collections.IstioNetworkingV1Alpha3Virtualservices,
52		collections.IstioNetworkingV1Alpha3Gateways,
53	)
54}
55
56func (c controller) Get(typ resource.GroupVersionKind, name, namespace string) *model.Config {
57	panic("implement me")
58}
59
60var _ = svc.HTTPRoute{}
61var _ = svc.GatewayClass{}
62
63func (c controller) List(typ resource.GroupVersionKind, namespace string) ([]model.Config, error) {
64	if typ != gatewayType.GroupVersionKind() && typ != vsType.GroupVersionKind() {
65		return nil, errUnsupportedOp
66	}
67
68	gatewayClass, err := c.cache.List(collections.K8SServiceApisV1Alpha1Gatewayclasses.Resource().GroupVersionKind(), namespace)
69	if err != nil {
70		return nil, fmt.Errorf("failed to list type GatewayClass: %v", err)
71	}
72	gateway, err := c.cache.List(collections.K8SServiceApisV1Alpha1Gateways.Resource().GroupVersionKind(), namespace)
73	if err != nil {
74		return nil, fmt.Errorf("failed to list type Gateway: %v", err)
75	}
76	httpRoute, err := c.cache.List(collections.K8SServiceApisV1Alpha1Httproutes.Resource().GroupVersionKind(), namespace)
77	if err != nil {
78		return nil, fmt.Errorf("failed to list type HTTPRoute: %v", err)
79	}
80	tcpRoute, err := c.cache.List(collections.K8SServiceApisV1Alpha1Tcproutes.Resource().GroupVersionKind(), namespace)
81	if err != nil {
82		return nil, fmt.Errorf("failed to list type TcpRoute: %v", err)
83	}
84	trafficSplit, err := c.cache.List(collections.K8SServiceApisV1Alpha1Trafficsplits.Resource().GroupVersionKind(), namespace)
85	if err != nil {
86		return nil, fmt.Errorf("failed to list type TrafficSplit: %v", err)
87	}
88
89	input := &KubernetesResources{
90		GatewayClass: gatewayClass,
91		Gateway:      gateway,
92		HTTPRoute:    httpRoute,
93		TCPRoute:     tcpRoute,
94		TrafficSplit: trafficSplit,
95	}
96	output := convertResources(input)
97
98	switch typ {
99	case gatewayType.GroupVersionKind():
100		return output.Gateway, nil
101	case vsType.GroupVersionKind():
102		return output.VirtualService, nil
103	}
104	return nil, errUnsupportedOp
105}
106
107var (
108	errUnsupportedOp = fmt.Errorf("unsupported operation: the gateway config store is a read-only view")
109)
110
111func (c controller) Create(config model.Config) (revision string, err error) {
112	return "", errUnsupportedOp
113}
114
115func (c controller) Update(config model.Config) (newRevision string, err error) {
116	return "", errUnsupportedOp
117}
118
119func (c controller) Delete(typ resource.GroupVersionKind, name, namespace string) error {
120	return errUnsupportedOp
121}
122
123func (c controller) Version() string {
124	return c.cache.Version()
125}
126
127func (c controller) GetResourceAtVersion(version string, key string) (resourceVersion string, err error) {
128	return c.cache.GetResourceAtVersion(version, key)
129}
130
131func (c controller) RegisterEventHandler(typ resource.GroupVersionKind, handler func(model.Config, model.Config, model.Event)) {
132	c.cache.RegisterEventHandler(typ, func(prev, cur model.Config, event model.Event) {
133		handler(prev, cur, event)
134	})
135}
136
137func (c controller) Run(stop <-chan struct{}) {
138}
139
140func (c controller) HasSynced() bool {
141	return c.cache.HasSynced()
142}
143
144func NewController(client kubernetes.Interface, c model.ConfigStoreCache) model.ConfigStoreCache {
145	return &controller{client, c}
146}
147