/
cec_types.go
160 lines (137 loc) · 5.26 KB
/
cec_types.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
// SPDX-License-Identifier: Apache-2.0
// Copyright Authors of Cilium
package v2
import (
"bytes"
"encoding/json"
"fmt"
"google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/encoding/prototext"
"google.golang.org/protobuf/proto"
anypb "google.golang.org/protobuf/types/known/anypb"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/cilium/cilium/pkg/option"
)
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +kubebuilder:resource:categories={cilium},singular="ciliumenvoyconfig",path="ciliumenvoyconfigs",scope="Namespaced",shortName={cec}
// +kubebuilder:printcolumn:JSONPath=".metadata.creationTimestamp",description="The age of the identity",name="Age",type=date
// +kubebuilder:storageversion
type CiliumEnvoyConfig struct {
// +k8s:openapi-gen=false
// +deepequal-gen=false
metav1.TypeMeta `json:",inline"`
// +k8s:openapi-gen=false
// +deepequal-gen=false
metav1.ObjectMeta `json:"metadata"`
// +k8s:openapi-gen=false
// +kubebuilder:validation:Type=object
Spec CiliumEnvoyConfigSpec `json:"spec,omitempty"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +deepequal-gen=false
// CiliumEnvoyConfigList is a list of CiliumEnvoyConfig objects.
type CiliumEnvoyConfigList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata"`
// Items is a list of CiliumEnvoyConfig.
Items []CiliumEnvoyConfig `json:"items"`
}
type CiliumEnvoyConfigSpec struct {
// Services specifies Kubernetes services for which traffic is
// forwarded to an Envoy listener for L7 load balancing. Backends
// of these services are automatically synced to Envoy usign EDS.
//
// +kubebuilder:validation:Optional
Services []*ServiceListener `json:"services,omitempty"`
// BackendServices specifies Kubernetes services whose backends
// are automatically synced to Envoy using EDS. Traffic for these
// services is not forwarded to an Envoy listener. This allows an
// Envoy listener load balance traffic to these backends while
// normal Cilium service load balancing takes care of balancing
// traffic for these services at the same time.
//
// +kubebuilder:validation:Optional
BackendServices []*Service `json:"backendServices,omitempty"`
// Envoy xDS resources, a list of the following Envoy resource types:
// type.googleapis.com/envoy.config.listener.v3.Listener,
// type.googleapis.com/envoy.config.route.v3.RouteConfiguration,
// type.googleapis.com/envoy.config.cluster.v3.Cluster,
// type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment, and
// type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret.
//
// +kubebuilder:validation:Required
Resources []XDSResource `json:"resources,omitempty"`
}
type Service struct {
// Name is the name of a destination Kubernetes service that identifies traffic
// to be redirected.
//
// +kubebuilder:validation:Required
Name string `json:"name"`
// Namespace is the Kubernetes service namespace.
// In CiliumEnvoyConfig namespace defaults to the namespace of the CEC,
// In CiliumClusterwideEnvoyConfig namespace defaults to "default".
// +kubebuilder:validation:Optional
Namespace string `json:"namespace"`
}
type ServiceListener struct {
// Name is the name of a destination Kubernetes service that identifies traffic
// to be redirected.
//
// +kubebuilder:validation:Required
Name string `json:"name"`
// Namespace is the Kubernetes service namespace.
// In CiliumEnvoyConfig namespace this is overridden to the namespace of the CEC,
// In CiliumClusterwideEnvoyConfig namespace defaults to "default".
// +kubebuilder:validation:Optional
Namespace string `json:"namespace"`
// Listener specifies the name of the Envoy listener the
// service traffic is redirected to. The listener must be
// specified in the Envoy 'resources' of the same
// CiliumEnvoyConfig.
//
// If omitted, the first listener specified in 'resources' is
// used.
//
// +kubebuilder:validation:Optional
Listener string `json:"listener"`
}
// +kubebuilder:pruning:PreserveUnknownFields
type XDSResource struct {
*anypb.Any `json:"-"`
}
// DeepCopyInto deep copies 'in' into 'out'.
func (in *XDSResource) DeepCopyInto(out *XDSResource) {
out.Any, _ = proto.Clone(in.Any).(*anypb.Any)
}
// Equal returns 'true' if 'a' and 'b' are equal.
func (a *XDSResource) DeepEqual(b *XDSResource) bool {
return proto.Equal(a.Any, b.Any)
}
// MarshalJSON ensures that the unstructured object produces proper
// JSON when passed to Go's standard JSON library.
func (u *XDSResource) MarshalJSON() ([]byte, error) {
return protojson.Marshal(u.Any)
}
// UnmarshalJSON ensures that the unstructured object properly decodes
// JSON when passed to Go's standard JSON library.
func (u *XDSResource) UnmarshalJSON(b []byte) (err error) {
// xDS resources are not validated in K8s, recover from possible panics
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("CEC JSON decoding paniced: %v", r)
}
}()
u.Any = &anypb.Any{}
err = protojson.Unmarshal(b, u.Any)
if err != nil {
var buf bytes.Buffer
json.Indent(&buf, b, "", "\t")
log.Warningf("Ignoring invalid CiliumEnvoyConfig JSON (%s): %s",
err, buf.String())
} else if option.Config.Debug {
log.Debugf("CEC unmarshaled XDS Resource: %v", prototext.Format(u.Any))
}
return nil
}