You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- Add how to create CRDs to contributing.md.
- Add a script that will copy new CRDs to consul-helm in the format
expected. This will reduce manual copying errors.
// IngressGateway is the Schema for the ingressgateways API
78
+
type IngressGateway struct {
79
+
metav1.TypeMeta `json:",inline"`
80
+
metav1.ObjectMeta `json:"metadata,omitempty"`
81
+
82
+
Spec IngressGatewaySpec `json:"spec,omitempty"`
83
+
Status IngressGatewayStatus `json:"status,omitempty"`
84
+
}
85
+
86
+
// +kubebuilder:object:root=true
87
+
88
+
// IngressGatewayList contains a list of IngressGateway
89
+
type IngressGatewayList struct {
90
+
metav1.TypeMeta `json:",inline"`
91
+
metav1.ListMeta `json:"metadata,omitempty"`
92
+
Items []IngressGateway `json:"items"`
93
+
}
94
+
95
+
// IngressGatewaySpec defines the desired state of IngressGateway
96
+
type IngressGatewaySpec struct {
97
+
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
98
+
// Important: Run "make" to regenerate code after modifying this file
99
+
100
+
// Foo is an example field of IngressGateway. Edit IngressGateway_types.go to remove/update
101
+
Foo string `json:"foo,omitempty"`
102
+
}
103
+
104
+
// IngressGatewayStatus defines the observed state of IngressGateway
105
+
type IngressGatewayStatus struct {
106
+
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
107
+
// Important: Run "make" to regenerate code after modifying this file
108
+
}
109
+
```
110
+
1. Add kubebuilder status metadata to the `IngressGateway struct`:
111
+
```go
112
+
// ServiceRouter is the Schema for the servicerouters API
113
+
// +kubebuilder:printcolumn:name="Synced",type="string",JSONPath=".status.conditions[?(@.type==\"Synced\")].status",description="The sync status of the resource with Consul"
114
+
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="The age of the resource"
115
+
type ServiceRouter struct {
116
+
```
117
+
1. Delete `IngressGatewayStatus` struct. We use a common status struct.
118
+
1. Use the `Status` struct instead and embed it:
119
+
```diff
120
+
// IngressGateway is the Schema for the ingressgateways API
121
+
type IngressGateway struct {
122
+
metav1.TypeMeta `json:",inline"`
123
+
metav1.ObjectMeta `json:"metadata,omitempty"`
124
+
125
+
Spec IngressGatewaySpec `json:"spec,omitempty"`
126
+
- Status IngressGatewayStatus `json:"status,omitempty"`
127
+
+ Status `json:"status,omitempty"`
128
+
}
129
+
```
130
+
1. Go to the Consul `api` package for the config entry, e.g. https://github.com/hashicorp/consul/blob/master/api/config_entry_gateways.go
131
+
1. Copy the top-level fields over into the `Spec` struct except for
132
+
`Kind`, `Name`, `Namespace`, `Meta`, `CreateIndex` and `ModifyIndex`. In this
133
+
example, the top-level fields remaining are `TLS` and `Listeners`:
134
+
135
+
```go
136
+
// IngressGatewaySpec defines the desired state of IngressGateway
137
+
type IngressGatewaySpec struct {
138
+
// TLS holds the TLS configuration for this gateway.
139
+
TLS GatewayTLSConfig
140
+
// Listeners declares what ports the ingress gateway should listen on, and
141
+
// what services to associated to those ports.
142
+
Listeners []IngressListener
143
+
}
144
+
```
145
+
1. Copy the structs over that are missing, e.g. `GatewayTLSConfig`, `IngressListener`.
146
+
1. Set `json` tags for all fields using camelCase starting with a lowercase letter:
147
+
```go
148
+
TLS GatewayTLSConfig `json:"tls"`
149
+
```
150
+
Note that you should use the fields name, e.g. `tls`, not the struct name, e.g. `gatewayTLSConfig`.
151
+
Remove any `alias` struct tags.
152
+
1. If the fields aren't documented, document them using the Consul docs as a reference.
153
+
154
+
### Spec Methods
155
+
1. Run `make ctrl-generate` to implement the deep copy methods.
156
+
1. Implement all the methods for `ConfigEntryResource` in the `_types.go` file. If using goland you can
157
+
automatically stub out all the methods by using Code -> Generate -> IngressGateway -> ConfigEntryResource.
158
+
1. Use existing implementations of other types to implement the methods. We have to
159
+
copy their code because we can't use a common struct that implements the methods
160
+
because that messes up the CRD code generation.
161
+
162
+
You should be able to follow the other "normal" types. The non-normal types
163
+
are `ServiceIntention` and `ProxyDefault` because they have special behaviour
164
+
around being global or their spec not matching up with Consul's directly.
165
+
1. When you get to `ToConsul` and `Validate` you'll need to actually think
166
+
about the implementation instead of copy/pasting and doing a simple replace.
167
+
1. For `ToConsul`, the pattern we follow is to implement `toConsul()` methods
168
+
on each sub-struct. You can see this pattern in the existing types.
169
+
1. For `Validate`, we again follow the pattern of implementing the method on
170
+
each sub-struct. You'll need to read the Consul documentation to understand
171
+
what validation needs to be done.
172
+
173
+
Things to keep in mind:
174
+
1. Re-use the `sliceContains` and `notInSliceMessage` helper methods where applicable.
175
+
1. If the invalid field is an entire struct, encode as json (look for `asJSON` for an example).
176
+
1. `validateNamespaces` should be a separate method.
177
+
1. If the field can have a `nil` pointer, check for that, e.g.
178
+
```go
179
+
func (in *ServiceRouteHTTPMatchHeader) validate(path *field.Path) *field.Error {
180
+
if in == nil {
181
+
return nil
182
+
}
183
+
```
184
+
185
+
### Spec Tests
186
+
1. Create a test file, e.g. `ingressgateway_types_test.go`.
187
+
1. Copy the tests for the `ConfigEntryResource` methods from another type and search and replace.
188
+
Only the tests for `ToConsul()`, `Validate()` and `MatchesConsul()` need to
0 commit comments