add controllers

change kiali mux to go-restful

add knative
This commit is contained in:
Jeff
2019-03-20 11:12:40 +08:00
committed by zryfish
parent 4c7c837771
commit aa4d07c80a
241 changed files with 53767 additions and 749 deletions

View File

@@ -0,0 +1,179 @@
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (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
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 v1beta1
import (
"github.com/kubernetes-sigs/application/pkg/component"
cr "github.com/kubernetes-sigs/application/pkg/customresource"
"github.com/kubernetes-sigs/application/pkg/finalizer"
"github.com/kubernetes-sigs/application/pkg/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"strings"
)
// Mutate - mutate expected
func (a *Application) Mutate(rsrc interface{}, labels map[string]string, status interface{}, expected, dependent, observed *resource.ObjectBag) (*resource.ObjectBag, error) {
exp := resource.ObjectBag{}
for _, o := range observed.Items() {
o.Lifecycle = resource.LifecycleManaged
exp.Add(o)
}
return &exp, nil
}
// Finalize - execute finalizers
func (a *Application) Finalize(rsrc, sts interface{}, observed *resource.ObjectBag) error {
finalizer.Remove(a, finalizer.Cleanup)
return nil
}
//DependentResources - returns dependent rsrc
func (a *Application) DependentResources(rsrc interface{}) *resource.ObjectBag {
return &resource.ObjectBag{}
}
// ExpectedResources returns the list of resource/name for those resources created by
// the operator for this spec and those resources referenced by this operator.
// Mark resources as owned, referred
func (a *Application) ExpectedResources(rsrc interface{}, rsrclabels map[string]string, dependent, aggregated *resource.ObjectBag) (*resource.ObjectBag, error) {
return &resource.ObjectBag{}, nil
}
// GKVersions returns the gvks for the given gk
func GKVersions(s *runtime.Scheme, mgk metav1.GroupKind) []schema.GroupVersionKind {
gvks := []schema.GroupVersionKind{}
gk := schema.GroupKind{Group: mgk.Group, Kind: mgk.Kind}
for gvk := range s.AllKnownTypes() {
if gk != gvk.GroupKind() {
continue
}
gvks = append(gvks, gvk)
}
return gvks
}
// Observables - return selectors
func (a *Application) Observables(scheme *runtime.Scheme, rsrc interface{}, rsrclabels map[string]string, expected *resource.ObjectBag) []resource.Observable {
var observables []resource.Observable
if a.Spec.Selector == nil || a.Spec.Selector.MatchLabels == nil {
return observables
}
for _, gk := range a.Spec.ComponentGroupKinds {
listGK := gk
if !strings.HasSuffix(listGK.Kind, "List") {
listGK.Kind = listGK.Kind + "List"
}
for _, gvk := range GKVersions(scheme, listGK) {
ol, err := scheme.New(gvk)
if err == nil {
observable := resource.Observable{
ObjList: ol.(metav1.ListInterface),
Labels: a.Spec.Selector.MatchLabels,
}
observables = append(observables, observable)
}
}
}
return observables
}
// Differs returns true if the resource needs to be updated
func (a *Application) Differs(expected metav1.Object, observed metav1.Object) bool {
return false
}
// UpdateComponentStatus use reconciled objects to update component status
func (a *Application) UpdateComponentStatus(rsrci, statusi interface{}, reconciled *resource.ObjectBag, err error) {
if a != nil {
stts := statusi.(*ApplicationStatus)
stts.UpdateStatus(reconciled.Objs(), err)
}
}
// ApplyDefaults default app crd
func (a *Application) ApplyDefaults() {
return
}
// UpdateRsrcStatus records status or error in status
func (a *Application) UpdateRsrcStatus(status interface{}, err error) bool {
appstatus := status.(*ApplicationStatus)
if status != nil {
a.Status = *appstatus
}
if err != nil {
a.Status.SetError("ErrorSeen", err.Error())
} else {
a.Status.ClearError()
}
return true
}
// Validate the Application
func (a *Application) Validate() error {
return nil
}
// Components returns components for this resource
func (a *Application) Components() []component.Component {
c := []component.Component{}
c = append(c, component.Component{
Handle: a,
Name: "app",
CR: a,
OwnerRef: a.OwnerRef(),
})
return c
}
// OwnerRef returns owner ref object with the component's resource as owner
func (a *Application) OwnerRef() *metav1.OwnerReference {
if !a.Spec.AddOwnerRef {
return nil
}
isController := false
gvk := schema.GroupVersionKind{
Group: SchemeGroupVersion.Group,
Version: SchemeGroupVersion.Version,
Kind: "Application",
}
ref := metav1.NewControllerRef(a, gvk)
ref.Controller = &isController
return ref
}
// NewRsrc - return a new resource object
func (a *Application) NewRsrc() cr.Handle {
return &Application{}
}
// NewStatus - return a resource status object
func (a *Application) NewStatus() interface{} {
s := a.Status.DeepCopy()
s.ComponentList = ComponentList{}
return s
}
// StatusDiffers returns True if there is a change in status
func (a *Application) StatusDiffers(new ApplicationStatus) bool {
return true
}

View File

@@ -0,0 +1,326 @@
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (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
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 v1beta1
import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// Constants for condition
const (
// Ready => controller considers this resource Ready
Ready = "Ready"
// Qualified => functionally tested
Qualified = "Qualified"
// Settled => observed generation == generation + settled means controller is done acting functionally tested
Settled = "Settled"
// Cleanup => it is set to track finalizer failures
Cleanup = "Cleanup"
// Error => last recorded error
Error = "Error"
ReasonInit = "Init"
)
// Descriptor defines the Metadata and informations about the Application.
type Descriptor struct {
// Type is the type of the application (e.g. WordPress, MySQL, Cassandra).
Type string `json:"type,omitempty"`
// Version is an optional version indicator for the Application.
Version string `json:"version,omitempty"`
// Description is a brief string description of the Application.
Description string `json:"description,omitempty"`
// Icons is an optional list of icons for an application. Icon information includes the source, size,
// and mime type.
Icons []ImageSpec `json:"icons,omitempty"`
// Maintainers is an optional list of maintainers of the application. The maintainers in this list maintain the
// the source code, images, and package for the application.
Maintainers []ContactData `json:"maintainers,omitempty"`
// Owners is an optional list of the owners of the installed application. The owners of the application should be
// contacted in the event of a planned or unplanned disruption affecting the application.
Owners []ContactData `json:"owners,omitempty"`
// Keywords is an optional list of key words associated with the application (e.g. MySQL, RDBMS, database).
Keywords []string `json:"keywords,omitempty"`
// Links are a list of descriptive URLs intended to be used to surface additional documentation, dashboards, etc.
Links []Link `json:"links,omitempty"`
// Notes contain a human readable snippets intended as a quick start for the users of the Application.
// CommonMark markdown syntax may be used for rich text representation.
Notes string `json:"notes,omitempty"`
}
// ApplicationSpec defines the specification for an Application.
type ApplicationSpec struct {
// ComponentGroupKinds is a list of Kinds for Application's components (e.g. Deployments, Pods, Services, CRDs). It
// can be used in conjunction with the Application's Selector to list or watch the Applications components.
ComponentGroupKinds []metav1.GroupKind `json:"componentKinds,omitempty"`
// Descriptor regroups information and metadata about an application.
Descriptor Descriptor `json:"descriptor,omitempty"`
// Selector is a label query over kinds that created by the application. It must match the component objects' labels.
// More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors
Selector *metav1.LabelSelector `json:"selector,omitempty"`
// AddOwnerRef objects - flag to indicate if we need to add OwnerRefs to matching objects
// Matching is done by using Selector to query all ComponentGroupKinds
AddOwnerRef bool `json:"addOwnerRef,omitempty"`
// Info contains human readable key,value pairs for the Application.
Info []InfoItem `json:"info,omitempty"`
// AssemblyPhase represents the current phase of the application's assembly.
// An empty value is equivalent to "Succeeded".
AssemblyPhase ApplicationAssemblyPhase `json:"assemblyPhase,omitempty"`
}
// ComponentList is a generic status holder for the top level resource
// +k8s:deepcopy-gen=true
type ComponentList struct {
// Object status array for all matching objects
Objects []ObjectStatus `json:"components,omitempty"`
}
// ObjectStatus is a generic status holder for objects
// +k8s:deepcopy-gen=true
type ObjectStatus struct {
// Link to object
Link string `json:"link,omitempty"`
// Name of object
Name string `json:"name,omitempty"`
// Kind of object
Kind string `json:"kind,omitempty"`
// Object group
Group string `json:"group,omitempty"`
// Status. Values: InProgress, Ready, Unknown
Status string `json:"status,omitempty"`
}
// ConditionType encodes information on the condition
type ConditionType string
// Condition describes the state of an object at a certain point.
// +k8s:deepcopy-gen=true
type Condition struct {
// Type of condition.
Type ConditionType `json:"type" protobuf:"bytes,1,opt,name=type,casttype=StatefulSetConditionType"`
// Status of the condition, one of True, False, Unknown.
Status corev1.ConditionStatus `json:"status" protobuf:"bytes,2,opt,name=status,casttype=k8s.io/api/core/v1.ConditionStatus"`
// The reason for the condition's last transition.
// +optional
Reason string `json:"reason,omitempty" protobuf:"bytes,4,opt,name=reason"`
// A human readable message indicating details about the transition.
// +optional
Message string `json:"message,omitempty" protobuf:"bytes,5,opt,name=message"`
// Last time the condition was probed
// +optional
LastUpdateTime metav1.Time `json:"lastUpdateTime,omitempty" protobuf:"bytes,3,opt,name=lastProbeTime"`
// Last time the condition transitioned from one status to another.
// +optional
LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty" protobuf:"bytes,3,opt,name=lastTransitionTime"`
}
// ApplicationStatus defines controller's the observed state of Application
type ApplicationStatus struct {
// ObservedGeneration is the most recent generation observed. It corresponds to the
// Object's generation, which is updated on mutation by the API Server.
// +optional
ObservedGeneration int64 `json:"observedGeneration,omitempty" protobuf:"varint,1,opt,name=observedGeneration"`
// Conditions represents the latest state of the object
// +optional
// +patchMergeKey=type
// +patchStrategy=merge
Conditions []Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,10,rep,name=conditions"`
// Resources embeds a list of object statuses
// +optional
ComponentList `json:",inline,omitempty"`
}
// ImageSpec contains information about an image used as an icon.
type ImageSpec struct {
// The source for image represented as either an absolute URL to the image or a Data URL containing
// the image. Data URLs are defined in RFC 2397.
Source string `json:"src"`
// (optional) The size of the image in pixels (e.g., 25x25).
Size string `json:"size,omitempty"`
// (optional) The mine type of the image (e.g., "image/png").
Type string `json:"type,omitempty"`
}
// ContactData contains information about an individual or organization.
type ContactData struct {
// Name is the descriptive name.
Name string `json:"name,omitempty"`
// Url could typically be a website address.
URL string `json:"url,omitempty"`
// Email is the email address.
Email string `json:"email,omitempty"`
}
// Link contains information about an URL to surface documentation, dashboards, etc.
type Link struct {
// Description is human readable content explaining the purpose of the link.
Description string `json:"description,omitempty"`
// Url typically points at a website address.
URL string `json:"url,omitempty"`
}
// InfoItem is a human readable key,value pair containing important information about how to access the Application.
type InfoItem struct {
// Name is a human readable title for this piece of information.
Name string `json:"name,omitempty"`
// Type of the value for this InfoItem.
Type InfoItemType `json:"type,omitempty"`
// Value is human readable content.
Value string `json:"value,omitempty"`
// ValueFrom defines a reference to derive the value from another source.
ValueFrom *InfoItemSource `json:"valueFrom,omitempty"`
}
// InfoItemType is a string that describes the value of InfoItem
type InfoItemType string
const (
// ValueInfoItemType const string for value type
ValueInfoItemType InfoItemType = "Value"
// ReferenceInfoItemType const string for ref type
ReferenceInfoItemType InfoItemType = "Reference"
)
// InfoItemSource represents a source for the value of an InfoItem.
type InfoItemSource struct {
// Type of source.
Type InfoItemSourceType `json:"type,omitempty"`
// Selects a key of a Secret.
SecretKeyRef *SecretKeySelector `json:"secretKeyRef,omitempty"`
// Selects a key of a ConfigMap.
ConfigMapKeyRef *ConfigMapKeySelector `json:"configMapKeyRef,omitempty"`
// Select a Service.
ServiceRef *ServiceSelector `json:"serviceRef,omitempty"`
// Select an Ingress.
IngressRef *IngressSelector `json:"ingressRef,omitempty"`
}
// InfoItemSourceType is a string
type InfoItemSourceType string
// Constants for info type
const (
SecretKeyRefInfoItemSourceType InfoItemSourceType = "SecretKeyRef"
ConfigMapKeyRefInfoItemSourceType InfoItemSourceType = "ConfigMapKeyRef"
ServiceRefInfoItemSourceType InfoItemSourceType = "ServiceRef"
IngressRefInfoItemSourceType InfoItemSourceType = "IngressRef"
)
// ConfigMapKeySelector selects a key from a ConfigMap.
type ConfigMapKeySelector struct {
// The ConfigMap to select from.
corev1.ObjectReference `json:",inline"`
// The key to select.
Key string `json:"key,omitempty"`
}
// SecretKeySelector selects a key from a Secret.
type SecretKeySelector struct {
// The Secret to select from.
corev1.ObjectReference `json:",inline"`
// The key to select.
Key string `json:"key,omitempty"`
}
// ServiceSelector selects a Service.
type ServiceSelector struct {
// The Service to select from.
corev1.ObjectReference `json:",inline"`
// The optional port to select.
Port *int32 `json:"port,omitempty"`
// The optional HTTP path.
Path string `json:"path,omitempty"`
}
// IngressSelector selects an Ingress.
type IngressSelector struct {
// The Ingress to select from.
corev1.ObjectReference `json:",inline"`
// The optional host to select.
Host string `json:"host,omitempty"`
// The optional HTTP path.
Path string `json:"path,omitempty"`
}
// ApplicationAssemblyPhase tracks the Application CRD phases: pending, succeded, failed
type ApplicationAssemblyPhase string
// Constants
const (
// Used to indicate that not all of application's components
// have been deployed yet.
Pending ApplicationAssemblyPhase = "Pending"
// Used to indicate that all of application's components
// have already been deployed.
Succeeded = "Succeeded"
// Used to indicate that deployment of application's components
// failed. Some components might be present, but deployment of
// the remaining ones will not be re-attempted.
Failed = "Failed"
)
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// Application is the Schema for the applications API
// +k8s:openapi-gen=true
type Application struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec ApplicationSpec `json:"spec,omitempty"`
Status ApplicationStatus `json:"status,omitempty"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// ApplicationList contains a list of Application
type ApplicationList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []Application `json:"items"`
}
func init() {
SchemeBuilder.Register(&Application{}, &ApplicationList{})
}

View File

@@ -0,0 +1,168 @@
/*
Copyright 2018 The Kubernetes Authors
Licensed under the Apache License, Version 2.0 (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
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 v1beta1
import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func (m *ApplicationStatus) addCondition(ctype ConditionType, status corev1.ConditionStatus, reason, message string) {
now := metav1.Now()
c := &Condition{
Type: ctype,
LastUpdateTime: now,
LastTransitionTime: now,
Status: status,
Reason: reason,
Message: message,
}
m.Conditions = append(m.Conditions, *c)
}
// setConditionValue updates or creates a new condition
func (m *ApplicationStatus) setConditionValue(ctype ConditionType, status corev1.ConditionStatus, reason, message string) {
var c *Condition
for i := range m.Conditions {
if m.Conditions[i].Type == ctype {
c = &m.Conditions[i]
}
}
if c == nil {
m.addCondition(ctype, status, reason, message)
} else {
// check message ?
if c.Status == status && c.Reason == reason && c.Message == message {
return
}
now := metav1.Now()
c.LastUpdateTime = now
if c.Status != status {
c.LastTransitionTime = now
}
c.Status = status
c.Reason = reason
c.Message = message
}
}
// RemoveCondition removes the condition with the provided type.
func (m *ApplicationStatus) RemoveCondition(ctype ConditionType) {
for i, c := range m.Conditions {
if c.Type == ctype {
m.Conditions[i] = m.Conditions[len(m.Conditions)-1]
m.Conditions = m.Conditions[:len(m.Conditions)-1]
break
}
}
}
// GetCondition get existing condition
func (m *ApplicationStatus) GetCondition(ctype ConditionType) *Condition {
for i := range m.Conditions {
if m.Conditions[i].Type == ctype {
return &m.Conditions[i]
}
}
return nil
}
// IsConditionTrue - if condition is true
func (m *ApplicationStatus) IsConditionTrue(ctype ConditionType) bool {
if c := m.GetCondition(ctype); c != nil {
return c.Status == corev1.ConditionTrue
}
return false
}
// IsReady returns true if ready condition is set
func (m *ApplicationStatus) IsReady() bool { return m.IsConditionTrue(Ready) }
// IsNotReady returns true if ready condition is set
func (m *ApplicationStatus) IsNotReady() bool { return !m.IsConditionTrue(Ready) }
// ConditionReason - return condition reason
func (m *ApplicationStatus) ConditionReason(ctype ConditionType) string {
if c := m.GetCondition(ctype); c != nil {
return c.Reason
}
return ""
}
// Ready - shortcut to set ready contition to true
func (m *ApplicationStatus) Ready(reason, message string) {
m.SetCondition(Ready, reason, message)
}
// NotReady - shortcut to set ready contition to false
func (m *ApplicationStatus) NotReady(reason, message string) {
m.ClearCondition(Ready, reason, message)
}
// SetError - shortcut to set error condition
func (m *ApplicationStatus) SetError(reason, message string) {
m.SetCondition(Error, reason, message)
}
// ClearError - shortcut to set error condition
func (m *ApplicationStatus) ClearError() {
m.ClearCondition(Error, "NoError", "No error seen")
}
// Settled - shortcut to set Settled contition to true
func (m *ApplicationStatus) Settled(reason, message string) {
m.SetCondition(Settled, reason, message)
}
// NotSettled - shortcut to set Settled contition to false
func (m *ApplicationStatus) NotSettled(reason, message string) {
m.ClearCondition(Settled, reason, message)
}
// EnsureCondition useful for adding default conditions
func (m *ApplicationStatus) EnsureCondition(ctype ConditionType) {
if c := m.GetCondition(ctype); c != nil {
return
}
m.addCondition(ctype, corev1.ConditionUnknown, ReasonInit, "Not Observed")
}
// EnsureStandardConditions - helper to inject standard conditions
func (m *ApplicationStatus) EnsureStandardConditions() {
m.EnsureCondition(Ready)
m.EnsureCondition(Settled)
m.EnsureCondition(Error)
}
// ClearCondition updates or creates a new condition
func (m *ApplicationStatus) ClearCondition(ctype ConditionType, reason, message string) {
m.setConditionValue(ctype, corev1.ConditionFalse, reason, message)
}
// SetCondition updates or creates a new condition
func (m *ApplicationStatus) SetCondition(ctype ConditionType, reason, message string) {
m.setConditionValue(ctype, corev1.ConditionTrue, reason, message)
}
// RemoveAllConditions updates or creates a new condition
func (m *ApplicationStatus) RemoveAllConditions() {
m.Conditions = []Condition{}
}
// ClearAllConditions updates or creates a new condition
func (m *ApplicationStatus) ClearAllConditions() {
for i := range m.Conditions {
m.Conditions[i].Status = corev1.ConditionFalse
}
}

View File

@@ -0,0 +1,23 @@
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (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
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 v1beta1 contains API Schema definitions for the app v1beta1 API group
// +k8s:openapi-gen=true
// +k8s:deepcopy-gen=package,register
// +k8s:conversion-gen=github.com/kubernetes-sigs/application/pkg/apis/app
// +k8s:defaulter-gen=TypeMeta
// +groupName=app.k8s.io
package v1beta1

View File

@@ -0,0 +1,46 @@
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (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
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.
*/
// NOTE: Boilerplate only. Ignore this file.
// Package v1beta1 contains API Schema definitions for the app v1beta1 API group
// +k8s:openapi-gen=true
// +k8s:deepcopy-gen=package,register
// +k8s:conversion-gen=github.com/kubernetes-sigs/application/pkg/apis/app
// +k8s:defaulter-gen=TypeMeta
// +groupName=app.k8s.io
package v1beta1
import (
"k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/controller-runtime/pkg/runtime/scheme"
)
var (
// SchemeGroupVersion is group version used to register these objects
SchemeGroupVersion = schema.GroupVersion{Group: "app.k8s.io", Version: "v1beta1"}
// SchemeBuilder is used to add go types to the GroupVersionKind scheme
SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion}
// AddToScheme is required by pkg/client/...
AddToScheme = SchemeBuilder.AddToScheme
)
// Resource is required by pkg/client/listers/...
func Resource(resource string) schema.GroupResource {
return SchemeGroupVersion.WithResource(resource).GroupResource()
}

View File

@@ -0,0 +1,193 @@
/*
Copyright 2018 The Kubernetes Authors
Licensed under the Apache License, Version 2.0 (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
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 v1beta1
import (
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
policyv1 "k8s.io/api/policy/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
)
// Constants defining labels
const (
StatusReady = "Ready"
StatusInProgress = "InProgress"
StatusDisabled = "Disabled"
)
func (s *ObjectStatus) update(rsrc metav1.Object) {
ro := rsrc.(runtime.Object)
gvk := ro.GetObjectKind().GroupVersionKind()
s.Link = rsrc.GetSelfLink()
s.Name = rsrc.GetName()
s.Group = gvk.GroupVersion().String()
s.Kind = gvk.GroupKind().Kind
s.Status = StatusReady
}
// ResetComponentList - reset component list objects
func (m *ApplicationStatus) ResetComponentList() {
m.ComponentList.Objects = []ObjectStatus{}
}
// UpdateStatus the component status
func (m *ApplicationStatus) UpdateStatus(rsrcs []metav1.Object, err error) {
var ready = true
for _, r := range rsrcs {
os := ObjectStatus{}
os.update(r)
switch r.(type) {
case *appsv1.StatefulSet:
os.Status = stsStatus(r.(*appsv1.StatefulSet))
case *policyv1.PodDisruptionBudget:
os.Status = pdbStatus(r.(*policyv1.PodDisruptionBudget))
case *appsv1.Deployment:
os.Status = deploymentStatus(r.(*appsv1.Deployment))
case *appsv1.ReplicaSet:
os.Status = replicasetStatus(r.(*appsv1.ReplicaSet))
case *appsv1.DaemonSet:
os.Status = daemonsetStatus(r.(*appsv1.DaemonSet))
case *corev1.Pod:
os.Status = podStatus(r.(*corev1.Pod))
case *corev1.Service:
os.Status = serviceStatus(r.(*corev1.Service))
case *corev1.PersistentVolumeClaim:
os.Status = pvcStatus(r.(*corev1.PersistentVolumeClaim))
//case *corev1.ReplicationController:
// Ingress
default:
os.Status = StatusReady
}
m.ComponentList.Objects = append(m.ComponentList.Objects, os)
}
for _, os := range m.ComponentList.Objects {
if os.Status != StatusReady {
ready = false
}
}
if ready {
m.Ready("ComponentsReady", "all components ready")
} else {
m.NotReady("ComponentsNotReady", "some components not ready")
}
if err != nil {
m.SetCondition(Error, "ErrorSeen", err.Error())
}
}
// Resource specific logic -----------------------------------
// Statefulset
func stsStatus(rsrc *appsv1.StatefulSet) string {
if rsrc.Status.ReadyReplicas == *rsrc.Spec.Replicas && rsrc.Status.CurrentReplicas == *rsrc.Spec.Replicas {
return StatusReady
}
return StatusInProgress
}
// Deployment
func deploymentStatus(rsrc *appsv1.Deployment) string {
status := StatusInProgress
progress := true
available := true
for _, c := range rsrc.Status.Conditions {
switch c.Type {
case appsv1.DeploymentProgressing:
// https://github.com/kubernetes/kubernetes/blob/a3ccea9d8743f2ff82e41b6c2af6dc2c41dc7b10/pkg/controller/deployment/progress.go#L52
if c.Status != corev1.ConditionTrue || c.Reason != "NewReplicaSetAvailable" {
progress = false
}
case appsv1.DeploymentAvailable:
if c.Status == corev1.ConditionFalse {
available = false
}
}
}
if progress && available {
status = StatusReady
}
return status
}
// Replicaset
func replicasetStatus(rsrc *appsv1.ReplicaSet) string {
status := StatusInProgress
failure := false
for _, c := range rsrc.Status.Conditions {
switch c.Type {
// https://github.com/kubernetes/kubernetes/blob/a3ccea9d8743f2ff82e41b6c2af6dc2c41dc7b10/pkg/controller/replicaset/replica_set_utils.go
case appsv1.ReplicaSetReplicaFailure:
if c.Status == corev1.ConditionTrue {
failure = true
break
}
}
}
if !failure && rsrc.Status.ReadyReplicas == rsrc.Status.Replicas && rsrc.Status.Replicas == rsrc.Status.AvailableReplicas {
status = StatusReady
}
return status
}
// Daemonset
func daemonsetStatus(rsrc *appsv1.DaemonSet) string {
status := StatusInProgress
if rsrc.Status.DesiredNumberScheduled == rsrc.Status.NumberAvailable && rsrc.Status.DesiredNumberScheduled == rsrc.Status.NumberReady {
status = StatusReady
}
return status
}
// PVC
func pvcStatus(rsrc *corev1.PersistentVolumeClaim) string {
status := StatusInProgress
if rsrc.Status.Phase == corev1.ClaimBound {
status = StatusReady
}
return status
}
// Service
func serviceStatus(rsrc *corev1.Service) string {
status := StatusReady
return status
}
// Pod
func podStatus(rsrc *corev1.Pod) string {
status := StatusInProgress
for i := range rsrc.Status.Conditions {
if rsrc.Status.Conditions[i].Type == corev1.PodReady &&
rsrc.Status.Conditions[i].Status == corev1.ConditionTrue {
status = StatusReady
break
}
}
return status
}
// PodDisruptionBudget
func pdbStatus(rsrc *policyv1.PodDisruptionBudget) string {
if rsrc.Status.CurrentHealthy >= rsrc.Status.DesiredHealthy {
return StatusReady
}
return StatusInProgress
}

View File

@@ -0,0 +1,419 @@
// +build !ignore_autogenerated
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (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
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.
*/
// Code generated by main. DO NOT EDIT.
package v1beta1
import (
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Application) DeepCopyInto(out *Application) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
in.Status.DeepCopyInto(&out.Status)
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Application.
func (in *Application) DeepCopy() *Application {
if in == nil {
return nil
}
out := new(Application)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *Application) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ApplicationList) DeepCopyInto(out *ApplicationList) {
*out = *in
out.TypeMeta = in.TypeMeta
out.ListMeta = in.ListMeta
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]Application, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplicationList.
func (in *ApplicationList) DeepCopy() *ApplicationList {
if in == nil {
return nil
}
out := new(ApplicationList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *ApplicationList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ApplicationSpec) DeepCopyInto(out *ApplicationSpec) {
*out = *in
if in.ComponentGroupKinds != nil {
in, out := &in.ComponentGroupKinds, &out.ComponentGroupKinds
*out = make([]v1.GroupKind, len(*in))
copy(*out, *in)
}
in.Descriptor.DeepCopyInto(&out.Descriptor)
if in.Selector != nil {
in, out := &in.Selector, &out.Selector
*out = new(v1.LabelSelector)
(*in).DeepCopyInto(*out)
}
if in.Info != nil {
in, out := &in.Info, &out.Info
*out = make([]InfoItem, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplicationSpec.
func (in *ApplicationSpec) DeepCopy() *ApplicationSpec {
if in == nil {
return nil
}
out := new(ApplicationSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ApplicationStatus) DeepCopyInto(out *ApplicationStatus) {
*out = *in
if in.Conditions != nil {
in, out := &in.Conditions, &out.Conditions
*out = make([]Condition, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
in.ComponentList.DeepCopyInto(&out.ComponentList)
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplicationStatus.
func (in *ApplicationStatus) DeepCopy() *ApplicationStatus {
if in == nil {
return nil
}
out := new(ApplicationStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ComponentList) DeepCopyInto(out *ComponentList) {
*out = *in
if in.Objects != nil {
in, out := &in.Objects, &out.Objects
*out = make([]ObjectStatus, len(*in))
copy(*out, *in)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentList.
func (in *ComponentList) DeepCopy() *ComponentList {
if in == nil {
return nil
}
out := new(ComponentList)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Condition) DeepCopyInto(out *Condition) {
*out = *in
in.LastUpdateTime.DeepCopyInto(&out.LastUpdateTime)
in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime)
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Condition.
func (in *Condition) DeepCopy() *Condition {
if in == nil {
return nil
}
out := new(Condition)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ConfigMapKeySelector) DeepCopyInto(out *ConfigMapKeySelector) {
*out = *in
out.ObjectReference = in.ObjectReference
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConfigMapKeySelector.
func (in *ConfigMapKeySelector) DeepCopy() *ConfigMapKeySelector {
if in == nil {
return nil
}
out := new(ConfigMapKeySelector)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ContactData) DeepCopyInto(out *ContactData) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContactData.
func (in *ContactData) DeepCopy() *ContactData {
if in == nil {
return nil
}
out := new(ContactData)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Descriptor) DeepCopyInto(out *Descriptor) {
*out = *in
if in.Icons != nil {
in, out := &in.Icons, &out.Icons
*out = make([]ImageSpec, len(*in))
copy(*out, *in)
}
if in.Maintainers != nil {
in, out := &in.Maintainers, &out.Maintainers
*out = make([]ContactData, len(*in))
copy(*out, *in)
}
if in.Owners != nil {
in, out := &in.Owners, &out.Owners
*out = make([]ContactData, len(*in))
copy(*out, *in)
}
if in.Keywords != nil {
in, out := &in.Keywords, &out.Keywords
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.Links != nil {
in, out := &in.Links, &out.Links
*out = make([]Link, len(*in))
copy(*out, *in)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Descriptor.
func (in *Descriptor) DeepCopy() *Descriptor {
if in == nil {
return nil
}
out := new(Descriptor)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ImageSpec) DeepCopyInto(out *ImageSpec) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageSpec.
func (in *ImageSpec) DeepCopy() *ImageSpec {
if in == nil {
return nil
}
out := new(ImageSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *InfoItem) DeepCopyInto(out *InfoItem) {
*out = *in
if in.ValueFrom != nil {
in, out := &in.ValueFrom, &out.ValueFrom
*out = new(InfoItemSource)
(*in).DeepCopyInto(*out)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InfoItem.
func (in *InfoItem) DeepCopy() *InfoItem {
if in == nil {
return nil
}
out := new(InfoItem)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *InfoItemSource) DeepCopyInto(out *InfoItemSource) {
*out = *in
if in.SecretKeyRef != nil {
in, out := &in.SecretKeyRef, &out.SecretKeyRef
*out = new(SecretKeySelector)
**out = **in
}
if in.ConfigMapKeyRef != nil {
in, out := &in.ConfigMapKeyRef, &out.ConfigMapKeyRef
*out = new(ConfigMapKeySelector)
**out = **in
}
if in.ServiceRef != nil {
in, out := &in.ServiceRef, &out.ServiceRef
*out = new(ServiceSelector)
(*in).DeepCopyInto(*out)
}
if in.IngressRef != nil {
in, out := &in.IngressRef, &out.IngressRef
*out = new(IngressSelector)
**out = **in
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InfoItemSource.
func (in *InfoItemSource) DeepCopy() *InfoItemSource {
if in == nil {
return nil
}
out := new(InfoItemSource)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *IngressSelector) DeepCopyInto(out *IngressSelector) {
*out = *in
out.ObjectReference = in.ObjectReference
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IngressSelector.
func (in *IngressSelector) DeepCopy() *IngressSelector {
if in == nil {
return nil
}
out := new(IngressSelector)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Link) DeepCopyInto(out *Link) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Link.
func (in *Link) DeepCopy() *Link {
if in == nil {
return nil
}
out := new(Link)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ObjectStatus) DeepCopyInto(out *ObjectStatus) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObjectStatus.
func (in *ObjectStatus) DeepCopy() *ObjectStatus {
if in == nil {
return nil
}
out := new(ObjectStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *SecretKeySelector) DeepCopyInto(out *SecretKeySelector) {
*out = *in
out.ObjectReference = in.ObjectReference
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretKeySelector.
func (in *SecretKeySelector) DeepCopy() *SecretKeySelector {
if in == nil {
return nil
}
out := new(SecretKeySelector)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ServiceSelector) DeepCopyInto(out *ServiceSelector) {
*out = *in
out.ObjectReference = in.ObjectReference
if in.Port != nil {
in, out := &in.Port, &out.Port
*out = new(int32)
**out = **in
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceSelector.
func (in *ServiceSelector) DeepCopy() *ServiceSelector {
if in == nil {
return nil
}
out := new(ServiceSelector)
in.DeepCopyInto(out)
return out
}