Skip to content

Commit 8453618

Browse files
committed
provide a basic operator v1 API
1 parent 602ca28 commit 8453618

File tree

8 files changed

+288
-2
lines changed

8 files changed

+288
-2
lines changed

config/v1/register.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ func addKnownTypes(scheme *runtime.Scheme) error {
3838
&ConsoleList{},
3939
&DNS{},
4040
&DNSList{},
41+
&GenericControllerConfig{},
4142
&IdentityProvider{},
4243
&IdentityProviderList{},
4344
&Image{},

config/v1/types.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,3 +244,33 @@ type ClientConnectionOverrides struct {
244244
// burst allows extra queries to accumulate when a client is exceeding its rate.
245245
Burst int32 `json:"burst"`
246246
}
247+
248+
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
249+
250+
// GenericControllerConfig provides information to configure a controller
251+
type GenericControllerConfig struct {
252+
metav1.TypeMeta `json:",inline"`
253+
254+
// ServingInfo is the HTTP serving information for the controller's endpoints
255+
ServingInfo HTTPServingInfo `json:"servingInfo,omitempty"`
256+
257+
// leaderElection provides information to elect a leader. Only override this if you have a specific need
258+
LeaderElection LeaderElection `json:"leaderElection,omitempty"`
259+
260+
// authentication allows configuration of authentication for the endpoints
261+
Authentication DelegatedAuthentication `json:"authentication,omitempty"`
262+
// authorization allows configuration of authentication for the endpoints
263+
Authorization DelegatedAuthorization `json:"authorization,omitempty"`
264+
}
265+
266+
// DelegatedAuthentication allows authentication to be disabled.
267+
type DelegatedAuthentication struct {
268+
// disabled indicates that authentication should be disabled. By default it will use delegated authentication.
269+
Disabled bool `json:"disabled,omitempty"`
270+
}
271+
272+
// DelegatedAuthorization allows authorization to be disabled.
273+
type DelegatedAuthorization struct {
274+
// disabled indicates that authorization should be disabled. By default it will use delegated authorization.
275+
Disabled bool `json:"disabled,omitempty"`
276+
}

hack/lib/init.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ legacyconfig/v1 \
2020
network/v1 \
2121
oauth/v1 \
2222
openshiftcontrolplane/v1 \
23+
operator/v1 \
2324
operator/v1alpha1 \
2425
project/v1 \
2526
quota/v1 \

hack/update-deepcopy.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@ verify="${VERIFY:-}"
1010
${CODEGEN_PKG}/generate-groups.sh "deepcopy" \
1111
github.com/openshift/api/generated \
1212
github.com/openshift/api \
13-
"apps:v1 authorization:v1 build:v1 config:v1 image:v1,docker10,dockerpre012 kubecontrolplane:v1 legacyconfig:v1 network:v1 oauth:v1 openshiftcontrolplane:v1 operator:v1alpha1 osin:v1 project:v1 quota:v1 route:v1 security:v1 servicecertsigner:v1alpha1 template:v1 user:v1 webconsole:v1" \
13+
"apps:v1 authorization:v1 build:v1 config:v1 image:v1,docker10,dockerpre012 kubecontrolplane:v1 legacyconfig:v1 network:v1 oauth:v1 openshiftcontrolplane:v1 operator:v1 operator:v1alpha1 osin:v1 project:v1 quota:v1 route:v1 security:v1 servicecertsigner:v1alpha1 template:v1 user:v1 webconsole:v1" \
1414
--go-header-file ${SCRIPT_ROOT}/hack/empty.txt \
1515
${verify}

operator/install.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"k8s.io/apimachinery/pkg/runtime"
55
"k8s.io/apimachinery/pkg/runtime/schema"
66

7+
operatorv1 "github.com/openshift/api/operator/v1"
78
operatorv1alpha1 "github.com/openshift/api/operator/v1alpha1"
89
)
910

@@ -12,7 +13,7 @@ const (
1213
)
1314

1415
var (
15-
schemeBuilder = runtime.NewSchemeBuilder(operatorv1alpha1.Install)
16+
schemeBuilder = runtime.NewSchemeBuilder(operatorv1alpha1.Install, operatorv1.Install)
1617
// Install is a function which adds every version of this group to a scheme
1718
Install = schemeBuilder.AddToScheme
1819
)

operator/v1/doc.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// +k8s:deepcopy-gen=package,register
2+
// +k8s:defaulter-gen=TypeMeta
3+
// +k8s:openapi-gen=true
4+
5+
// +groupName=operator.openshift.io
6+
package v1

operator/v1/register.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package v1
2+
3+
import (
4+
configv1 "github.com/openshift/api/config/v1"
5+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
6+
"k8s.io/apimachinery/pkg/runtime"
7+
"k8s.io/apimachinery/pkg/runtime/schema"
8+
)
9+
10+
var (
11+
GroupName = "operator.openshift.io"
12+
GroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha1"}
13+
schemeBuilder = runtime.NewSchemeBuilder(addKnownTypes, configv1.Install)
14+
// Install is a function which adds this version to a scheme
15+
Install = schemeBuilder.AddToScheme
16+
17+
// SchemeGroupVersion generated code relies on this name
18+
// Deprecated
19+
SchemeGroupVersion = GroupVersion
20+
// AddToScheme exists solely to keep the old generators creating valid code
21+
// DEPRECATED
22+
AddToScheme = schemeBuilder.AddToScheme
23+
)
24+
25+
// Resource generated code relies on this being here, but it logically belongs to the group
26+
// DEPRECATED
27+
func Resource(resource string) schema.GroupResource {
28+
return schema.GroupResource{Group: GroupName, Resource: resource}
29+
}
30+
31+
func addKnownTypes(scheme *runtime.Scheme) error {
32+
metav1.AddToGroupVersion(scheme, GroupVersion)
33+
34+
scheme.AddKnownTypes(GroupVersion)
35+
36+
return nil
37+
}

operator/v1/types.go

Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
package v1
2+
3+
import (
4+
corev1 "k8s.io/api/core/v1"
5+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
6+
runtime "k8s.io/apimachinery/pkg/runtime"
7+
)
8+
9+
// MyOperatorResource is an example operator configuration type
10+
type MyOperatorResource struct {
11+
metav1.TypeMeta `json:",inline"`
12+
metav1.ObjectMeta `json:"metadata"`
13+
14+
Spec MyOperatorResourceSpec `json:"spec"`
15+
Status MyOperatorResourceStatus `json:"status"`
16+
}
17+
18+
type MyOperatorResourceSpec struct {
19+
OperatorSpec `json:",inline"`
20+
}
21+
22+
type MyOperatorResourceStatus struct {
23+
OperatorStatus `json:",inline"`
24+
}
25+
26+
type ManagementState string
27+
28+
var (
29+
// Force means that the operator is actively managing its resources and ignoring unmet prereqs
30+
Force ManagementState = "Force"
31+
// Managed means that the operator is actively managing its resources and trying to keep the component active
32+
Managed ManagementState = "Managed"
33+
// Unmanaged means that the operator is not taking any action related to the component
34+
Unmanaged ManagementState = "Unmanaged"
35+
// Removed means that the operator is actively managing its resources and trying to remove all traces of the component
36+
Removed ManagementState = "Removed"
37+
)
38+
39+
// OperatorSpec contains common fields for an operator to need. It is intended to be anonymous included
40+
// inside of the Spec struct for you particular operator.
41+
type OperatorSpec struct {
42+
// managementState indicates whether and how the operator should manage the component
43+
ManagementState ManagementState `json:"managementState"`
44+
45+
// operandSpecs provide information about customization for particular units
46+
OperandSpecs []OperandSpec `json:"operandSpecs"`
47+
48+
// unsupportedConfigOverrides holds a sparse config that will override any previously set options. It only needs to be the fields to override
49+
// it will end up overlaying in the following order:
50+
// 1. hardcoded defaults
51+
// 2. observedConfig
52+
// 3. unsupportedConfigOverrides
53+
UnsupportedConfigOverrides runtime.RawExtension `json:"unsupportedConfigOverrides"`
54+
55+
// observedConfig holds a sparse config that controller has observed from the cluster state. It exists in spec because
56+
// it is an input to the level for the operator
57+
ObservedConfig runtime.RawExtension `json:"observedConfig"`
58+
}
59+
60+
// ResourcePatch is a way to represent the patch you would issue to `kubectl patch` in the API
61+
type ResourcePatch struct {
62+
// type is the type of patch to apply: jsonmerge, strategicmerge
63+
Type string `json:"type"`
64+
// patch the patch itself
65+
Patch string `json:"patch"`
66+
}
67+
68+
// OperandSpec holds information for customatization of a particular unit (logical pod)
69+
type OperandSpec struct {
70+
// name is the name of this unit. The operator must be aware of it.
71+
Name string `json:"name"`
72+
73+
// operandContainerSpecs are per-container options
74+
OperandContainerSpecs []OperandContainerSpec `json:"operandContainerSpecs"`
75+
76+
// Alternatively, we could simply include a RawExtension which is used in place of the "normal" default manifest
77+
UnsupportedResourcePatches []ResourcePatch `json:"unsupportedResourcePatches"`
78+
}
79+
80+
type OperandContainerSpec struct {
81+
// name is the name of the container to modify
82+
Name string `json:"name"`
83+
84+
// resources are the requests and limits to place in the container. Nil means to accept the defaults.
85+
Resources *corev1.ResourceRequirements `json:"resources,omitempty"`
86+
87+
// logging contains parameters for setting log values on the operand. Nil means to accept the defaults.
88+
Logging LoggingConfig `json:"logging,omitempty"`
89+
}
90+
91+
// LoggingConfig holds information about configuring logging
92+
type LoggingConfig struct {
93+
Type string `json:"type"`
94+
95+
Glog *GlogConfig `json:"glog,omitempty"`
96+
CapnsLog *CapnsLogConfig `json:"capnsLog,omitempty"`
97+
Java *JavaLog `json:"java,omitempty"`
98+
}
99+
100+
// GlogConfig holds information about configuring logging
101+
type GlogConfig struct {
102+
// level is passed to glog.
103+
Level int64 `json:"level"`
104+
105+
// vmodule is passed to glog.
106+
Vmodule string `json:"vmodule"`
107+
}
108+
109+
type CapnsLogConfig struct {
110+
// level is passed to capnslog: critical, error, warning, notice, info, debug, trace
111+
Level string `json:"level"`
112+
113+
// There is some kind of repo/package level thing for this
114+
}
115+
116+
type JavaLog struct {
117+
// level is passed to jsr47: fatal, error, warning, info, fine, finer, finest
118+
Level string `json:"level"`
119+
120+
// There is some kind of repo/package level thing for this. might end up hierarchical
121+
}
122+
123+
type OperatorStatus struct {
124+
// conditions is a list of conditions and their status
125+
Conditions []OperatorCondition `json:"conditions,omitempty"`
126+
127+
// version is the level this availability applies to
128+
Version string `json:"version"`
129+
130+
// readyReplicas indicates how many replicas are ready and at the desired state
131+
ReadyReplicas int32 `json:"readyReplicas"`
132+
133+
// generations are used to determine when an item needs to be reconciled or has changed in a way that needs a reaction.
134+
Generations []GenerationStatus `json:"generations"`
135+
}
136+
137+
// GenerationStatus keeps track of the generation for a given resource so that decisions about forced updated can be made.
138+
type GenerationStatus struct {
139+
// group is the group of the thing you're tracking
140+
Group string `json:"group"`
141+
// resource is the resource type of the thing you're tracking
142+
Resource string `json:"resource"`
143+
// namespace is where the thing you're tracking is
144+
Namespace string `json:"namespace"`
145+
// name is the name of the thing you're tracking
146+
Name string `json:"name"`
147+
// lastGeneration is the last generation of the workload controller involved
148+
LastGeneration int64 `json:"lastGeneration"`
149+
// hash is an optional field set for resources without generation that are content sensitive like secrets and configmaps
150+
Hash string `json:"hash"`
151+
}
152+
153+
var (
154+
// Available indicates that the operand is present and accessible in the cluster
155+
OperatorStatusTypeAvailable = "Available"
156+
// Progressing indicates that the operator is trying to transition the operand to a different state
157+
OperatorStatusTypeProgressing = "Progressing"
158+
// Failing indicates that the operator (not the operand) is unable to fulfill the user intent
159+
OperatorStatusTypeFailing = "Failing"
160+
// PrereqsSatisfied indicates that the things this operator depends on are present and at levels compatible with the
161+
// current and desired states.
162+
OperatorStatusTypePrereqsSatisfied = "PrereqsSatisfied"
163+
// Upgradeable indicates that the operator configuration itself (not prereqs) can be auto-upgraded by the CVO
164+
OperatorStatusTypeUpgradeable = "Upgradeable"
165+
)
166+
167+
// OperatorCondition is just the standard condition fields.
168+
type OperatorCondition struct {
169+
Type string `json:"type"`
170+
Status ConditionStatus `json:"status"`
171+
LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty"`
172+
Reason string `json:"reason,omitempty"`
173+
Message string `json:"message,omitempty"`
174+
}
175+
176+
type ConditionStatus string
177+
178+
const (
179+
ConditionTrue ConditionStatus = "True"
180+
ConditionFalse ConditionStatus = "False"
181+
ConditionUnknown ConditionStatus = "Unknown"
182+
)
183+
184+
// StaticPodOperatorStatus is status for controllers that manage static pods. There are different needs because individual
185+
// node status must be tracked.
186+
type StaticPodOperatorStatus struct {
187+
OperatorStatus `json:",inline"`
188+
189+
// latestAvailableDeploymentGeneration is the deploymentID of the most recent deployment
190+
LatestAvailableDeploymentGeneration int32 `json:"latestAvailableDeploymentGeneration"`
191+
192+
// nodeStatuses track the deployment values and errors across individual nodes
193+
NodeStatuses []NodeStatus `json:"nodeStatuses"`
194+
}
195+
196+
// NodeStatus provides information about the current state of a particular node managed by this operator.
197+
type NodeStatus struct {
198+
// nodeName is the name of the node
199+
NodeName string `json:"nodeName"`
200+
201+
// currentDeploymentGeneration is the generation of the most recently successful deployment
202+
CurrentDeploymentGeneration int32 `json:"currentDeploymentGeneration"`
203+
// targetDeploymentGeneration is the generation of the deployment we're trying to apply
204+
TargetDeploymentGeneration int32 `json:"targetDeploymentGeneration"`
205+
// lastFailedDeploymentGeneration is the generation of the deployment we tried and failed to deploy.
206+
LastFailedDeploymentGeneration int32 `json:"lastFailedDeploymentGeneration"`
207+
208+
// lastFailedDeploymentGenerationErrors is a list of the errors during the failed deployment referenced in lastFailedDeploymentGeneration
209+
LastFailedDeploymentErrors []string `json:"lastFailedDeploymentErrors"`
210+
}

0 commit comments

Comments
 (0)