Skip to content
......@@ -3,8 +3,9 @@ module k8s.libre.sh
go 1.13
require (
github.com/golangci/golangci-lint v1.27.0 // indirect
github.com/onsi/ginkgo v1.12.0
github.com/onsi/gomega v1.8.1
github.com/onsi/gomega v1.9.0
github.com/presslabs/controller-util v0.2.2
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 // indirect
k8s.io/api v0.18.1
......
This diff is collapsed.
package instance
import (
"github.com/presslabs/controller-util/syncer"
"k8s.io/apimachinery/pkg/labels"
interfaces "k8s.libre.sh/interfaces"
meta "k8s.libre.sh/meta"
)
type Instance interface {
Meta
GetComponents() map[int]Component
GetOwner() interfaces.Object
GetSettings() Settings
}
type Meta interface {
meta.Meta
GetApplication() string
SetApplication(string)
GetInstance() string
SetInstance(string)
GetVersion() string
SetVersion(string)
GetComponent() string
SetComponent(string)
GetPartOf() string
SetPartOf(string)
GetManagedBy() string
SetManagedBy(string)
}
func InstanceLabels(m Meta) map[string]string {
labels := labels.Set{
"app.kubernetes.io/name": m.GetApplication(),
"app.kubernetes.io/instance": m.GetInstance(),
"app.kubernetes.io/version": m.GetVersion(),
"app.kubernetes.io/component": m.GetComponent(),
"app.kubernetes.io/part-of": m.GetPartOf(),
"app.kubernetes.io/managed-by": m.GetManagedBy(),
}
return labels
}
func NewSyncers(i Instance, r interfaces.Reconcile, owner interfaces.Object) (syncers []syncer.Interface) {
components := i.GetComponents()
for _, c := range components {
mutators := c.GetObjects()
for _, m := range mutators {
syncers = append(syncers, NewObjectSyncer(m, owner, r))
}
}
return syncers
}
/*
Licensed under the Apache License, Version 2.0 (the "License");
Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (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
https://www.gnu.org/licenses/agpl-3.0.html
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
......@@ -25,18 +25,16 @@ import (
// Reconcile is the interface for Reconcile object structs . This
// interface can be used to pass around Reconcile structs commonly
// used in Operators.
// used in Kubebuilder.
//
// Note however that by default Reconcile structs generated using
// Operator SDK do not implement this interface. Add following
// Kubebuilder do not implement this interface. Add following
// functions to implement this interface.
//
// func (r *ReconcileObject) GetClient() client.Client { return r.client }
// func (r *ReconcileObject) GetScheme() *runtime.Scheme { return r.scheme }
// func (r *ReconcileObject) GetScheme() *runtime.Recorder { return r.recorder }
//
// The Reconcile object structs must implement this interface to use
// Operatorlib functions.
type Reconcile interface {
// Getter function for reconcile client
GetClient() client.Client
......
/*
Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.gnu.org/licenses/agpl-3.0.html
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 meta
import (
"fmt"
"k8s.io/apimachinery/pkg/labels"
)
// TODO remove meta in interface, not needed
// Instance interface can work with the commons app.kubernetes.io labels - https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/#labels
type Instance interface {
Meta
// The name of the application - app.kubernetes.io/name
GetApplication() string
SetApplication(string)
// A unique name identifying the instance of an application - app.kubernetes.io/instance
GetInstance() string
SetInstance(string)
// The current version of the application (e.g., a semantic version, revision hash, etc.) - app.kubernetes.io/version
GetVersion() string
SetVersion(string)
// The component within the architecture - app.kubernetes.io/component
GetComponent() string
SetComponent(string)
// The name of a higher level application this one is part of - app.kubernetes.io/part-of
GetPartOf() string
SetPartOf(string)
// The tool being used to manage the operation of an application - app.kubernetes.io/managed-by
GetManagedBy() string
SetManagedBy(string)
}
// Instance labels returns the app.kubernetes.io labels
func InstanceLabels(m Instance) map[string]string {
labels := labels.Set{
"app.kubernetes.io/name": m.GetApplication(),
"app.kubernetes.io/instance": m.GetInstance(),
"app.kubernetes.io/version": m.GetVersion(),
"app.kubernetes.io/component": m.GetComponent(),
"app.kubernetes.io/part-of": m.GetPartOf(),
"app.kubernetes.io/managed-by": m.GetManagedBy(),
}
return labels
}
// TODO use Object interface and rename Merge ?
func SetObjectMeta(src Instance, dest Instance) {
dest.SetLabels(labels.Merge(dest.GetLabels(), InstanceLabels(src)))
if len(dest.GetName()) == 0 {
dest.SetName(fmt.Sprintf("%v-%v", src.GetInstance(), dest.GetComponent()))
}
if len(dest.GetNamespace()) == 0 {
dest.SetNamespace(src.GetNamespace())
}
}
/*
Licensed under the Apache License, Version 2.0 (the "License");
Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (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
https://www.gnu.org/licenses/agpl-3.0.html
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
......@@ -16,68 +16,31 @@ limitations under the License.
package meta
import (
"k8s.io/apimachinery/pkg/labels"
interfaces "k8s.libre.sh/interfaces"
)
// Meta interface is a stripped down version of https://godoc.org/k8s.io/apimachinery/pkg/apis/meta/v1#Object with
// only user definied specs.
//
// To mutates an object a type must implements this interface
type Meta interface {
GetLabels() map[string]string
SetLabels(labels map[string]string)
GetAnnotations() map[string]string
SetAnnotations(annotations map[string]string)
GetName() string
SetName(string)
GetNamespace() string
SetNamespace(string)
}
type Labels map[string]string
/* func (l *Labels) GetApplication() string { return *l["app.kubernetes.io/name"] }
func (l *Labels) SetApplication(s string) { *l["app.kubernetes.io/name"] = s }
func (l *Labels) GetInstance() string { return *l["app.kubernetes.io/instance"] }
func (l *Labels) SetInstance(s string) { *l["app.kubernetes.io/instance"] = s }
func (l *Labels) GetVersion() string { return *l["app.kubernetes.io/version"] }
func (l *Labels) SetVersion(s string) { *l["app.kubernetes.io/version"] = s }
func (l *Labels) GetComponent() string { return *l["app.kubernetes.io/component"] }
func (l *Labels) SetComponent(s string) { *l["app.kubernetes.io/component"] = s }
func (l *Labels) GetPartOf() string { return *l["app.kubernetes.io/part-of"] }
func (l *Labels) SetPartOf(s string) { *l["app.kubernetes.io/part-of"] = s }
func (l *Labels) GetManagedBy() string { *l["app.kubernetes.io/managed-by"] }
func (l *Labels) SetManagedBy(s string) { *l["app.kubernetes.io/managed-by"] = s }
*/
type Application interface {
GetApplication() string
SetApplication(string)
GetInstance() string
SetInstance(string)
GetVersion() string
SetVersion(string)
GetComponent() string
SetComponent(string)
GetPartOf() string
SetPartOf(string)
GetManagedBy() string
SetManagedBy(string)
}
// MutateMeta mutates an Object meta
func MutateMeta(o Meta, obj interfaces.Object) error {
obj.SetLabels(o.GetLabels())
if len(obj.GetName()) == 0 {
obj.SetName(o.GetName())
}
if len(obj.GetNamespace()) == 0 {
obj.SetNamespace(o.GetNamespace())
if len(o.GetAnnotations()) > 0 {
obj.SetAnnotations(labels.Merge(obj.GetAnnotations(), o.GetAnnotations()))
}
return nil
......
/*
Licensed under the Apache License, Version 2.0 (the "License");
Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (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
https://www.gnu.org/licenses/agpl-3.0.html
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
......@@ -15,17 +15,50 @@ limitations under the License.
package meta
import "fmt"
// ObjectMeta meta is a stripped down version of the ObjectMeta type https://godoc.org/k8s.io/apimachinery/pkg/apis/meta/v1#ObjectMeta
// with only user defined specs
//
// This type can be used in an application CRD
// ObjectMeta implements the Meta interface and can be used to mutates an object
//
// +kubebuilder:object:generate=true
type ObjectMeta struct {
Name string `json:"name,omitempty"`
Namespace string `json:"namespace,omitempty"`
Labels map[string]string `json:"labels,omitempty"`
// Name must be unique within a namespace. Is required when creating resources, although
// some resources may allow a client to request the generation of an appropriate name
// automatically. Name is primarily intended for creation idempotence and configuration
// definition.
// Cannot be updated.
// More info: http://kubernetes.io/docs/user-guide/identifiers#names
// +optional
Name string `json:"name,omitempty"`
// Namespace defines the space within each name must be unique. An empty namespace is
// equivalent to the "default" namespace, but "default" is the canonical representation.
// Not all objects are required to be scoped to a namespace - the value of this field for
// those objects will be empty.
//
// Must be a DNS_LABEL.
// Cannot be updated.
// More info: http://kubernetes.io/docs/user-guide/namespaces
// +optional
Namespace string `json:"namespace,omitempty"`
// Map of string keys and values that can be used to organize and categorize
// (scope and select) objects. May match selectors of replication controllers
// and services.
// More info: http://kubernetes.io/docs/user-guide/labels
// +optional
Labels map[string]string `json:"labels,omitempty"`
// Annotations is an unstructured key value map stored with a resource that may be
// set by external tools to store and retrieve arbitrary metadata. They are not
// queryable and should be preserved when modifying objects.
// More info: http://kubernetes.io/docs/user-guide/annotations
// +optional
Annotations map[string]string `json:"annotations,omitempty"`
Finalizers map[string]string `json:"finalizers,omitempty"`
}
// SetLabels sets the ObjectMeta labels
func (c *ObjectMeta) SetLabels(labels map[string]string) {
if len(c.Labels) == 0 {
c.Labels = make(map[string]string)
......@@ -39,56 +72,70 @@ func (c *ObjectMeta) SetLabels(labels map[string]string) {
}
}
// SetAnnotations sets the ObjectMeta annotations
func (c *ObjectMeta) SetAnnotations(annotations map[string]string) {
if len(c.Annotations) == 0 {
c.Annotations = make(map[string]string)
}
if len(annotations) > 0 {
for k, v := range annotations {
if len(c.Annotations[k]) == 0 {
c.Annotations[k] = v
}
}
}
}
// GetLabels returns the ObjectMeta labels
func (c *ObjectMeta) GetLabels() map[string]string { return c.Labels }
// GetAnnotations returns the Annotations labels
func (c *ObjectMeta) GetAnnotations() map[string]string { return c.Annotations }
func (c *ObjectMeta) GetFinalizers() map[string]string { return c.Finalizers }
// GetName returns the ObjectMeta name
func (o *ObjectMeta) GetName() string { return o.Name }
// SetName sets the ObjectMeta name
func (o *ObjectMeta) SetName(name string) { o.Name = name }
// GetNamespace returns the ObjectMeta namespace
func (o *ObjectMeta) GetNamespace() string { return o.Namespace }
// SetNamespace sets the ObjectMeta namespace
func (o *ObjectMeta) SetNamespace(namespace string) { o.Namespace = namespace }
// GetApplication returns the ObjectMeta application name from the app.kubernetes.io/name label
func (c *ObjectMeta) GetApplication() string { return c.Labels["app.kubernetes.io/name"] }
// SetApplication sets the ObjectMeta application name from the app.kubernetes.io/name label
func (c *ObjectMeta) SetApplication(s string) { c.Labels["app.kubernetes.io/name"] = s }
// GetInstance returns the ObjectMeta application name from the app.kubernetes.io/instance label
func (c *ObjectMeta) GetInstance() string { return c.Labels["app.kubernetes.io/instance"] }
// SetInstance sets the ObjectMeta application name from the app.kubernetes.io/instance label
func (c *ObjectMeta) SetInstance(s string) { c.Labels["app.kubernetes.io/instance"] = s }
// GetVersion returns the ObjectMeta application name from the app.kubernetes.io/version label
func (c *ObjectMeta) GetVersion() string { return c.Labels["app.kubernetes.io/version"] }
// SetVersion sets the ObjectMeta application name from the app.kubernetes.io/version label
func (c *ObjectMeta) SetVersion(s string) { c.Labels["app.kubernetes.io/version"] = s }
// GetComponent returns the ObjectMeta application name from the app.kubernetes.io/component label
func (c *ObjectMeta) GetComponent() string { return c.Labels["app.kubernetes.io/component"] }
// SetComponent sets the ObjectMeta application name from the app.kubernetes.io/component label
func (c *ObjectMeta) SetComponent(s string) { c.Labels["app.kubernetes.io/component"] = s }
// GetPartOf returns the ObjectMeta application name from the app.kubernetes.io/part-of label
func (c *ObjectMeta) GetPartOf() string { return c.Labels["app.kubernetes.io/part-of"] }
// SetPartOf sets the ObjectMeta application name from the app.kubernetes.io/part-of label
func (c *ObjectMeta) SetPartOf(s string) { c.Labels["app.kubernetes.io/part-of"] = s }
// GetManagedBy returns the ObjectMeta application name from the app.kubernetes.io/managed-by label
func (c *ObjectMeta) GetManagedBy() string { return c.Labels["app.kubernetes.io/managed-by"] }
// SetManagedBy sets the ObjectMeta application name from the app.kubernetes.io/managed-by label
func (c *ObjectMeta) SetManagedBy(s string) { c.Labels["app.kubernetes.io/managed-by"] = s }
func Init(om *ObjectMeta) {
if om == nil {
om = new(ObjectMeta)
}
if len(om.Labels) == 0 {
om.Labels = make(map[string]string)
}
fmt.Println(om)
}
func New() *ObjectMeta {
om := new(ObjectMeta)
om.Labels = make(map[string]string)
return om
}
......@@ -38,13 +38,6 @@ func (in *ObjectMeta) DeepCopyInto(out *ObjectMeta) {
(*out)[key] = val
}
}
if in.Finalizers != nil {
in, out := &in.Finalizers, &out.Finalizers
*out = make(map[string]string, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObjectMeta.
......
/*
Licensed under the Apache License, Version 2.0 (the "License");
Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (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
https://www.gnu.org/licenses/agpl-3.0.html
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
......@@ -29,14 +29,17 @@ func MutateConfigMap(r Mutate, obj *corev1.ConfigMap, m meta.Meta) error {
data := r.GetData()
if len(obj.Data) == 0 {
obj.Data = make(map[string]string)
obj.Data = make(map[string]string, len(data))
}
if len(data) > 0 {
// TODO TO FIX data won't be removed if parameter removed
/* if len(data) > 0 {
for k, v := range data {
obj.Data[k] = v
}
}
} */
obj.Data = data
meta.MutateMeta(m, obj)
......
/*
Licensed under the Apache License, Version 2.0 (the "License");
Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (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
https://www.gnu.org/licenses/agpl-3.0.html
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
......@@ -16,9 +16,9 @@ limitations under the License.
package configmap
import (
parameters "k8s.libre.sh/application/settings/parameters"
interfaces "k8s.libre.sh/interfaces"
meta "k8s.libre.sh/meta"
parameters "k8s.libre.sh/settings"
corev1 "k8s.io/api/core/v1"
)
......
......@@ -20,8 +20,8 @@ limitations under the License.
package configmap
import (
"k8s.libre.sh/application/settings/parameters"
"k8s.libre.sh/meta"
"k8s.libre.sh/settings"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
......@@ -34,11 +34,11 @@ func (in *ConfigMap) DeepCopyInto(out *ConfigMap) {
}
if in.Parameters != nil {
in, out := &in.Parameters, &out.Parameters
*out = make(settings.Parameters, len(*in))
*out = make(parameters.Parameters, len(*in))
for i := range *in {
if (*in)[i] != nil {
in, out := &(*in)[i], &(*out)[i]
*out = new(settings.Parameter)
*out = new(parameters.Parameter)
**out = **in
}
}
......
/*
Licensed under the Apache License, Version 2.0 (the "License");
Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (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
https://www.gnu.org/licenses/agpl-3.0.html
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
......@@ -23,8 +23,7 @@ type Mutate interface {
// Parameters
// GetVolumeMount() []corev1.VolumeMount
GetEnvFrom() []corev1.EnvFromSource
GetEnv() []corev1.EnvVar
// GetParameters() parameters.Parameters
GetEnvVar() []corev1.EnvVar
// Runtime
GetContainerName() string
GetContainerImage() string
......@@ -45,7 +44,7 @@ func MutateContainer(r Mutate, obj *corev1.Container) error {
obj.Args = r.GetContainerArgs()
obj.EnvFrom = r.GetEnvFrom()
obj.Env = r.GetEnv()
obj.Env = r.GetEnvVar()
// obj.VolumeMounts = r.GetVolumeMount()
......
/*
Licensed under the Apache License, Version 2.0 (the "License");
Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (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
https://www.gnu.org/licenses/agpl-3.0.html
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
......@@ -17,45 +17,89 @@ package container
import (
corev1 "k8s.io/api/core/v1"
parameters "k8s.libre.sh/settings"
parameters "k8s.libre.sh/application/settings"
)
// Container is the specification of the desired behavior of the Container.
// It is a stripped down version of https://godoc.org/k8s.io/api/core/v1#Container
// with only user definied specs
//
// Parameters are used to define how settings are passed on to the container.
//
// +kubebuilder:object:generate=true
type Container struct {
*TemplateSpec `json:",inline"`
parameters.Settings `json:"parameters,omitempty"`
*ContainerSpec `json:",inline"`
*parameters.ConfigSpec `json:"parameters,omitempty"`
}
// +kubebuilder:object:generate=true
type TemplateSpec struct {
Name string `json:"name,omitempty"`
Args []string `json:"args,omitempty"`
Image string `json:"image,omitempty"`
ImagePullPolicy corev1.PullPolicy `json:"imagePullPolicy,omitempty"`
ImagePullSecrets []corev1.LocalObjectReference `json:"imagePullSecrets,omitempty"`
Ports []corev1.ContainerPort `json:"ports,omitempty"`
Probes `json:"inline,omitempty"`
type ContainerSpec struct {
// Name of the container specified as a DNS_LABEL.
// Each container in a pod must have a unique name (DNS_LABEL).
// Cannot be updated.
Name string `json:"name,omitempty"`
// Docker image name.
// More info: https://kubernetes.io/docs/concepts/containers/images
// This field is optional to allow higher level config management to default or override
// container images in workload controllers like Deployments and StatefulSets.
// +optional
Image string `json:"image,omitempty"`
// Arguments to the entrypoint.
// The docker image's CMD is used if this is not provided.
// Variable references $(VAR_NAME) are expanded using the container's environment. If a variable
// cannot be resolved, the reference in the input string will be unchanged. The $(VAR_NAME) syntax
// can be escaped with a double $$, ie: $$(VAR_NAME). Escaped references will never be expanded,
// regardless of whether the variable exists or not.
// Cannot be updated.
// More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell
// +optional
Args []string `json:"args,omitempty"`
// List of ports to expose from the container. Exposing a port here gives
// the system additional information about the network connections a
// container uses, but is primarily informational. Not specifying a port here
// DOES NOT prevent that port from being exposed. Any port which is
// listening on the default "0.0.0.0" address inside a container will be
// accessible from the network.
// Cannot be updated.
// +optional
// +patchMergeKey=containerPort
// +patchStrategy=merge
// +listType=map
// +listMapKey=containerPort
// +listMapKey=protocol
Ports []corev1.ContainerPort `json:"ports,omitempty"`
// Image pull policy.
// One of Always, Never, IfNotPresent.
// Defaults to Always if :latest tag is specified, or IfNotPresent otherwise.
// Cannot be updated.
// More info: https://kubernetes.io/docs/concepts/containers/images#updating-images
// +optional
ImagePullPolicy corev1.PullPolicy `json:"imagePullPolicy,omitempty"`
Probes `json:"inline,omitempty"`
}
// Periodic probe for container health
//
// +kubebuilder:object:generate=true
type Probes struct {
// Periodic probe of container liveness.
// Container will be restarted if the probe fails.
// Cannot be updated.
// More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
// +optional
ReadinessProbe *corev1.Probe `json:"readinessProbe,omitempty" protobuf:"bytes,11,opt,name=readinessProbe"`
LivenessProbe *corev1.Probe `json:"livenessProbe,omitempty" protobuf:"bytes,10,opt,name=livenessProbe"`
// Periodic probe of container liveness.
// Container will be restarted if the probe fails.
// Cannot be updated.
// More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
// +optional
LivenessProbe *corev1.Probe `json:"livenessProbe,omitempty" protobuf:"bytes,10,opt,name=livenessProbe"`
}
func (r *TemplateSpec) GetContainerImage() string { return r.Image }
func (r *TemplateSpec) GetContainerName() string { return r.Name }
func (r *TemplateSpec) GetContainerImagePullPolicy() corev1.PullPolicy { return r.ImagePullPolicy }
func (r *TemplateSpec) GetContainerPorts() []corev1.ContainerPort { return r.Ports }
func (r *TemplateSpec) GetContainerLivenessProbe() *corev1.Probe { return r.LivenessProbe }
func (r *TemplateSpec) GetContainerReadinessProbe() *corev1.Probe { return r.ReadinessProbe }
func (r *TemplateSpec) GetContainerArgs() []string { return r.Args }
// func (r *TemplateSpec) GetParameters() parameters.Parameters { return nil }
//func NewContainer(spec *TemplateSpec, p parameters.Parameters) *Container {
// return &Container{
// Parameters: p,
// TemplateSpec: spec,
// }
//}
func (c *ContainerSpec) GetContainerImage() string { return c.Image }
func (c *ContainerSpec) GetContainerName() string { return c.Name }
func (c *ContainerSpec) GetContainerImagePullPolicy() corev1.PullPolicy { return c.ImagePullPolicy }
func (c *ContainerSpec) GetContainerPorts() []corev1.ContainerPort { return c.Ports }
func (c *ContainerSpec) GetContainerLivenessProbe() *corev1.Probe { return c.LivenessProbe }
func (c *ContainerSpec) GetContainerReadinessProbe() *corev1.Probe { return c.ReadinessProbe }
func (c *ContainerSpec) GetContainerArgs() []string { return c.Args }
......@@ -26,12 +26,15 @@ import (
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Container) DeepCopyInto(out *Container) {
*out = *in
if in.TemplateSpec != nil {
in, out := &in.TemplateSpec, &out.TemplateSpec
*out = new(TemplateSpec)
if in.ContainerSpec != nil {
in, out := &in.ContainerSpec, &out.ContainerSpec
*out = new(ContainerSpec)
(*in).DeepCopyInto(*out)
}
in.Settings.DeepCopyInto(&out.Settings)
if in.ConfigSpec != nil {
in, out := &in.ConfigSpec, &out.ConfigSpec
*out = (*in).DeepCopy()
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Container.
......@@ -45,57 +48,52 @@ func (in *Container) DeepCopy() *Container {
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Probes) DeepCopyInto(out *Probes) {
func (in *ContainerSpec) DeepCopyInto(out *ContainerSpec) {
*out = *in
if in.ReadinessProbe != nil {
in, out := &in.ReadinessProbe, &out.ReadinessProbe
*out = new(v1.Probe)
(*in).DeepCopyInto(*out)
if in.Args != nil {
in, out := &in.Args, &out.Args
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.LivenessProbe != nil {
in, out := &in.LivenessProbe, &out.LivenessProbe
*out = new(v1.Probe)
(*in).DeepCopyInto(*out)
if in.Ports != nil {
in, out := &in.Ports, &out.Ports
*out = make([]v1.ContainerPort, len(*in))
copy(*out, *in)
}
in.Probes.DeepCopyInto(&out.Probes)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Probes.
func (in *Probes) DeepCopy() *Probes {
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerSpec.
func (in *ContainerSpec) DeepCopy() *ContainerSpec {
if in == nil {
return nil
}
out := new(Probes)
out := new(ContainerSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *TemplateSpec) DeepCopyInto(out *TemplateSpec) {
func (in *Probes) DeepCopyInto(out *Probes) {
*out = *in
if in.Args != nil {
in, out := &in.Args, &out.Args
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.ImagePullSecrets != nil {
in, out := &in.ImagePullSecrets, &out.ImagePullSecrets
*out = make([]v1.LocalObjectReference, len(*in))
copy(*out, *in)
if in.ReadinessProbe != nil {
in, out := &in.ReadinessProbe, &out.ReadinessProbe
*out = new(v1.Probe)
(*in).DeepCopyInto(*out)
}
if in.Ports != nil {
in, out := &in.Ports, &out.Ports
*out = make([]v1.ContainerPort, len(*in))
copy(*out, *in)
if in.LivenessProbe != nil {
in, out := &in.LivenessProbe, &out.LivenessProbe
*out = new(v1.Probe)
(*in).DeepCopyInto(*out)
}
in.Probes.DeepCopyInto(&out.Probes)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TemplateSpec.
func (in *TemplateSpec) DeepCopy() *TemplateSpec {
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Probes.
func (in *Probes) DeepCopy() *Probes {
if in == nil {
return nil
}
out := new(TemplateSpec)
out := new(Probes)
in.DeepCopyInto(out)
return out
}
/*
Licensed under the Apache License, Version 2.0 (the "License");
Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (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
https://www.gnu.org/licenses/agpl-3.0.html
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
......@@ -24,53 +24,72 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// Deployment is the specification of the desired behavior of the Deployment.
// It is a stripped down version of https://godoc.org/k8s.io/api/apps/v1#Deployment
// with only user definied specs
//
// +kubebuilder:object:generate=true
type Deployment struct {
// Standard object metadata.
// +optional
*meta.ObjectMeta `json:"meta,omitempty"`
*DeploymentSpec `json:",inline"`
// Specification of the desired behavior of the Deployment.
// +optional
*DeploymentSpec `json:",inline"`
}
// DeploymentSpec is the specification of the desired behavior of the DeploymentSpec.
// It is a stripped down version of https://godoc.org/k8s.io/api/apps/v1#DeploymentSpec
// with only user definied specs
//
// +kubebuilder:object:generate=true
type DeploymentSpec struct {
Replicas *int32 `json:"replicas,omitempty"`
Strategy appsv1.DeploymentStrategy `json:"strategy,omitempty"`
// Number of desired pods. This is a pointer to distinguish between explicit
// zero and not specified. Defaults to 1.
// +optional
Replicas *int32 `json:"replicas,omitempty"`
// The deployment strategy to use to replace existing pods with new ones.
// +optional
// +patchStrategy=retainKeys
Strategy appsv1.DeploymentStrategy `json:"strategy,omitempty"`
// PodSpec describes the pods that will be created.
*pod.PodSpec `json:",inline"`
}
func (r *DeploymentSpec) GetReplicas() *int32 {
return r.Replicas
func (spec *DeploymentSpec) GetReplicas() *int32 {
return spec.Replicas
}
func (r *DeploymentSpec) GetDeploymentStrategy() appsv1.DeploymentStrategy {
return r.Strategy
func (spec *DeploymentSpec) GetDeploymentStrategy() appsv1.DeploymentStrategy {
return spec.Strategy
}
func (o *Deployment) GetObject() interfaces.Object {
return &appsv1.Deployment{}
}
func (w *Deployment) Mutate(obj interfaces.Object) error {
func (o *Deployment) Mutate(obj interfaces.Object) error {
deploy := obj.(*appsv1.Deployment)
w.PodSpec.ObjectMeta = w.ObjectMeta
// TODO TO FIX merge meta
o.PodSpec.ObjectMeta = o.ObjectMeta
MutateDeployment(w, deploy)
err := MutateDeployment(o, deploy)
if err != nil {
return err
}
meta.MutateMeta(w.ObjectMeta, obj)
err = meta.MutateMeta(o.ObjectMeta, obj)
if err != nil {
return err
}
deploy.Spec.Template.ObjectMeta.Name = deploy.ObjectMeta.Name
deploy.Spec.Template.ObjectMeta.Labels = w.ObjectMeta.Labels
deploy.Spec.Template.ObjectMeta.Labels = o.ObjectMeta.Labels
deploy.Spec.Selector = metav1.SetAsLabelSelector(w.ObjectMeta.Labels)
deploy.Spec.Selector = metav1.SetAsLabelSelector(o.ObjectMeta.Labels)
return nil
}
//func NewDeployment(spec *DeploymentSpec, p parameters.Parameters) *Deployment {
// return &Deployment{
// Parameters: p,
// DeploymentSpec: spec,
// }
//}
/*
Licensed under the Apache License, Version 2.0 (the "License");
Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (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
https://www.gnu.org/licenses/agpl-3.0.html
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
......
/*
Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.gnu.org/licenses/agpl-3.0.html
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 ingress
import (
......
/*
Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.gnu.org/licenses/agpl-3.0.html
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 ingress
import (
interfaces "k8s.libre.sh/interfaces"
meta "k8s.libre.sh/meta"
parameters "k8s.libre.sh/settings"
networkingv1beta1 "k8s.io/api/networking/v1beta1"
)
......@@ -31,5 +45,3 @@ func (o *Ingress) Mutate(obj interfaces.Object) error {
func (o *Ingress) GetObject() interfaces.Object {
return &networkingv1beta1.Ingress{}
}
func (o *Ingress) SetSettings(parameters parameters.Parameters) {}
/*
Licensed under the Apache License, Version 2.0 (the "License");
Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (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
https://www.gnu.org/licenses/agpl-3.0.html
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
......@@ -13,36 +13,30 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package instance
// Objects package contains core kubernetes resources definitions that can be included in an application CRD.
// The definitions are stripped down version with only specs that should be user-defined.
//
// Every objects definied in this package implements a mutate interface which can create or update its associated kubernetes resource.
//
// All those objects also implements the Object inteface from which we can create an object syncer - see https://github.com/presslabs/controller-util/syncer
package objects
import (
"fmt"
"k8s.io/apimachinery/pkg/labels"
interfaces "k8s.libre.sh/interfaces"
meta "k8s.libre.sh/meta"
"github.com/presslabs/controller-util/syncer"
)
// Object interface must be supported by all types that want to sync an object.
// The object interface provides a mutate function and a runtime.Object that can be used in controller-runtime CreateOrUpdate
type Object interface {
Meta
meta.Instance
Mutate(obj interfaces.Object) error
GetObject() interfaces.Object
}
func SetObjectMeta(instance Meta, dest Meta) {
dest.SetLabels(labels.Merge(dest.GetLabels(), InstanceLabels(instance)))
if len(dest.GetName()) == 0 {
dest.SetName(fmt.Sprintf("%v-%v", instance.GetInstance(), dest.GetComponent()))
}
if len(dest.GetNamespace()) == 0 {
dest.SetNamespace(instance.GetNamespace())
}
}
// NewObjectSyncer returns a syncer interface from https://github.com/presslabs/controller-util/syncer which can reconcile an object, create events and logs.
func NewObjectSyncer(i Object, owner interfaces.Object, r interfaces.Reconcile) syncer.Interface {
obj := i.GetObject()
obj.SetName(i.GetName())
......
/*
Licensed under the Apache License, Version 2.0 (the "License");
Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (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
https://www.gnu.org/licenses/agpl-3.0.html
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
......@@ -38,7 +38,7 @@ func MutatePod(r Mutate, obj *corev1.PodTemplateSpec) error {
containerList := []corev1.Container{}
obj.Spec.SecurityContext = r.GetPodSecurityContext()
//& obj.Spec.Volumes = r.GetPodVolumes()
// obj.Spec.Volumes = r.GetPodVolumes()
obj.Spec.RestartPolicy = r.GetPodRestartPolicy()
obj.Spec.NodeSelector = r.GetPodNodeSelector()
obj.Spec.Affinity = r.GetPodAffinity()
......@@ -46,24 +46,19 @@ func MutatePod(r Mutate, obj *corev1.PodTemplateSpec) error {
containers := r.GetContainers()
if len(containers) > 0 {
/* MutateContainer(r, container)
containerList = append(containerList, *container)
obj.Spec.Containers = containerList
*/
for k, c := range containers {
if len(obj.Spec.Containers) == 0 {
container.MutateContainer(c, containerSpec)
containerList = append(containerList, *containerSpec)
obj.Spec.Containers = containerList
} else {
// TODO FIX mutate container by name ?
container.MutateContainer(c, &obj.Spec.Containers[k])
}
}
} /* else {
// for k, c := range containers {
// MutateContainer(c, &obj.Spec.Containers[k])
// }
// } */
}
// TODO add init containers
if r.GetPodSecurityContext() != nil {
......