forked from kubernetes-sigs/ingress2gateway
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprovider.go
166 lines (136 loc) · 6.3 KB
/
provider.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/*
Copyright 2023 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package i2gw
import (
"context"
"sync"
"github.com/kubernetes-sigs/ingress2gateway/pkg/i2gw/intermediate"
networkingv1 "k8s.io/api/networking/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/validation/field"
"sigs.k8s.io/controller-runtime/pkg/client"
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
gatewayv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
gatewayv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1"
)
// ProviderConstructorByName is a map of ProviderConstructor functions by a
// provider name. Different Provider implementations should add their construction
// func at startup.
var ProviderConstructorByName = map[ProviderName]ProviderConstructor{}
// ProviderName is a string alias that stores the concrete Provider name.
type ProviderName string
// ProviderConstructor is a construction function that constructs concrete
// implementations of the Provider interface.
type ProviderConstructor func(conf *ProviderConf) Provider
// ProviderConf contains all the configuration required for every concrete
// Provider implementation.
type ProviderConf struct {
Client client.Client
Namespace string
ProviderSpecificFlags map[string]map[string]string
}
// The Provider interface specifies the required functionality which needs to be
// implemented by every concrete Ingress/Gateway-API provider, in order for it to
// be used.
type Provider interface {
CustomResourceReader
ResourcesToIRConverter
IRToGatewayAPIConverter
}
type CustomResourceReader interface {
// ReadResourcesFromCluster reads custom resources associated with
// the underlying Provider implementation from the kubernetes cluster.
ReadResourcesFromCluster(ctx context.Context) error
// ReadResourcesFromFile reads custom resources associated with
// the underlying Provider implementation from the file.
ReadResourcesFromFile(ctx context.Context, filename string) error
}
// The ResourcesToIRConverter interface specifies conversion functions from Ingress
// and extensions into IR.
type ResourcesToIRConverter interface {
// ToIR converts stored API entities associated with the Provider into IR.
ToIR() (intermediate.IR, field.ErrorList)
}
// The IRToGatewayAPIConverter interface specifies conversion functions from IR
// into Gateway and Gateway extensions.
type IRToGatewayAPIConverter interface {
// ToGatewayResources converts stored IR with the Provider into
// Gateway API resources and extensions
ToGatewayResources(intermediate.IR) (GatewayResources, field.ErrorList)
}
// ImplementationSpecificHTTPPathTypeMatchConverter is an option to customize the ingress implementationSpecific
// match type conversion.
type ImplementationSpecificHTTPPathTypeMatchConverter func(*gatewayv1.HTTPPathMatch)
// ProviderImplementationSpecificOptions contains customized implementation-specific fields and functions.
// These will be used by the common package to customize the provider-specific behavior for all the
// implementation-specific fields of the ingress API.
type ProviderImplementationSpecificOptions struct {
ToImplementationSpecificHTTPPathTypeMatch ImplementationSpecificHTTPPathTypeMatchConverter
}
// GatewayResources contains all Gateway-API objects and provider Gateway
// extensions.
type GatewayResources struct {
Gateways map[types.NamespacedName]gatewayv1.Gateway
GatewayClasses map[types.NamespacedName]gatewayv1.GatewayClass
HTTPRoutes map[types.NamespacedName]gatewayv1.HTTPRoute
TLSRoutes map[types.NamespacedName]gatewayv1alpha2.TLSRoute
TCPRoutes map[types.NamespacedName]gatewayv1alpha2.TCPRoute
UDPRoutes map[types.NamespacedName]gatewayv1alpha2.UDPRoute
ReferenceGrants map[types.NamespacedName]gatewayv1beta1.ReferenceGrant
GatewayExtensions []unstructured.Unstructured
}
// FeatureParser is a function that reads the Ingresses, and applies
// the appropriate modifications to the GatewayResources.
//
// Different FeatureParsers will run in undetermined order. The function must
// modify / create only the required fields of the gateway resources and nothing else.
type FeatureParser func([]networkingv1.Ingress, *intermediate.IR) field.ErrorList
var providerSpecificFlagDefinitions = providerSpecificFlags{
flags: make(map[ProviderName]map[string]ProviderSpecificFlag),
mu: sync.RWMutex{},
}
type providerSpecificFlags struct {
flags map[ProviderName]map[string]ProviderSpecificFlag
mu sync.RWMutex // thread-safe, so provider-specific flags can be registered concurrently.
}
type ProviderSpecificFlag struct {
Name string
Description string
DefaultValue string
}
func (f *providerSpecificFlags) add(provider ProviderName, flag ProviderSpecificFlag) {
f.mu.Lock()
defer f.mu.Unlock()
if f.flags[provider] == nil {
f.flags[provider] = map[string]ProviderSpecificFlag{}
}
f.flags[provider][flag.Name] = flag
}
func (f *providerSpecificFlags) all() map[ProviderName]map[string]ProviderSpecificFlag {
f.mu.RLock()
defer f.mu.RUnlock()
return f.flags
}
// RegisterProviderSpecificFlag registers a provider-specific flag.
// Each provider-specific flag is exposed to the user as an optional command-line flag --<provider>-<flag>.
// If the flag is not provided, it is up to the provider to decide to use the default value or raise an error.
// The provider can read the values of provider-specific flags input by the user from the ProviderConf.
// RegisterProviderSpecificFlag is thread-safe.
func RegisterProviderSpecificFlag(provider ProviderName, flag ProviderSpecificFlag) {
providerSpecificFlagDefinitions.add(provider, flag)
}
// GetProviderSpecificFlagDefinitions returns the provider specific confs registered by the providers.
func GetProviderSpecificFlagDefinitions() map[ProviderName]map[string]ProviderSpecificFlag {
return providerSpecificFlagDefinitions.all()
}