Skip to content

Commit af014dc

Browse files
authored
Expand crd configuration options (#22)
* added nodeselector, resources, tolerations #20 #18 #8 draft for additional vars from configmap #19 * added extra configuration #8 #18 #19 #20
1 parent 8ac3c23 commit af014dc

11 files changed

+238
-38
lines changed

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ OPERATOR_SDK_VERSION ?= v1.38.0
5252
# Image URL to use all building/pushing image targets
5353
DOCKER_HUB_NAME ?= $(shell docker info | sed '/Username:/!d;s/.* //')
5454
IMG_NAME ?= typesense-operator
55-
IMG_TAG ?= 0.2.6
55+
IMG_TAG ?= 0.2.7
5656
IMG ?= $(DOCKER_HUB_NAME)/$(IMG_NAME):$(IMG_TAG)
5757

5858
# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary.

README.md

+24-12
Original file line numberDiff line numberDiff line change
@@ -172,18 +172,30 @@ introducing `TypesenseCluster`, a new Custom Resource Definition:
172172
173173
**Spec**
174174
175-
| Name | Description | Optional | Default |
176-
|-------------------|----------------------------------------------------|----------|---------|
177-
| image | Typesense image | | |
178-
| adminApiKey | Reference to the `Secret` to be used for bootstrap | X | |
179-
| replicas | Size of the cluster | | 1 |
180-
| apiPort | REST/API port | | 8108 |
181-
| peeringPort | Peering port | | 8107 |
182-
| resetPeersOnError | automatic reset of peers on error | | true |
183-
| corsDomains | domains that would be allowed for CORS calls | X | |
184-
| storage | check `StorageSpec` below | | |
185-
| ingress | check `IngressSpec` below | X | |
186-
| scrapers | array of `DocSearchScraperSpec`; check below | X | |
175+
| Name | Description | Optional | Default |
176+
|-------------------------------|----------------------------------------------------------|----------|---------------|
177+
| image | Typesense image | | |
178+
| adminApiKey | Reference to the `Secret` to be used for bootstrap | X | |
179+
| replicas | Size of the cluster | | 1 |
180+
| apiPort | REST/API port | | 8108 |
181+
| peeringPort | Peering port | | 8107 |
182+
| resetPeersOnError | automatic reset of peers on error | | true |
183+
| enableCors | enables CORS | X | false |
184+
| corsDomains | domains that would be allowed for CORS calls | X | |
185+
| resources | resource request & limit | X | _check specs_ |
186+
| nodeSelector | node selection constraint | X | |
187+
| tolerations | schedule pods with matching taints | X | |
188+
| additionalServerConfiguration | a reference to a `ConfigMap` holding extra configuration | X | |
189+
| storage | check `StorageSpec` below | | |
190+
| ingress | check `IngressSpec` below | X | |
191+
| scrapers | array of `DocSearchScraperSpec`; check below | X | |
192+
193+
> [!IMPORTANT]
194+
> * Any Typesense server configuration variable that is defined in Spec is overriding any additional reference of
195+
> the same variable in `additionalServerConfiguration`. You can find an example of providing an additional `ConfigMap`
196+
> in: **config/samples/ts_v1alpha1_typesensecluster_kind.yaml**
197+
> * Add additional Typesense server configuration variables in `ConfigMap` as described in:
198+
> https://typesense.org/docs/27.1/api/server-configuration.html#using-environment-variables
187199
188200
**StorageSpec** (optional)
189201

api/v1alpha1/typesensecluster_types.go

+16
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,26 @@ type TypesenseClusterSpec struct {
6161
// +kubebuilder:validation:Type=boolean
6262
ResetPeersOnError bool `json:"resetPeersOnError,omitempty"`
6363

64+
// +optional
65+
// +kubebuilder:default=false
66+
// +kubebuilder:validation:Type=boolean
67+
EnableCors bool `json:"enableCors,omitempty"`
68+
6469
// +optional
6570
// +kubebuilder:validation:Type=string
6671
CorsDomains *string `json:"corsDomains,omitempty"`
6772

73+
Resources *corev1.ResourceRequirements `json:"resources,omitempty"`
74+
75+
// +kubebuilder:validation:Optional
76+
NodeSelector map[string]string `json:"nodeSelector,omitempty"`
77+
78+
// +kubebuilder:validation:Optional
79+
Tolerations []corev1.Toleration `json:"tolerations,omitempty"`
80+
81+
// +kubebuilder:validation:Optional
82+
AdditionalServerConfiguration *corev1.LocalObjectReference `json:"additionalServerConfiguration,omitempty"`
83+
6884
Storage *StorageSpec `json:"storage"`
6985

7086
Ingress *IngressSpec `json:"ingress,omitempty"`

api/v1alpha1/typesensecluster_types_helpers.go

+33-9
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,54 @@
11
package v1alpha1
22

33
import (
4+
corev1 "k8s.io/api/core/v1"
45
"k8s.io/apimachinery/pkg/api/resource"
5-
"strings"
66
)
77

8-
func (s *TypesenseClusterSpec) IsCorsEnabled() bool {
9-
if s.CorsDomains != nil && strings.TrimSpace(*s.CorsDomains) != "" {
10-
return true
8+
func (s *TypesenseClusterSpec) GetResources() corev1.ResourceRequirements {
9+
if s.Resources != nil {
10+
return *s.Resources
1111
}
12-
return false
12+
13+
return corev1.ResourceRequirements{
14+
Limits: corev1.ResourceList{
15+
corev1.ResourceCPU: resource.MustParse("1024m"),
16+
corev1.ResourceMemory: resource.MustParse("512Mi"),
17+
},
18+
Requests: corev1.ResourceList{
19+
corev1.ResourceCPU: resource.MustParse("128m"),
20+
corev1.ResourceMemory: resource.MustParse("256Mi"),
21+
},
22+
}
23+
}
24+
25+
func (s *TypesenseClusterSpec) GetAdditionalServerConfiguration() []corev1.EnvFromSource {
26+
if s.AdditionalServerConfiguration != nil {
27+
return []corev1.EnvFromSource{
28+
{
29+
ConfigMapRef: &corev1.ConfigMapEnvSource{
30+
LocalObjectReference: *s.AdditionalServerConfiguration,
31+
},
32+
},
33+
}
34+
}
35+
36+
return []corev1.EnvFromSource{}
1337
}
1438

1539
func (s *TypesenseClusterSpec) GetCorsDomains() string {
16-
if s.IsCorsEnabled() {
40+
if s.EnableCors {
1741
return *s.CorsDomains
1842
}
1943
return ""
2044
}
2145

22-
func (s *TypesenseClusterSpec) GetStorage() *StorageSpec {
46+
func (s *TypesenseClusterSpec) GetStorage() StorageSpec {
2347
if s.Storage != nil {
24-
return s.Storage
48+
return *s.Storage
2549
}
2650

27-
return &StorageSpec{
51+
return StorageSpec{
2852
Size: resource.MustParse("100Mi"),
2953
StorageClassName: "standard",
3054
}

api/v1alpha1/zz_generated.deepcopy.go

+24
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

charts/typesense-operator/Chart.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ type: application
1313
# This is the chart version. This version number should be incremented each time you make changes
1414
# to the chart and its templates, including the app version.
1515
# Versions are expected to follow Semantic Versioning (https://semver.org/)
16-
version: 0.2.6
16+
version: 0.2.7
1717
# This is the version number of the application being deployed. This version number should be
1818
# incremented each time you make changes to the application. Versions are not expected to
1919
# follow Semantic Versioning. They should reflect the version the application is using.
2020
# It is recommended to use it with quotes.
21-
appVersion: "0.2.6"
21+
appVersion: "0.2.7"

charts/typesense-operator/values.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ controllerManager:
1212
- ALL
1313
image:
1414
repository: akyriako78/typesense-operator
15-
tag: 0.2.6
15+
tag: 0.2.7
1616
resources:
1717
limits:
1818
cpu: 500m

config/crd/bases/ts.opentelekomcloud.com_typesenseclusters.yaml

+118
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,24 @@ spec:
5555
spec:
5656
description: TypesenseClusterSpec defines the desired state of TypesenseCluster
5757
properties:
58+
additionalServerConfiguration:
59+
description: |-
60+
LocalObjectReference contains enough information to let you locate the
61+
referenced object inside the same namespace.
62+
properties:
63+
name:
64+
default: ""
65+
description: |-
66+
Name of the referent.
67+
This field is effectively required, but due to backwards compatibility is
68+
allowed to be empty. Instances of this type with an empty value here are
69+
almost certainly wrong.
70+
TODO: Add other useful fields. apiVersion, kind, uid?
71+
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
72+
TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
73+
type: string
74+
type: object
75+
x-kubernetes-map-type: atomic
5876
adminApiKey:
5977
description: |-
6078
SecretReference represents a Secret Reference. It has enough information to retrieve secret
@@ -78,6 +96,9 @@ spec:
7896
type: integer
7997
corsDomains:
8098
type: string
99+
enableCors:
100+
default: false
101+
type: boolean
81102
image:
82103
type: string
83104
ingress:
@@ -101,6 +122,10 @@ spec:
101122
- host
102123
- ingressClassName
103124
type: object
125+
nodeSelector:
126+
additionalProperties:
127+
type: string
128+
type: object
104129
peeringPort:
105130
default: 8107
106131
exclusiveMinimum: true
@@ -115,6 +140,61 @@ spec:
115140
resetPeersOnError:
116141
default: true
117142
type: boolean
143+
resources:
144+
description: ResourceRequirements describes the compute resource requirements.
145+
properties:
146+
claims:
147+
description: |-
148+
Claims lists the names of resources, defined in spec.resourceClaims,
149+
that are used by this container.
150+
151+
152+
This is an alpha field and requires enabling the
153+
DynamicResourceAllocation feature gate.
154+
155+
156+
This field is immutable. It can only be set for containers.
157+
items:
158+
description: ResourceClaim references one entry in PodSpec.ResourceClaims.
159+
properties:
160+
name:
161+
description: |-
162+
Name must match the name of one entry in pod.spec.resourceClaims of
163+
the Pod where this field is used. It makes that resource available
164+
inside a container.
165+
type: string
166+
required:
167+
- name
168+
type: object
169+
type: array
170+
x-kubernetes-list-map-keys:
171+
- name
172+
x-kubernetes-list-type: map
173+
limits:
174+
additionalProperties:
175+
anyOf:
176+
- type: integer
177+
- type: string
178+
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
179+
x-kubernetes-int-or-string: true
180+
description: |-
181+
Limits describes the maximum amount of compute resources allowed.
182+
More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
183+
type: object
184+
requests:
185+
additionalProperties:
186+
anyOf:
187+
- type: integer
188+
- type: string
189+
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
190+
x-kubernetes-int-or-string: true
191+
description: |-
192+
Requests describes the minimum amount of compute resources required.
193+
If Requests is omitted for a container, it defaults to Limits if that is explicitly specified,
194+
otherwise to an implementation-defined value. Requests cannot exceed Limits.
195+
More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
196+
type: object
197+
type: object
118198
scrapers:
119199
items:
120200
properties:
@@ -148,6 +228,44 @@ spec:
148228
required:
149229
- storageClassName
150230
type: object
231+
tolerations:
232+
items:
233+
description: |-
234+
The pod this Toleration is attached to tolerates any taint that matches
235+
the triple <key,value,effect> using the matching operator <operator>.
236+
properties:
237+
effect:
238+
description: |-
239+
Effect indicates the taint effect to match. Empty means match all taint effects.
240+
When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute.
241+
type: string
242+
key:
243+
description: |-
244+
Key is the taint key that the toleration applies to. Empty means match all taint keys.
245+
If the key is empty, operator must be Exists; this combination means to match all values and all keys.
246+
type: string
247+
operator:
248+
description: |-
249+
Operator represents a key's relationship to the value.
250+
Valid operators are Exists and Equal. Defaults to Equal.
251+
Exists is equivalent to wildcard for value, so that a pod can
252+
tolerate all taints of a particular category.
253+
type: string
254+
tolerationSeconds:
255+
description: |-
256+
TolerationSeconds represents the period of time the toleration (which must be
257+
of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default,
258+
it is not set, which means tolerate the taint forever (do not evict). Zero and
259+
negative values will be treated as 0 (evict immediately) by the system.
260+
format: int64
261+
type: integer
262+
value:
263+
description: |-
264+
Value is the taint value the toleration matches to.
265+
If the operator is Exists, the value should be empty, otherwise just a regular string.
266+
type: string
267+
type: object
268+
type: array
151269
required:
152270
- image
153271
- storage

config/manager/kustomization.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ kind: Kustomization
55
images:
66
- name: controller
77
newName: akyriako78/typesense-operator
8-
newTag: 0.1.0
8+
newTag: 0.2.7-dev.1

config/samples/ts_v1alpha1_typesensecluster_kind.yaml

+10
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@ spec:
2626
ingressClassName: nginx
2727
clusterIssuer: lets-encrypt-prod
2828
---
29+
apiVersion: v1
30+
kind: ConfigMap
31+
metadata:
32+
name: c-kind-2-config
33+
data:
34+
TYPESENSE_ENABLE_SEARCH_ANALYTICS: "true"
35+
TYPESENSE_ENABLE_CORS: "true"
36+
---
2937
apiVersion: ts.opentelekomcloud.com/v1alpha1
3038
kind: TypesenseCluster
3139
metadata:
@@ -36,6 +44,8 @@ metadata:
3644
spec:
3745
image: typesense/typesense:26.0
3846
replicas: 1
47+
additionalServerConfiguration:
48+
name: c-kind-2-config
3949
storage:
4050
storageClassName: typesense-local-path
4151
ingress:

0 commit comments

Comments
 (0)