mirror of
https://github.com/ysoftdevs/gardener-extension-shoot-fleet-agent.git
synced 2026-06-12 16:44:40 +02:00
Initial v1.0.0 commit
This commit is contained in:
+289
@@ -0,0 +1,289 @@
|
||||
SPDX short identifier: Apache-2.0
|
||||
|
||||
```
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
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.
|
||||
```
|
||||
|
||||
## APIs
|
||||
|
||||
This project may include APIs to SAP or third party products or services. The use of these APIs,
|
||||
products and services may be subject to additional agreements. In no event shall the application
|
||||
of the Apache Software License, v.2 to this project grant any rights in or to these APIs, products
|
||||
or services that would alter, expand, be inconsistent with, or supersede any terms of these additional
|
||||
agreements. API means application programming interfaces, as well as their respective specifications
|
||||
and implementing code that allows other software products to communicate with or call on SAP or
|
||||
third party products or services (for example, SAP Enterprise Services, BAPIs, Idocs, RFCs and
|
||||
ABAP calls or other user exits) and may be made available through SAP or third party products,
|
||||
SDKs, documentation or other media.
|
||||
|
||||
## Subcomponents
|
||||
|
||||
This project includes the following subcomponents that are subject to separate license terms.
|
||||
Your use of these subcomponents is subject to the separate license terms applicable to
|
||||
each subcomponent.
|
||||
|
||||
Schema of the external API types that are served by the Kubernetes API server
|
||||
https://github.com/kubernetes/api
|
||||
Copyright 2017 The Kubernetes Authors
|
||||
Apache 2 license (https://github.com/kubernetes/api/blob/master/LICENSE)
|
||||
|
||||
Scheme, typing, encoding, decoding, and conversion packages for Kubernetes and Kubernetes-like API objects.
|
||||
https://github.com/kubernetes/apimachinery
|
||||
Copyright 2014 The Kubernetes Authors
|
||||
Apache 2 license (https://github.com/kubernetes/apimachinery/blob/master/LICENSE)
|
||||
|
||||
Logrus.
|
||||
https://github.com/sirupsen/logrus
|
||||
Copyright (c) 2014 Simon Eskildsen
|
||||
MIT license (https://github.com/sirupsen/logrus/blob/master/LICENSE)
|
||||
|
||||
Client-go
|
||||
https://github.com/kubernetes/client-go
|
||||
Copyright 2017 The Kubernetes Authors
|
||||
Apache 2 license (https://github.com/kubernetes/client-go/blob/master/LICENSE)
|
||||
|
||||
Etcd
|
||||
https://github.com/coreos/etcd
|
||||
Copyright 2017 The etcd Authors
|
||||
Apache 2 license (https://github.com/coreos/etcd/blob/master/LICENSE)
|
||||
|
||||
Kubebuilder
|
||||
Copyright 2017 The Kubernetes Authors
|
||||
Apache 2 license (https://github.com/kubernetes-sigs/kubebuilder/blob/master/LICENSE)
|
||||
|
||||
Helm
|
||||
https://git.k8s.io/helm
|
||||
Copyright 2017 The Kubernetes Authors
|
||||
Apache 2 license (https://git.k8s.io/helm/LICENSE)
|
||||
|
||||
------
|
||||
|
||||
## MIT License
|
||||
|
||||
SPDX short identifier: MIT
|
||||
|
||||
```
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) <year> <owner>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
```
|
||||
|
||||
------
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
## etcd-druid
|
||||
|
||||
Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved.
|
||||
+324
@@ -0,0 +1,324 @@
|
||||
// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file.
|
||||
//
|
||||
// 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 v1alpha1
|
||||
|
||||
import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
const (
|
||||
// GarbageCollectionPolicyExponential defines the exponential policy for garbage collecting old backups
|
||||
GarbageCollectionPolicyExponential = "Exponential"
|
||||
// GarbageCollectionPolicyLimitBased defines the limit based policy for garbage collecting old backups
|
||||
GarbageCollectionPolicyLimitBased = "LimitBased"
|
||||
|
||||
// Basic is a constant for metrics level basic.
|
||||
Basic MetricsLevel = "basic"
|
||||
// Extensive is a constant for metrics level extensive.
|
||||
Extensive MetricsLevel = "extensive"
|
||||
)
|
||||
|
||||
// MetricsLevel defines the level 'basic' or 'extensive'.
|
||||
// +kubebuilder:validation:Enum=basic;extensive
|
||||
type MetricsLevel string
|
||||
|
||||
// GarbageCollectionPolicy defines the type of policy for snapshot garbage collection.
|
||||
// +kubebuilder:validation:Enum=Exponential;LimitBased
|
||||
type GarbageCollectionPolicy string
|
||||
|
||||
// StorageProvider defines the type of object store provider for storing backups.
|
||||
type StorageProvider string
|
||||
|
||||
// StoreSpec defines parameters related to ObjectStore persisting backups
|
||||
type StoreSpec struct {
|
||||
// +optional
|
||||
Container *string `json:"container,omitempty"`
|
||||
// +required
|
||||
Prefix string `json:"prefix"`
|
||||
// +optional
|
||||
Provider *StorageProvider `json:"provider,omitempty"`
|
||||
// +optional
|
||||
SecretRef *corev1.SecretReference `json:"secretRef,omitempty"`
|
||||
}
|
||||
|
||||
// TLSConfig hold the TLS configuration details.
|
||||
type TLSConfig struct {
|
||||
// +required
|
||||
ServerTLSSecretRef corev1.SecretReference `json:"serverTLSSecretRef"`
|
||||
// +required
|
||||
ClientTLSSecretRef corev1.SecretReference `json:"clientTLSSecretRef"`
|
||||
// +required
|
||||
TLSCASecretRef corev1.SecretReference `json:"tlsCASecretRef"`
|
||||
}
|
||||
|
||||
// BackupSpec defines parametes associated with the full and delta snapshots of etcd
|
||||
type BackupSpec struct {
|
||||
// Port define the port on which etcd-backup-restore server will exposed.
|
||||
// +optional
|
||||
Port *int `json:"port,omitempty"`
|
||||
// +optional
|
||||
TLS *TLSConfig `json:"tls,omitempty"`
|
||||
// Image defines the etcd container image and tag
|
||||
// +optional
|
||||
Image *string `json:"image,omitempty"`
|
||||
// Store defines the specification of object store provider for storing backups.
|
||||
// +optional
|
||||
Store *StoreSpec `json:"store,omitempty"`
|
||||
// Resources defines the compute Resources required by backup-restore container.
|
||||
// More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/
|
||||
// +optional
|
||||
Resources *corev1.ResourceRequirements `json:"resources,omitempty"`
|
||||
// FullSnapshotSchedule defines the cron standard schedule for full snapshots.
|
||||
// +optional
|
||||
FullSnapshotSchedule *string `json:"fullSnapshotSchedule,omitempty"`
|
||||
// GarbageCollectionPolicy defines the policy for garbage collecting old backups
|
||||
// +optional
|
||||
GarbageCollectionPolicy *GarbageCollectionPolicy `json:"garbageCollectionPolicy,omitempty"`
|
||||
// GarbageCollectionPeriod defines the period for garbage collecting old backups
|
||||
// +optional
|
||||
GarbageCollectionPeriod *metav1.Duration `json:"garbageCollectionPeriod,omitempty"`
|
||||
// DeltaSnapshotPeriod defines the period after which delta snapshots will be taken
|
||||
// +optional
|
||||
DeltaSnapshotPeriod *metav1.Duration `json:"deltaSnapshotPeriod,omitempty"`
|
||||
// DeltaSnapshotMemoryLimit defines the memory limit after which delta snapshots will be taken
|
||||
// +optional
|
||||
DeltaSnapshotMemoryLimit *resource.Quantity `json:"deltaSnapshotMemoryLimit,omitempty"`
|
||||
}
|
||||
|
||||
// EtcdConfig defines parametes associated etcd deployed
|
||||
type EtcdConfig struct {
|
||||
// Quota defines the etcd DB quota.
|
||||
// +optional
|
||||
Quota *resource.Quantity `json:"quota,omitempty"`
|
||||
// DefragmentationSchedule defines the cron standard schedule for defragmentation of etcd.
|
||||
// +optional
|
||||
DefragmentationSchedule *string `json:"defragmentationSchedule,omitempty"`
|
||||
// +optional
|
||||
ServerPort *int `json:"serverPort,omitempty"`
|
||||
// +optional
|
||||
ClientPort *int `json:"clientPort,omitempty"`
|
||||
// Image defines the etcd container image and tag
|
||||
// +optional
|
||||
Image *string `json:"image,omitempty"`
|
||||
// +optional
|
||||
AuthSecretRef *corev1.SecretReference `json:"authSecretRef,omitempty"`
|
||||
// Metrics defines the level of detail for exported metrics of etcd, specify 'extensive' to include histogram metrics.
|
||||
// +optional
|
||||
Metrics MetricsLevel `json:"metrics,omitempty"`
|
||||
// Resources defines the compute Resources required by etcd container.
|
||||
// More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/
|
||||
// +optional
|
||||
Resources *corev1.ResourceRequirements `json:"resources,omitempty"`
|
||||
// +optional
|
||||
TLS *TLSConfig `json:"tls,omitempty"`
|
||||
}
|
||||
|
||||
// EtcdSpec defines the desired state of Etcd
|
||||
type EtcdSpec struct {
|
||||
// selector is a label query over pods that should match the replica count.
|
||||
// It must match the pod template's labels.
|
||||
// More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors
|
||||
Selector *metav1.LabelSelector `json:"selector"`
|
||||
// +required
|
||||
Labels map[string]string `json:"labels"`
|
||||
// +optional
|
||||
Annotations map[string]string `json:"annotations,omitempty"`
|
||||
// +required
|
||||
Etcd EtcdConfig `json:"etcd"`
|
||||
// +required
|
||||
Backup BackupSpec `json:"backup"`
|
||||
// +required
|
||||
Replicas int `json:"replicas"`
|
||||
// PriorityClassName is the name of a priority class that shall be used for the etcd pods.
|
||||
// +optional
|
||||
PriorityClassName *string `json:"priorityClassName,omitempty"`
|
||||
// StorageClass defines the name of the StorageClass required by the claim.
|
||||
// More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1
|
||||
// +optional
|
||||
StorageClass *string `json:"storageClass,omitempty"`
|
||||
// StorageCapacity defines the size of persistent volume.
|
||||
// +optional
|
||||
StorageCapacity *resource.Quantity `json:"storageCapacity,omitempty"`
|
||||
// VolumeClaimTemplate defines the volume claim template to be created
|
||||
// +optional
|
||||
VolumeClaimTemplate *string `json:"volumeClaimTemplate,omitempty"`
|
||||
}
|
||||
|
||||
// CrossVersionObjectReference contains enough information to let you identify the referred resource.
|
||||
type CrossVersionObjectReference struct {
|
||||
// Kind of the referent
|
||||
// +required
|
||||
Kind string `json:"kind,omitempty"`
|
||||
// Name of the referent
|
||||
// +required
|
||||
Name string `json:"name,omitempty"`
|
||||
// API version of the referent
|
||||
// +optional
|
||||
APIVersion string `json:"apiVersion,omitempty"`
|
||||
}
|
||||
|
||||
// ConditionStatus is the status of a condition.
|
||||
type ConditionStatus string
|
||||
|
||||
// ConditionType is a string alias.
|
||||
type ConditionType string
|
||||
|
||||
const (
|
||||
// ConditionAvailable is a condition type for indicating availability.
|
||||
ConditionAvailable ConditionType = "Available"
|
||||
|
||||
// ConditionTrue means a resource is in the condition.
|
||||
ConditionTrue ConditionStatus = "True"
|
||||
// ConditionFalse means a resource is not in the condition.
|
||||
ConditionFalse ConditionStatus = "False"
|
||||
// ConditionUnknown means Gardener can't decide if a resource is in the condition or not.
|
||||
ConditionUnknown ConditionStatus = "Unknown"
|
||||
// ConditionProgressing means the condition was seen true, failed but stayed within a predefined failure threshold.
|
||||
// In the future, we could add other intermediate conditions, e.g. ConditionDegraded.
|
||||
ConditionProgressing ConditionStatus = "Progressing"
|
||||
|
||||
// ConditionCheckError is a constant for a reason in condition.
|
||||
ConditionCheckError = "ConditionCheckError"
|
||||
)
|
||||
|
||||
// Condition holds the information about the state of a resource.
|
||||
type Condition struct {
|
||||
// Type of the Etcd condition.
|
||||
Type ConditionType `json:"type,omitempty"`
|
||||
// Status of the condition, one of True, False, Unknown.
|
||||
Status ConditionStatus `json:"status,omitempty"`
|
||||
// Last time the condition transitioned from one status to another.
|
||||
LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty"`
|
||||
// Last time the condition was updated.
|
||||
LastUpdateTime metav1.Time `json:"lastUpdateTime,omitempty"`
|
||||
// The reason for the condition's last transition.
|
||||
Reason string `json:"reason,omitempty"`
|
||||
// A human readable message indicating details about the transition.
|
||||
Message string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
// EndpointStatus is the status of a condition.
|
||||
type EndpointStatus string
|
||||
|
||||
// LastOperationType is a string alias.
|
||||
type LastOperationType string
|
||||
|
||||
const (
|
||||
// LastOperationTypeCreate indicates a 'create' operation.
|
||||
LastOperationTypeCreate LastOperationType = "Create"
|
||||
// LastOperationTypeReconcile indicates a 'reconcile' operation.
|
||||
LastOperationTypeReconcile LastOperationType = "Reconcile"
|
||||
// LastOperationTypeDelete indicates a 'delete' operation.
|
||||
LastOperationTypeDelete LastOperationType = "Delete"
|
||||
)
|
||||
|
||||
// LastOperationState is a string alias.
|
||||
type LastOperationState string
|
||||
|
||||
const (
|
||||
// LastOperationStateProcessing indicates that an operation is ongoing.
|
||||
LastOperationStateProcessing LastOperationState = "Processing"
|
||||
// LastOperationStateSucceeded indicates that an operation has completed successfully.
|
||||
LastOperationStateSucceeded LastOperationState = "Succeeded"
|
||||
// LastOperationStateError indicates that an operation is completed with errors and will be retried.
|
||||
LastOperationStateError LastOperationState = "Error"
|
||||
// LastOperationStateFailed indicates that an operation is completed with errors and won't be retried.
|
||||
LastOperationStateFailed LastOperationState = "Failed"
|
||||
// LastOperationStatePending indicates that an operation cannot be done now, but will be tried in future.
|
||||
LastOperationStatePending LastOperationState = "Pending"
|
||||
// LastOperationStateAborted indicates that an operation has been aborted.
|
||||
LastOperationStateAborted LastOperationState = "Aborted"
|
||||
)
|
||||
|
||||
// LastOperation indicates the type and the state of the last operation, along with a description
|
||||
// message and a progress indicator.
|
||||
type LastOperation struct {
|
||||
// A human readable message indicating details about the last operation.
|
||||
Description string `json:"description,omitempty"`
|
||||
// Last time the operation state transitioned from one to another.
|
||||
LastUpdateTime metav1.Time `json:"lastUpdateTime,omitempty"`
|
||||
// The progress in percentage (0-100) of the last operation.
|
||||
Progress int `json:"progress,omitempty"`
|
||||
// Status of the last operation, one of Aborted, Processing, Succeeded, Error, Failed.
|
||||
State LastOperationState `json:"state,omitempty"`
|
||||
// Type of the last operation, one of Create, Reconcile, Delete.
|
||||
Type LastOperationType `json:"type,omitempty"`
|
||||
}
|
||||
|
||||
// EtcdStatus defines the observed state of Etcd
|
||||
type EtcdStatus struct {
|
||||
// ObservedGeneration is the most recent generation observed for this resource.
|
||||
// +optional
|
||||
ObservedGeneration *int64 `json:"observedGeneration,omitempty"`
|
||||
// +optional
|
||||
Etcd CrossVersionObjectReference `json:"etcd,omitempty"`
|
||||
// +optional
|
||||
Conditions []Condition `json:"conditions,omitempty"`
|
||||
// +optional
|
||||
CurrentReplicas int32 `json:"currentReplicas,omitempty"`
|
||||
// +optional
|
||||
ServiceName *string `json:"serviceName,omitempty"`
|
||||
// +optional
|
||||
LastError *string `json:"lastError,omitempty"`
|
||||
// +optional
|
||||
Replicas int32 `json:"replicas,omitempty"`
|
||||
// +optional
|
||||
ReadyReplicas int32 `json:"readyReplicas,omitempty"`
|
||||
// +optional
|
||||
Ready *bool `json:"ready,omitempty"`
|
||||
// +optional
|
||||
UpdatedReplicas int32 `json:"updatedReplicas,omitempty"`
|
||||
// selector is a label query over pods that should match the replica count.
|
||||
// It must match the pod template's labels.
|
||||
// +optional
|
||||
LabelSelector *metav1.LabelSelector `json:"labelSelector,omitempty"`
|
||||
//LastOperation LastOperation `json:"lastOperation,omitempty"`
|
||||
}
|
||||
|
||||
// +genclient
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:printcolumn:name="Ready",type=string,JSONPath=`.status.ready`
|
||||
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
|
||||
// +kubebuilder:subresource:scale:specpath=.spec.replicas,statuspath=.status.replicas,selectorpath=.status.labelSelector
|
||||
|
||||
// Etcd is the Schema for the etcds API
|
||||
type Etcd struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec EtcdSpec `json:"spec,omitempty"`
|
||||
Status EtcdStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// +genclient
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// EtcdList contains a list of Etcd
|
||||
type EtcdList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []Etcd `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&Etcd{}, &EtcdList{})
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file.
|
||||
//
|
||||
// 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 v1alpha1 contains API Schema definitions for the druid v1alpha1 API group
|
||||
// +kubebuilder:object:generate=true
|
||||
// +groupName=druid.gardener.cloud
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"sigs.k8s.io/controller-runtime/pkg/scheme"
|
||||
)
|
||||
|
||||
var (
|
||||
// GroupVersion is group version used to register these objects
|
||||
GroupVersion = schema.GroupVersion{Group: "druid.gardener.cloud", Version: "v1alpha1"}
|
||||
|
||||
// SchemeBuilder is used to add go types to the GroupVersionKind scheme
|
||||
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
|
||||
|
||||
// AddToScheme adds the types in this group-version to the given scheme.
|
||||
AddToScheme = SchemeBuilder.AddToScheme
|
||||
)
|
||||
+404
@@ -0,0 +1,404 @@
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file.
|
||||
//
|
||||
// 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 controller-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "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 *BackupSpec) DeepCopyInto(out *BackupSpec) {
|
||||
*out = *in
|
||||
if in.Port != nil {
|
||||
in, out := &in.Port, &out.Port
|
||||
*out = new(int)
|
||||
**out = **in
|
||||
}
|
||||
if in.TLS != nil {
|
||||
in, out := &in.TLS, &out.TLS
|
||||
*out = new(TLSConfig)
|
||||
**out = **in
|
||||
}
|
||||
if in.Image != nil {
|
||||
in, out := &in.Image, &out.Image
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.Store != nil {
|
||||
in, out := &in.Store, &out.Store
|
||||
*out = new(StoreSpec)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.Resources != nil {
|
||||
in, out := &in.Resources, &out.Resources
|
||||
*out = new(v1.ResourceRequirements)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.FullSnapshotSchedule != nil {
|
||||
in, out := &in.FullSnapshotSchedule, &out.FullSnapshotSchedule
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.GarbageCollectionPolicy != nil {
|
||||
in, out := &in.GarbageCollectionPolicy, &out.GarbageCollectionPolicy
|
||||
*out = new(GarbageCollectionPolicy)
|
||||
**out = **in
|
||||
}
|
||||
if in.GarbageCollectionPeriod != nil {
|
||||
in, out := &in.GarbageCollectionPeriod, &out.GarbageCollectionPeriod
|
||||
*out = new(metav1.Duration)
|
||||
**out = **in
|
||||
}
|
||||
if in.DeltaSnapshotPeriod != nil {
|
||||
in, out := &in.DeltaSnapshotPeriod, &out.DeltaSnapshotPeriod
|
||||
*out = new(metav1.Duration)
|
||||
**out = **in
|
||||
}
|
||||
if in.DeltaSnapshotMemoryLimit != nil {
|
||||
in, out := &in.DeltaSnapshotMemoryLimit, &out.DeltaSnapshotMemoryLimit
|
||||
x := (*in).DeepCopy()
|
||||
*out = &x
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackupSpec.
|
||||
func (in *BackupSpec) DeepCopy() *BackupSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(BackupSpec)
|
||||
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.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime)
|
||||
in.LastUpdateTime.DeepCopyInto(&out.LastUpdateTime)
|
||||
}
|
||||
|
||||
// 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 *CrossVersionObjectReference) DeepCopyInto(out *CrossVersionObjectReference) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CrossVersionObjectReference.
|
||||
func (in *CrossVersionObjectReference) DeepCopy() *CrossVersionObjectReference {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(CrossVersionObjectReference)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Etcd) DeepCopyInto(out *Etcd) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
in.Status.DeepCopyInto(&out.Status)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Etcd.
|
||||
func (in *Etcd) DeepCopy() *Etcd {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Etcd)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *Etcd) 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 *EtcdConfig) DeepCopyInto(out *EtcdConfig) {
|
||||
*out = *in
|
||||
if in.Quota != nil {
|
||||
in, out := &in.Quota, &out.Quota
|
||||
x := (*in).DeepCopy()
|
||||
*out = &x
|
||||
}
|
||||
if in.DefragmentationSchedule != nil {
|
||||
in, out := &in.DefragmentationSchedule, &out.DefragmentationSchedule
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.ServerPort != nil {
|
||||
in, out := &in.ServerPort, &out.ServerPort
|
||||
*out = new(int)
|
||||
**out = **in
|
||||
}
|
||||
if in.ClientPort != nil {
|
||||
in, out := &in.ClientPort, &out.ClientPort
|
||||
*out = new(int)
|
||||
**out = **in
|
||||
}
|
||||
if in.Image != nil {
|
||||
in, out := &in.Image, &out.Image
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.AuthSecretRef != nil {
|
||||
in, out := &in.AuthSecretRef, &out.AuthSecretRef
|
||||
*out = new(v1.SecretReference)
|
||||
**out = **in
|
||||
}
|
||||
if in.Resources != nil {
|
||||
in, out := &in.Resources, &out.Resources
|
||||
*out = new(v1.ResourceRequirements)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.TLS != nil {
|
||||
in, out := &in.TLS, &out.TLS
|
||||
*out = new(TLSConfig)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EtcdConfig.
|
||||
func (in *EtcdConfig) DeepCopy() *EtcdConfig {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(EtcdConfig)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *EtcdList) DeepCopyInto(out *EtcdList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]Etcd, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EtcdList.
|
||||
func (in *EtcdList) DeepCopy() *EtcdList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(EtcdList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *EtcdList) 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 *EtcdSpec) DeepCopyInto(out *EtcdSpec) {
|
||||
*out = *in
|
||||
if in.Selector != nil {
|
||||
in, out := &in.Selector, &out.Selector
|
||||
*out = new(metav1.LabelSelector)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.Labels != nil {
|
||||
in, out := &in.Labels, &out.Labels
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.Annotations != nil {
|
||||
in, out := &in.Annotations, &out.Annotations
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
in.Etcd.DeepCopyInto(&out.Etcd)
|
||||
in.Backup.DeepCopyInto(&out.Backup)
|
||||
if in.PriorityClassName != nil {
|
||||
in, out := &in.PriorityClassName, &out.PriorityClassName
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.StorageClass != nil {
|
||||
in, out := &in.StorageClass, &out.StorageClass
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.StorageCapacity != nil {
|
||||
in, out := &in.StorageCapacity, &out.StorageCapacity
|
||||
x := (*in).DeepCopy()
|
||||
*out = &x
|
||||
}
|
||||
if in.VolumeClaimTemplate != nil {
|
||||
in, out := &in.VolumeClaimTemplate, &out.VolumeClaimTemplate
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EtcdSpec.
|
||||
func (in *EtcdSpec) DeepCopy() *EtcdSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(EtcdSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *EtcdStatus) DeepCopyInto(out *EtcdStatus) {
|
||||
*out = *in
|
||||
if in.ObservedGeneration != nil {
|
||||
in, out := &in.ObservedGeneration, &out.ObservedGeneration
|
||||
*out = new(int64)
|
||||
**out = **in
|
||||
}
|
||||
out.Etcd = in.Etcd
|
||||
if in.Conditions != nil {
|
||||
in, out := &in.Conditions, &out.Conditions
|
||||
*out = make([]Condition, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.ServiceName != nil {
|
||||
in, out := &in.ServiceName, &out.ServiceName
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.LastError != nil {
|
||||
in, out := &in.LastError, &out.LastError
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.Ready != nil {
|
||||
in, out := &in.Ready, &out.Ready
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
if in.LabelSelector != nil {
|
||||
in, out := &in.LabelSelector, &out.LabelSelector
|
||||
*out = new(metav1.LabelSelector)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EtcdStatus.
|
||||
func (in *EtcdStatus) DeepCopy() *EtcdStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(EtcdStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LastOperation) DeepCopyInto(out *LastOperation) {
|
||||
*out = *in
|
||||
in.LastUpdateTime.DeepCopyInto(&out.LastUpdateTime)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LastOperation.
|
||||
func (in *LastOperation) DeepCopy() *LastOperation {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LastOperation)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *StoreSpec) DeepCopyInto(out *StoreSpec) {
|
||||
*out = *in
|
||||
if in.Container != nil {
|
||||
in, out := &in.Container, &out.Container
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.Provider != nil {
|
||||
in, out := &in.Provider, &out.Provider
|
||||
*out = new(StorageProvider)
|
||||
**out = **in
|
||||
}
|
||||
if in.SecretRef != nil {
|
||||
in, out := &in.SecretRef, &out.SecretRef
|
||||
*out = new(v1.SecretReference)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StoreSpec.
|
||||
func (in *StoreSpec) DeepCopy() *StoreSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(StoreSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *TLSConfig) DeepCopyInto(out *TLSConfig) {
|
||||
*out = *in
|
||||
out.ServerTLSSecretRef = in.ServerTLSSecretRef
|
||||
out.ClientTLSSecretRef = in.ClientTLSSecretRef
|
||||
out.TLSCASecretRef = in.TLSCASecretRef
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TLSConfig.
|
||||
func (in *TLSConfig) DeepCopy() *TLSConfig {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(TLSConfig)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
+320
@@ -0,0 +1,320 @@
|
||||
```
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
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.
|
||||
```
|
||||
|
||||
## APIs
|
||||
|
||||
This project may include APIs to SAP or third party products or services. The use of these APIs, products and services may be subject to additional agreements. In no event shall the application of the Apache Software License, v.2 to this project grant any rights in or to these APIs, products or services that would alter, expand, be inconsistent with, or supersede any terms of these additional agreements. API means application programming interfaces, as well as their respective specifications and implementing code that allows other software products to communicate with or call on SAP or third party products or services (for example, SAP Enterprise Services, BAPIs, Idocs, RFCs and ABAP calls or other user exits) and may be made available through SAP or third party products, SDKs, documentation or other media.
|
||||
|
||||
## Subcomponents
|
||||
|
||||
This project includes the following subcomponents that are subject to separate license terms.
|
||||
Your use of these subcomponents is subject to the separate license terms applicable to
|
||||
each subcomponent.
|
||||
|
||||
Gardener Controller Manager Library
|
||||
Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved.
|
||||
Apache 2 license (https://github.com/gardener/controller-manager-library/blob/master/LICENSE.md)
|
||||
|
||||
APIMachinery
|
||||
https://git.k8s.io/apimachinery
|
||||
Copyright 2017 The Kubernetes Authors
|
||||
Apache 2 license (https://git.k8s.io/apimachinery/LICENSE)
|
||||
|
||||
Client-Go
|
||||
https://git.k8s.io/client-go
|
||||
Copyright 2017 The Kubernetes Authors
|
||||
Apache 2 license (https://git.k8s.io/client-go/LICENSE)
|
||||
|
||||
Code-Generator
|
||||
https://git.k8s.io/code-generator
|
||||
Copyright 2017 The Kubernetes Authors
|
||||
Apache 2 license (https://git.k8s.io/code-generator/LICENSE)
|
||||
|
||||
Cobra.
|
||||
https://github.com/spf13/cobra
|
||||
Copyright © 2013 Steve Francia
|
||||
Apache 2 license (https://git.k8s.io/code-generator/LICENSE)
|
||||
|
||||
Logrus.
|
||||
https://github.com/sirupsen/logrus
|
||||
Copyright (c) 2014 Simon Eskildsen
|
||||
MIT license (https://github.com/sirupsen/logrus/blob/master/LICENSE)
|
||||
|
||||
Google DNS SDK
|
||||
https://github.com/googleapis/google-api-go-client
|
||||
Copyright (c) 2011 Google Inc. All rights reserved
|
||||
BSD 3-Clause "New" or "Revised" License (https://github.com/googleapis/google-api-go-client/blob/master/LICENSE)
|
||||
|
||||
AWS SDK for Go
|
||||
Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
Copyright 2014-2015 Stripe, Inc.
|
||||
Apache 2 license (https://github.com/aws/aws-sdk-go/blob/master/LICENSE.txt)
|
||||
|
||||
Some code fragments have been extracted from kubernetes-incubator/external-dns
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
Apache 2 license (https://github.com/kubernetes-incubator/external-dns/blob/master/LICENSE)
|
||||
|
||||
------
|
||||
|
||||
## MIT License
|
||||
|
||||
SPDX short identifier: MIT
|
||||
|
||||
```
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) <year> <owner>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
```
|
||||
|
||||
## The 3-Clause BSD License
|
||||
|
||||
SPDX short identifier: BSD-3-Clause
|
||||
|
||||
```
|
||||
Copyright <YEAR> <COPYRIGHT HOLDER>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
```
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
## External DNS Management
|
||||
Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved.
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
//go:generate bash ../../../vendor/github.com/gardener/controller-manager-library/hack/generate-crds
|
||||
//go:generate bash ../../../hack/generate-code
|
||||
// +kubebuilder:skip
|
||||
|
||||
package dns
|
||||
|
||||
const (
|
||||
GroupName = "dns.gardener.cloud"
|
||||
)
|
||||
Generated
Vendored
+81
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
type DNSAnnotationList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
// Standard list metadata
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []DNSAnnotation `json:"items"`
|
||||
}
|
||||
|
||||
// +kubebuilder:storageversion
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:resource:scope=Namespaced,path=dnsannotations,shortName=dnsa,singular=dnsannotation
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:printcolumn:name=RefGroup,JSONPath=".spec.resourceRef.apiVersion",type=string
|
||||
// +kubebuilder:printcolumn:name=RefKind,JSONPath=".spec.resourceRef.kind",type=string
|
||||
// +kubebuilder:printcolumn:name=RefName,JSONPath=".spec.resourceRef.name",type=string
|
||||
// +kubebuilder:printcolumn:name=RefNamespace,JSONPath=".spec.resourceRef.namespace",type=string
|
||||
// +kubebuilder:printcolumn:name=Active,JSONPath=".status.active",type=boolean
|
||||
// +kubebuilder:printcolumn:name=Age,JSONPath=".metadata.creationTimestamp",type=date
|
||||
// +genclient
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
type DNSAnnotation struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
Spec DNSAnnotationSpec `json:"spec"`
|
||||
// +optional
|
||||
Status DNSAnnotationStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
type DNSAnnotationSpec struct {
|
||||
ResourceRef ResourceReference `json:"resourceRef"`
|
||||
Annotations map[string]string `json:"annotations"`
|
||||
}
|
||||
|
||||
type ResourceReference struct {
|
||||
// API Version of the annotated object
|
||||
APIVersion string `json:"apiVersion"`
|
||||
// Kind of the annotated object
|
||||
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
Kind string `json:"kind"`
|
||||
// Name of the annotated object
|
||||
// +optional
|
||||
Name string `json:"name,omitempty"`
|
||||
// Namspace of the annotated object
|
||||
// Defaulted by the namespace of the containing resource.
|
||||
// +optional
|
||||
Namespace string `json:"namespace,omitempty"`
|
||||
}
|
||||
|
||||
type DNSAnnotationStatus struct {
|
||||
// Indicates that annotation is observed by a DNS sorce controller
|
||||
// +optional
|
||||
Active bool `json:"active,omitempty"`
|
||||
// In case of a configuration problem this field describes the reason
|
||||
// +optional
|
||||
Message string `json:"message,omitempty"`
|
||||
}
|
||||
Generated
Vendored
+108
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
type DNSEntryList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
// Standard list metadata
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []DNSEntry `json:"items"`
|
||||
}
|
||||
|
||||
// +kubebuilder:storageversion
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:resource:scope=Namespaced,path=dnsentries,shortName=dnse,singular=dnsentry
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:printcolumn:name=DNS,description="FQDN of DNS Entry",JSONPath=".spec.dnsName",type=string
|
||||
// +kubebuilder:printcolumn:name=OWNERID,JSONPath=".spec.ownerId",type=string
|
||||
// +kubebuilder:printcolumn:name=TYPE,JSONPath=".status.providerType",type=string
|
||||
// +kubebuilder:printcolumn:name=PROVIDER,JSONPath=".status.provider",type=string
|
||||
// +kubebuilder:printcolumn:name=STATUS,JSONPath=".status.state",type=string
|
||||
// +genclient
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
type DNSEntry struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
Spec DNSEntrySpec `json:"spec"`
|
||||
// +optional
|
||||
Status DNSEntryStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
type DNSEntrySpec struct {
|
||||
// full qualified domain name
|
||||
DNSName string `json:"dnsName"`
|
||||
// reference to base entry used to inherit attributes from
|
||||
// +optional
|
||||
Reference *EntryReference `json:"reference,omitempty"`
|
||||
// owner id used to tag entries in external DNS system
|
||||
// +optional
|
||||
OwnerId *string `json:"ownerId,omitempty"`
|
||||
// time to live for records in external DNS system
|
||||
// +optional
|
||||
TTL *int64 `json:"ttl,omitempty"`
|
||||
// lookup interval for CNAMEs that must be resolved to IP addresses
|
||||
// +optional
|
||||
CNameLookupInterval *int64 `json:"cnameLookupInterval,omitempty"`
|
||||
// text records, either text or targets must be specified
|
||||
// +optional
|
||||
Text []string `json:"text,omitempty"`
|
||||
// target records (CNAME or A records), either text or targets must be specified
|
||||
// +optional
|
||||
Targets []string `json:"targets,omitempty"`
|
||||
}
|
||||
|
||||
type DNSEntryStatus struct {
|
||||
// +optional
|
||||
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
|
||||
// entry state
|
||||
// +optional
|
||||
State string `json:"state"`
|
||||
// message describing the reason for the state
|
||||
// +optional
|
||||
Message *string `json:"message,omitempty"`
|
||||
// provider type used for the entry
|
||||
// +optional
|
||||
ProviderType *string `json:"providerType,omitempty"`
|
||||
// assigned provider
|
||||
// +optional
|
||||
Provider *string `json:"provider,omitempty"`
|
||||
// zone used for the entry
|
||||
// +optional
|
||||
Zone *string `json:"zone,omitempty"`
|
||||
// time to live used for the entry
|
||||
// +optional
|
||||
TTL *int64 `json:"ttl,omitempty"`
|
||||
// effective targets generated for the entry
|
||||
// +optional
|
||||
Targets []string `json:"targets,omitempty"`
|
||||
}
|
||||
|
||||
type EntryReference struct {
|
||||
// name of the referenced DNSEntry object
|
||||
Name string `json:"name"`
|
||||
// namespace of the referenced DNSEntry object
|
||||
// +optional
|
||||
Namespace string `json:"namespace,omitempty"`
|
||||
}
|
||||
Generated
Vendored
+73
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
type DNSOwnerList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
// Standard list metadata
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []DNSOwner `json:"items"`
|
||||
}
|
||||
|
||||
// +kubebuilder:storageversion
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:resource:scope=Cluster,path=dnsowners,shortName=dnso,singular=dnsowner
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:printcolumn:name=OwnerId,JSONPath=".spec.ownerId",type=string
|
||||
// +kubebuilder:printcolumn:name=Active,JSONPath=".spec.active",type=boolean
|
||||
// +kubebuilder:printcolumn:name=Usages,JSONPath=".status.amount",type=string
|
||||
// +genclient
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
type DNSOwner struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
Spec DNSOwnerSpec `json:"spec"`
|
||||
// +optional
|
||||
Status DNSOwnerStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
type DNSOwnerSpec struct {
|
||||
// owner id used to tag entries in external DNS system
|
||||
OwnerId string `json:"ownerId"`
|
||||
// state of the ownerid for the DNS controller observing entry using this owner id
|
||||
// (default:true)
|
||||
// +optional
|
||||
Active *bool `json:"active,omitempty"`
|
||||
}
|
||||
|
||||
type DNSOwnerStatus struct {
|
||||
// Entry statistic for this owner id
|
||||
// +optional
|
||||
Entries DNSOwnerStatusEntries `json:"entries,omitempty"`
|
||||
}
|
||||
|
||||
type DNSOwnerStatusEntries struct {
|
||||
// number of entries using this owner id
|
||||
// +optional
|
||||
Amount int `json:"amount"`
|
||||
// number of entries per provider type
|
||||
// +optional
|
||||
ByType map[string]int `json:"types,omitempty"`
|
||||
}
|
||||
Generated
Vendored
+105
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
type DNSProviderList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
// Standard list metadata
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []DNSProvider `json:"items"`
|
||||
}
|
||||
|
||||
// +kubebuilder:storageversion
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:resource:scope=Namespaced,path=dnsproviders,shortName=dnspr,singular=dnsprovider
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:printcolumn:name=TYPE,JSONPath=".spec.type",type=string
|
||||
// +kubebuilder:printcolumn:name=STATUS,JSONPath=".status.state",type=string
|
||||
// +genclient
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
type DNSProvider struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
Spec DNSProviderSpec `json:"spec"`
|
||||
// +optional
|
||||
Status DNSProviderStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
type DNSProviderSpec struct {
|
||||
// type of the provider (selecting the responsible type of DNS controller)
|
||||
Type string `json:"type,omitempty"`
|
||||
// optional additional provider specific configuration values
|
||||
// +kubebuilder:validation:XPreserveUnknownFields
|
||||
// +kubebuilder:pruning:PreserveUnknownFields
|
||||
// +optional
|
||||
ProviderConfig *runtime.RawExtension `json:"providerConfig,omitempty"`
|
||||
// access credential for the external DNS system of the given type
|
||||
SecretRef *corev1.SecretReference `json:"secretRef,omitempty"`
|
||||
// desired selection of usable domains
|
||||
// (by default all zones and domains in those zones will be served)
|
||||
// +optional
|
||||
Domains *DNSSelection `json:"domains,omitempty"`
|
||||
// desired selection of usable domains
|
||||
// the domain selection is used for served zones, only
|
||||
// (by default all zones will be served)
|
||||
// +optional
|
||||
Zones *DNSSelection `json:"zones,omitempty"`
|
||||
}
|
||||
|
||||
type DNSSelection struct {
|
||||
// values that should be observed (domains or zones)
|
||||
// + optional
|
||||
Include []string `json:"include,omitempty"`
|
||||
// values that should be ignored (domains or zones)
|
||||
// + optional
|
||||
Exclude []string `json:"exclude,omitempty"`
|
||||
}
|
||||
|
||||
type DNSProviderStatus struct {
|
||||
// +optional
|
||||
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
|
||||
// state of the provider
|
||||
// +optional
|
||||
State string `json:"state"`
|
||||
// message describing the reason for the actual state of the provider
|
||||
Message *string `json:"message,omitempty"`
|
||||
// actually served domain selection
|
||||
// +optional
|
||||
Domains DNSSelectionStatus `json:"domains"`
|
||||
// actually served zones
|
||||
// +optional
|
||||
Zones DNSSelectionStatus `json:"zones"`
|
||||
}
|
||||
|
||||
type DNSSelectionStatus struct {
|
||||
// included values (domains or zones)
|
||||
// + optional
|
||||
Included []string `json:"included,omitempty"`
|
||||
// Excluded values (domains or zones)
|
||||
// + optional
|
||||
Excluded []string `json:"excluded,omitempty"`
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
// +k8s:deepcopy-gen=package,register
|
||||
|
||||
// Package v1alpha1 is the v1alpha1 version of the API.
|
||||
// +groupName=dns.gardener.cloud
|
||||
package v1alpha1
|
||||
Generated
Vendored
+75
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"github.com/gardener/external-dns-management/pkg/apis/dns"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
const (
|
||||
Version = "v1alpha1"
|
||||
GroupName = dns.GroupName
|
||||
|
||||
DNSOwnerKind = "DNSOwner"
|
||||
DNSOwnerPlural = "dnsowners"
|
||||
|
||||
DNSProviderKind = "DNSProvider"
|
||||
DNSProviderPlural = "dnsproviders"
|
||||
|
||||
DNSEntryKind = "DNSEntry"
|
||||
DNSEntryPlural = "dnsentries"
|
||||
|
||||
DNSAnnotationKind = "DNSAnnotation"
|
||||
DNSAnnotationPlural = "dnsannotations"
|
||||
)
|
||||
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
var SchemeGroupVersion = schema.GroupVersion{Group: dns.GroupName, Version: Version}
|
||||
|
||||
// Kind takes an unqualified kind and returns back a Group qualified GroupKind
|
||||
func Kind(kind string) schema.GroupKind {
|
||||
return SchemeGroupVersion.WithKind(kind).GroupKind()
|
||||
}
|
||||
|
||||
// Resource takes an unqualified resources and returns a Group qualified GroupResource
|
||||
func Resource(resource string) schema.GroupResource {
|
||||
return SchemeGroupVersion.WithResource(resource).GroupResource()
|
||||
}
|
||||
|
||||
var (
|
||||
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
|
||||
AddToScheme = SchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
// Adds the list of known types to Scheme.
|
||||
func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&DNSOwner{},
|
||||
&DNSOwnerList{},
|
||||
&DNSProvider{},
|
||||
&DNSProviderList{},
|
||||
&DNSEntry{},
|
||||
&DNSEntryList{},
|
||||
&DNSAnnotation{},
|
||||
&DNSAnnotationList{},
|
||||
)
|
||||
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
|
||||
return nil
|
||||
}
|
||||
Generated
Vendored
+24
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
package v1alpha1
|
||||
|
||||
const STATE_PENDING = "Pending"
|
||||
const STATE_ERROR = "Error"
|
||||
const STATE_INVALID = "Invalid"
|
||||
const STATE_STALE = "Stale"
|
||||
const STATE_READY = "Ready"
|
||||
const STATE_DELETING = "Deleting"
|
||||
Generated
Vendored
+606
@@ -0,0 +1,606 @@
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright (c) 2020 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
|
||||
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 deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
v1 "k8s.io/api/core/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 *DNSAnnotation) DeepCopyInto(out *DNSAnnotation) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
out.Status = in.Status
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DNSAnnotation.
|
||||
func (in *DNSAnnotation) DeepCopy() *DNSAnnotation {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DNSAnnotation)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *DNSAnnotation) 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 *DNSAnnotationList) DeepCopyInto(out *DNSAnnotationList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]DNSAnnotation, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DNSAnnotationList.
|
||||
func (in *DNSAnnotationList) DeepCopy() *DNSAnnotationList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DNSAnnotationList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *DNSAnnotationList) 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 *DNSAnnotationSpec) DeepCopyInto(out *DNSAnnotationSpec) {
|
||||
*out = *in
|
||||
out.ResourceRef = in.ResourceRef
|
||||
if in.Annotations != nil {
|
||||
in, out := &in.Annotations, &out.Annotations
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DNSAnnotationSpec.
|
||||
func (in *DNSAnnotationSpec) DeepCopy() *DNSAnnotationSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DNSAnnotationSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *DNSAnnotationStatus) DeepCopyInto(out *DNSAnnotationStatus) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DNSAnnotationStatus.
|
||||
func (in *DNSAnnotationStatus) DeepCopy() *DNSAnnotationStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DNSAnnotationStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *DNSEntry) DeepCopyInto(out *DNSEntry) {
|
||||
*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 DNSEntry.
|
||||
func (in *DNSEntry) DeepCopy() *DNSEntry {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DNSEntry)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *DNSEntry) 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 *DNSEntryList) DeepCopyInto(out *DNSEntryList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]DNSEntry, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DNSEntryList.
|
||||
func (in *DNSEntryList) DeepCopy() *DNSEntryList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DNSEntryList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *DNSEntryList) 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 *DNSEntrySpec) DeepCopyInto(out *DNSEntrySpec) {
|
||||
*out = *in
|
||||
if in.Reference != nil {
|
||||
in, out := &in.Reference, &out.Reference
|
||||
*out = new(EntryReference)
|
||||
**out = **in
|
||||
}
|
||||
if in.OwnerId != nil {
|
||||
in, out := &in.OwnerId, &out.OwnerId
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.TTL != nil {
|
||||
in, out := &in.TTL, &out.TTL
|
||||
*out = new(int64)
|
||||
**out = **in
|
||||
}
|
||||
if in.CNameLookupInterval != nil {
|
||||
in, out := &in.CNameLookupInterval, &out.CNameLookupInterval
|
||||
*out = new(int64)
|
||||
**out = **in
|
||||
}
|
||||
if in.Text != nil {
|
||||
in, out := &in.Text, &out.Text
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Targets != nil {
|
||||
in, out := &in.Targets, &out.Targets
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DNSEntrySpec.
|
||||
func (in *DNSEntrySpec) DeepCopy() *DNSEntrySpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DNSEntrySpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *DNSEntryStatus) DeepCopyInto(out *DNSEntryStatus) {
|
||||
*out = *in
|
||||
if in.Message != nil {
|
||||
in, out := &in.Message, &out.Message
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.ProviderType != nil {
|
||||
in, out := &in.ProviderType, &out.ProviderType
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.Provider != nil {
|
||||
in, out := &in.Provider, &out.Provider
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.Zone != nil {
|
||||
in, out := &in.Zone, &out.Zone
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.TTL != nil {
|
||||
in, out := &in.TTL, &out.TTL
|
||||
*out = new(int64)
|
||||
**out = **in
|
||||
}
|
||||
if in.Targets != nil {
|
||||
in, out := &in.Targets, &out.Targets
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DNSEntryStatus.
|
||||
func (in *DNSEntryStatus) DeepCopy() *DNSEntryStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DNSEntryStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *DNSOwner) DeepCopyInto(out *DNSOwner) {
|
||||
*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 DNSOwner.
|
||||
func (in *DNSOwner) DeepCopy() *DNSOwner {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DNSOwner)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *DNSOwner) 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 *DNSOwnerList) DeepCopyInto(out *DNSOwnerList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]DNSOwner, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DNSOwnerList.
|
||||
func (in *DNSOwnerList) DeepCopy() *DNSOwnerList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DNSOwnerList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *DNSOwnerList) 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 *DNSOwnerSpec) DeepCopyInto(out *DNSOwnerSpec) {
|
||||
*out = *in
|
||||
if in.Active != nil {
|
||||
in, out := &in.Active, &out.Active
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DNSOwnerSpec.
|
||||
func (in *DNSOwnerSpec) DeepCopy() *DNSOwnerSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DNSOwnerSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *DNSOwnerStatus) DeepCopyInto(out *DNSOwnerStatus) {
|
||||
*out = *in
|
||||
in.Entries.DeepCopyInto(&out.Entries)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DNSOwnerStatus.
|
||||
func (in *DNSOwnerStatus) DeepCopy() *DNSOwnerStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DNSOwnerStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *DNSOwnerStatusEntries) DeepCopyInto(out *DNSOwnerStatusEntries) {
|
||||
*out = *in
|
||||
if in.ByType != nil {
|
||||
in, out := &in.ByType, &out.ByType
|
||||
*out = make(map[string]int, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DNSOwnerStatusEntries.
|
||||
func (in *DNSOwnerStatusEntries) DeepCopy() *DNSOwnerStatusEntries {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DNSOwnerStatusEntries)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *DNSProvider) DeepCopyInto(out *DNSProvider) {
|
||||
*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 DNSProvider.
|
||||
func (in *DNSProvider) DeepCopy() *DNSProvider {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DNSProvider)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *DNSProvider) 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 *DNSProviderList) DeepCopyInto(out *DNSProviderList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]DNSProvider, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DNSProviderList.
|
||||
func (in *DNSProviderList) DeepCopy() *DNSProviderList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DNSProviderList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *DNSProviderList) 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 *DNSProviderSpec) DeepCopyInto(out *DNSProviderSpec) {
|
||||
*out = *in
|
||||
if in.ProviderConfig != nil {
|
||||
in, out := &in.ProviderConfig, &out.ProviderConfig
|
||||
*out = new(runtime.RawExtension)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.SecretRef != nil {
|
||||
in, out := &in.SecretRef, &out.SecretRef
|
||||
*out = new(v1.SecretReference)
|
||||
**out = **in
|
||||
}
|
||||
if in.Domains != nil {
|
||||
in, out := &in.Domains, &out.Domains
|
||||
*out = new(DNSSelection)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.Zones != nil {
|
||||
in, out := &in.Zones, &out.Zones
|
||||
*out = new(DNSSelection)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DNSProviderSpec.
|
||||
func (in *DNSProviderSpec) DeepCopy() *DNSProviderSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DNSProviderSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *DNSProviderStatus) DeepCopyInto(out *DNSProviderStatus) {
|
||||
*out = *in
|
||||
if in.Message != nil {
|
||||
in, out := &in.Message, &out.Message
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
in.Domains.DeepCopyInto(&out.Domains)
|
||||
in.Zones.DeepCopyInto(&out.Zones)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DNSProviderStatus.
|
||||
func (in *DNSProviderStatus) DeepCopy() *DNSProviderStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DNSProviderStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *DNSSelection) DeepCopyInto(out *DNSSelection) {
|
||||
*out = *in
|
||||
if in.Include != nil {
|
||||
in, out := &in.Include, &out.Include
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Exclude != nil {
|
||||
in, out := &in.Exclude, &out.Exclude
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DNSSelection.
|
||||
func (in *DNSSelection) DeepCopy() *DNSSelection {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DNSSelection)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *DNSSelectionStatus) DeepCopyInto(out *DNSSelectionStatus) {
|
||||
*out = *in
|
||||
if in.Included != nil {
|
||||
in, out := &in.Included, &out.Included
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Excluded != nil {
|
||||
in, out := &in.Excluded, &out.Excluded
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DNSSelectionStatus.
|
||||
func (in *DNSSelectionStatus) DeepCopy() *DNSSelectionStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DNSSelectionStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *EntryReference) DeepCopyInto(out *EntryReference) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EntryReference.
|
||||
func (in *EntryReference) DeepCopy() *EntryReference {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(EntryReference)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ResourceReference) DeepCopyInto(out *ResourceReference) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceReference.
|
||||
func (in *ResourceReference) DeepCopy() *ResourceReference {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ResourceReference)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
+288
@@ -0,0 +1,288 @@
|
||||
```
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
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.
|
||||
```
|
||||
|
||||
## APIs
|
||||
|
||||
This project may include APIs to SAP or third party products or services. The use of these APIs, products and services may be subject to additional agreements. In no event shall the application of the Apache Software License, v.2 to this project grant any rights in or to these APIs, products or services that would alter, expand, be inconsistent with, or supersede any terms of these additional agreements. API means application programming interfaces, as well as their respective specifications and implementing code that allows other software products to communicate with or call on SAP or third party products or services (for example, SAP Enterprise Services, BAPIs, Idocs, RFCs and ABAP calls or other user exits) and may be made available through SAP or third party products, SDKs, documentation or other media.
|
||||
|
||||
## Subcomponents
|
||||
|
||||
This project includes the following subcomponents that are subject to separate license terms.
|
||||
Your use of these subcomponents is subject to the separate license terms applicable to
|
||||
each subcomponent.
|
||||
|
||||
Gardener.
|
||||
https://github.com/gardener/gardener.
|
||||
Copyright (c) 2019 SAP SE or an SAP affiliate company.
|
||||
Apache 2 license (https://github.com/gardener/gardener/blob/master/LICENSE.md).
|
||||
|
||||
controller-runtime.
|
||||
https://sigs.k8s.io/controller-runtime.
|
||||
Copyright 2019 The Kubernetes Authors.
|
||||
Apache 2 license (https://sigs.k8s.io/controller-runtime/LICENSE).
|
||||
|
||||
API.
|
||||
https://git.k8s.io/api.
|
||||
Copyright 2019 The Kubernetes Authors.
|
||||
Apache 2 license (https://git.k8s.io/api/LICENSE).
|
||||
|
||||
APIMachinery.
|
||||
https://git.k8s.io/apimachinery.
|
||||
Copyright 2019 The Kubernetes Authors.
|
||||
Apache 2 license (https://git.k8s.io/apimachinery/LICENSE).
|
||||
|
||||
Client-Go.
|
||||
https://git.k8s.io/client-go.
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
Apache 2 license (https://git.k8s.io/client-go/LICENSE).
|
||||
|
||||
YAML marshaling and unmarshalling support for Go.
|
||||
gopkg.in/yaml.v2.
|
||||
Copyright 2011-2016 Canonical Ltd.
|
||||
Apache 2 license (https://github.com/go-yaml/yaml/blob/v2/LICENSE)
|
||||
|
||||
Packr.
|
||||
https://github.com/gobuffalo/packr
|
||||
Copyright (c) 2016 Mark Bates.
|
||||
MIT license (https://github.com/gobuffalo/packr/blob/master/LICENSE.txt)
|
||||
|
||||
Cobra.
|
||||
https://github.com/spf13/cobra
|
||||
Copyright 2019 Steve Francia.
|
||||
Apache 2 license (https://github.com/spf13/cobra/blob/master/LICENSE.txt)
|
||||
|
||||
Ginkgo.
|
||||
https://github.com/onsi/ginkgo.
|
||||
Copyright (c) 2013-2014 Onsi Fakhouri.
|
||||
MIT license (https://github.com/onsi/ginkgo/blob/master/LICENSE)
|
||||
|
||||
Gomega.
|
||||
github.com/onsi/gomega.
|
||||
Copyright (c) 2013-2014 Onsi Fakhouri.
|
||||
MIT license (https://github.com/onsi/gomega/blob/master/LICENSE)
|
||||
|
||||
------
|
||||
## MIT License
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) <year> <owner>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
## Gardener Resource Manager
|
||||
Copyright (c) 2017-2019 SAP SE or an SAP affiliate company. All rights reserved.
|
||||
|
||||
## Seed Source
|
||||
|
||||
The source code of this component was seeded based on a copy of the following files from [github.com/kubernetes-sigs](github.com/kubernetes-sigs):
|
||||
|
||||
controller-runtime.
|
||||
https://sigs.k8s.io/controller-runtime.
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
Apache 2 license (https://sigs.k8s.io/controller-runtime/LICENSE).
|
||||
|
||||
Version: 0.1.9.
|
||||
Commit-ID: f6f0bc9611363b43664d08fb097ab13243ef621d
|
||||
Commit-Message: Merge pull request #263 from DirectXMan12/release/v0.1.9
|
||||
Generated
Vendored
+18
@@ -0,0 +1,18 @@
|
||||
// Copyright (c) 2018 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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 resources
|
||||
|
||||
// GroupName is the group name use in this package
|
||||
const GroupName = "resources.gardener.cloud"
|
||||
Generated
Vendored
+24
@@ -0,0 +1,24 @@
|
||||
// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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.
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
// +k8s:conversion-gen=github.com/gardener/gardener-resource-manager/pkg/apis/resources
|
||||
// +k8s:openapi-gen=true
|
||||
// +k8s:defaulter-gen=TypeMeta
|
||||
|
||||
//go:generate ../../../../hack/update-codegen.sh
|
||||
|
||||
// Package v1alpha1 contains the configuration of the Gardener Resource Manager.
|
||||
// +groupName=resources.gardener.cloud
|
||||
package v1alpha1 // import "github.com/gardener/gardener-resource-manager/pkg/apis/resources/v1alpha1"
|
||||
Generated
Vendored
+51
@@ -0,0 +1,51 @@
|
||||
// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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 v1alpha1
|
||||
|
||||
import (
|
||||
resources "github.com/gardener/gardener-resource-manager/pkg/apis/resources"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
var SchemeGroupVersion = schema.GroupVersion{Group: resources.GroupName, Version: "v1alpha1"}
|
||||
|
||||
// Kind takes an unqualified kind and returns back a Group qualified GroupKind
|
||||
func Kind(kind string) schema.GroupKind {
|
||||
return SchemeGroupVersion.WithKind(kind).GroupKind()
|
||||
}
|
||||
|
||||
// Resource takes an unqualified resource and returns a Group qualified GroupResource
|
||||
func Resource(resource string) schema.GroupResource {
|
||||
return SchemeGroupVersion.WithResource(resource).GroupResource()
|
||||
}
|
||||
|
||||
var (
|
||||
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
|
||||
AddToScheme = SchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
// Adds the list of known types to Scheme.
|
||||
func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&ManagedResource{},
|
||||
&ManagedResourceList{},
|
||||
)
|
||||
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
|
||||
return nil
|
||||
}
|
||||
Generated
Vendored
+170
@@ -0,0 +1,170 @@
|
||||
// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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 v1alpha1
|
||||
|
||||
import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
const (
|
||||
// Ignore is an annotation that dictates whether a resources should be ignored during
|
||||
// reconciliation.
|
||||
Ignore = "resources.gardener.cloud/ignore"
|
||||
// DeleteOnInvalidUpdate is a constant for an annotation on a resource managed by a ManagedResource. If set to
|
||||
// true then the controller will delete the object in case it faces an "Invalid" response during an update operation.
|
||||
DeleteOnInvalidUpdate = "resources.gardener.cloud/delete-on-invalid-update"
|
||||
// KeepObject is a constant for an annotation on a resource managed by a ManagedResource. If set to
|
||||
// true then the controller will not delete the object in case it is removed from the ManagedResource or the
|
||||
// ManagedResource itself is deleted.
|
||||
KeepObject = "resources.gardener.cloud/keep-object"
|
||||
)
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// ManagedResource describes a list of managed resources.
|
||||
type ManagedResource struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
// Standard object metadata.
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
// Spec contains the specification of this managed resource.
|
||||
Spec ManagedResourceSpec `json:"spec,omitempty"`
|
||||
// Status contains the status of this managed resource.
|
||||
Status ManagedResourceStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// ManagedResourceList is a list of ManagedResource resources.
|
||||
type ManagedResourceList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
// +optional
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Items is the list of ManagedResource.
|
||||
Items []ManagedResource `json:"items"`
|
||||
}
|
||||
|
||||
type ManagedResourceSpec struct {
|
||||
// Class holds the resource class used to control the responsibility for multiple resource manager instances
|
||||
// +optional
|
||||
Class *string `json:"class,omitempty"`
|
||||
// SecretRefs is a list of secret references.
|
||||
SecretRefs []corev1.LocalObjectReference `json:"secretRefs"`
|
||||
// InjectLabels injects the provided labels into every resource that is part of the referenced secrets.
|
||||
// +optional
|
||||
InjectLabels map[string]string `json:"injectLabels,omitempty"`
|
||||
// ForceOverwriteLabels specifies that all existing labels should be overwritten. Defaults to false.
|
||||
// +optional
|
||||
ForceOverwriteLabels *bool `json:"forceOverwriteLabels,omitempty"`
|
||||
// ForceOverwriteAnnotations specifies that all existing annotations should be overwritten. Defaults to false.
|
||||
// +optional
|
||||
ForceOverwriteAnnotations *bool `json:"forceOverwriteAnnotations,omitempty"`
|
||||
// KeepObjects specifies whether the objects should be kept although the managed resource has already been deleted.
|
||||
// Defaults to false.
|
||||
// +optional
|
||||
KeepObjects *bool `json:"keepObjects,omitempty"`
|
||||
// Equivalences specifies possible group/kind equivalences for objects.
|
||||
// +optional
|
||||
Equivalences [][]metav1.GroupKind `json:"equivalences,omitempty"`
|
||||
// DeletePersistentVolumeClaims specifies if PersistentVolumeClaims created by StatefulSets, which are managed by this
|
||||
// resource, should also be deleted when the corresponding StatefulSet is deleted (defaults to false).
|
||||
// +optional
|
||||
DeletePersistentVolumeClaims *bool `json:"deletePersistentVolumeClaims,omitempty"`
|
||||
}
|
||||
|
||||
// ManagedResourceStatus is the status of a managed resource.
|
||||
type ManagedResourceStatus struct {
|
||||
Conditions []ManagedResourceCondition `json:"conditions,omitempty"`
|
||||
// ObservedGeneration is the most recent generation observed for this resource.
|
||||
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
|
||||
// Resources is a list of objects that have been created.
|
||||
// +optional
|
||||
Resources []ObjectReference `json:"resources,omitempty"`
|
||||
}
|
||||
|
||||
type ObjectReference struct {
|
||||
corev1.ObjectReference `json:",inline"`
|
||||
// Labels is a map of labels that were used during last update of the resource.
|
||||
Labels map[string]string `json:"labels,omitempty"`
|
||||
// Annotations is a map of annotations that were used during last update of the resource.
|
||||
Annotations map[string]string `json:"annotations,omitempty"`
|
||||
}
|
||||
|
||||
// ConditionType is the type of a condition.
|
||||
type ConditionType string
|
||||
|
||||
const (
|
||||
// ResourcesApplied is a condition type that indicates whether all resources are applied to the target cluster.
|
||||
ResourcesApplied ConditionType = "ResourcesApplied"
|
||||
// ResourcesHealthy is a condition type that indicates whether all resources are present and healthy.
|
||||
ResourcesHealthy ConditionType = "ResourcesHealthy"
|
||||
)
|
||||
|
||||
// ConditionStatus is the status of a condition.
|
||||
type ConditionStatus string
|
||||
|
||||
// These are valid condition statuses.
|
||||
const (
|
||||
// ConditionTrue means a resource is in the condition.
|
||||
ConditionTrue ConditionStatus = "True"
|
||||
// ConditionFalse means a resource is not in the condition.
|
||||
ConditionFalse ConditionStatus = "False"
|
||||
// ConditionUnknown means that the controller can't decide if a resource is in the condition or not
|
||||
ConditionUnknown ConditionStatus = "Unknown"
|
||||
// ConditionProgressing means that the controller is currently acting on the resource and the condition is therefore progressing.
|
||||
ConditionProgressing ConditionStatus = "Progressing"
|
||||
)
|
||||
|
||||
// These are well-known reasons for ManagedResourceConditions.
|
||||
const (
|
||||
// ConditionApplySucceeded indicates that the `ResourcesApplied` condition is `True`,
|
||||
// because all resources have been applied successfully.
|
||||
ConditionApplySucceeded = "ApplySucceeded"
|
||||
// ConditionApplyFailed indicates that the `ResourcesApplied` condition is `False`,
|
||||
// because applying the resources failed.
|
||||
ConditionApplyFailed = "ApplyFailed"
|
||||
// ConditionDecodingFailed indicates that the `ResourcesApplied` condition is `False`,
|
||||
// because decoding the resources of the ManagedResource failed.
|
||||
ConditionDecodingFailed = "DecodingFailed"
|
||||
// ConditionApplyProgressing indicates that the `ResourcesApplied` condition is `Progressing`,
|
||||
// because the resources are currently being reconciled.
|
||||
ConditionApplyProgressing = "ApplyProgressing"
|
||||
// ConditionDeletionFailed indicates that the `ResourcesApplied` condition is `False`,
|
||||
// because deleting the resources failed.
|
||||
ConditionDeletionFailed = "DeletionFailed"
|
||||
// ConditionDeletionPending indicates that the `ResourcesApplied` condition is `Progressing`,
|
||||
// because the deletion of some resources are still pending.
|
||||
ConditionDeletionPending = "DeletionPending"
|
||||
// ConditionHealthChecksPending indicates that the `ResourcesHealthy` condition is `Unknown`,
|
||||
// because the health checks have not been completely executed yet for the current set of resources.
|
||||
ConditionHealthChecksPending = "HealthChecksPending"
|
||||
)
|
||||
|
||||
// ManagedResourceCondition describes the state of a deployment at a certain period.
|
||||
type ManagedResourceCondition struct {
|
||||
// Type of the ManagedResource condition.
|
||||
Type ConditionType `json:"type"`
|
||||
// Status of the ManagedResource condition.
|
||||
Status ConditionStatus `json:"status"`
|
||||
// Last time the condition was updated.
|
||||
LastUpdateTime metav1.Time `json:"lastUpdateTime"`
|
||||
// Last time the condition transitioned from one status to another.
|
||||
LastTransitionTime metav1.Time `json:"lastTransitionTime"`
|
||||
// The reason for the condition's last transition.
|
||||
Reason string `json:"reason"`
|
||||
// A human readable message indicating details about the transition.
|
||||
Message string `json:"message"`
|
||||
}
|
||||
Generated
Vendored
+231
@@ -0,0 +1,231 @@
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright (c) 2020 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
|
||||
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 deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "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 *ManagedResource) DeepCopyInto(out *ManagedResource) {
|
||||
*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 ManagedResource.
|
||||
func (in *ManagedResource) DeepCopy() *ManagedResource {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ManagedResource)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *ManagedResource) 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 *ManagedResourceCondition) DeepCopyInto(out *ManagedResourceCondition) {
|
||||
*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 ManagedResourceCondition.
|
||||
func (in *ManagedResourceCondition) DeepCopy() *ManagedResourceCondition {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ManagedResourceCondition)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ManagedResourceList) DeepCopyInto(out *ManagedResourceList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]ManagedResource, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ManagedResourceList.
|
||||
func (in *ManagedResourceList) DeepCopy() *ManagedResourceList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ManagedResourceList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *ManagedResourceList) 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 *ManagedResourceSpec) DeepCopyInto(out *ManagedResourceSpec) {
|
||||
*out = *in
|
||||
if in.Class != nil {
|
||||
in, out := &in.Class, &out.Class
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.SecretRefs != nil {
|
||||
in, out := &in.SecretRefs, &out.SecretRefs
|
||||
*out = make([]v1.LocalObjectReference, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.InjectLabels != nil {
|
||||
in, out := &in.InjectLabels, &out.InjectLabels
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.ForceOverwriteLabels != nil {
|
||||
in, out := &in.ForceOverwriteLabels, &out.ForceOverwriteLabels
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
if in.ForceOverwriteAnnotations != nil {
|
||||
in, out := &in.ForceOverwriteAnnotations, &out.ForceOverwriteAnnotations
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
if in.KeepObjects != nil {
|
||||
in, out := &in.KeepObjects, &out.KeepObjects
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
if in.Equivalences != nil {
|
||||
in, out := &in.Equivalences, &out.Equivalences
|
||||
*out = make([][]metav1.GroupKind, len(*in))
|
||||
for i := range *in {
|
||||
if (*in)[i] != nil {
|
||||
in, out := &(*in)[i], &(*out)[i]
|
||||
*out = make([]metav1.GroupKind, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
}
|
||||
if in.DeletePersistentVolumeClaims != nil {
|
||||
in, out := &in.DeletePersistentVolumeClaims, &out.DeletePersistentVolumeClaims
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ManagedResourceSpec.
|
||||
func (in *ManagedResourceSpec) DeepCopy() *ManagedResourceSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ManagedResourceSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ManagedResourceStatus) DeepCopyInto(out *ManagedResourceStatus) {
|
||||
*out = *in
|
||||
if in.Conditions != nil {
|
||||
in, out := &in.Conditions, &out.Conditions
|
||||
*out = make([]ManagedResourceCondition, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.Resources != nil {
|
||||
in, out := &in.Resources, &out.Resources
|
||||
*out = make([]ObjectReference, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ManagedResourceStatus.
|
||||
func (in *ManagedResourceStatus) DeepCopy() *ManagedResourceStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ManagedResourceStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ObjectReference) DeepCopyInto(out *ObjectReference) {
|
||||
*out = *in
|
||||
out.ObjectReference = in.ObjectReference
|
||||
if in.Labels != nil {
|
||||
in, out := &in.Labels, &out.Labels
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.Annotations != nil {
|
||||
in, out := &in.Annotations, &out.Annotations
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObjectReference.
|
||||
func (in *ObjectReference) DeepCopy() *ObjectReference {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ObjectReference)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
Generated
Vendored
+120
@@ -0,0 +1,120 @@
|
||||
// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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 manager
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
resourcesv1alpha1 "github.com/gardener/gardener-resource-manager/pkg/apis/resources/v1alpha1"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
|
||||
)
|
||||
|
||||
type ManagedResource struct {
|
||||
client client.Client
|
||||
resource *resourcesv1alpha1.ManagedResource
|
||||
}
|
||||
|
||||
func NewManagedResource(client client.Client) *ManagedResource {
|
||||
return &ManagedResource{
|
||||
client: client,
|
||||
resource: &resourcesv1alpha1.ManagedResource{},
|
||||
}
|
||||
}
|
||||
|
||||
func (m *ManagedResource) WithNamespacedName(namespace, name string) *ManagedResource {
|
||||
m.resource.Namespace = namespace
|
||||
m.resource.Name = name
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *ManagedResource) WithLabels(labels map[string]string) *ManagedResource {
|
||||
m.resource.Labels = labels
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *ManagedResource) WithAnnotations(annotations map[string]string) *ManagedResource {
|
||||
m.resource.Annotations = annotations
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *ManagedResource) WithClass(name string) *ManagedResource {
|
||||
if name == "" {
|
||||
m.resource.Spec.Class = nil
|
||||
} else {
|
||||
m.resource.Spec.Class = &name
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *ManagedResource) WithSecretRef(secretRefName string) *ManagedResource {
|
||||
m.resource.Spec.SecretRefs = append(m.resource.Spec.SecretRefs, corev1.LocalObjectReference{Name: secretRefName})
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *ManagedResource) WithSecretRefs(secretRefs []corev1.LocalObjectReference) *ManagedResource {
|
||||
m.resource.Spec.SecretRefs = append(m.resource.Spec.SecretRefs, secretRefs...)
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *ManagedResource) WithInjectedLabels(labelsToInject map[string]string) *ManagedResource {
|
||||
m.resource.Spec.InjectLabels = labelsToInject
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *ManagedResource) ForceOverwriteAnnotations(v bool) *ManagedResource {
|
||||
m.resource.Spec.ForceOverwriteAnnotations = &v
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *ManagedResource) ForceOverwriteLabels(v bool) *ManagedResource {
|
||||
m.resource.Spec.ForceOverwriteLabels = &v
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *ManagedResource) KeepObjects(v bool) *ManagedResource {
|
||||
m.resource.Spec.KeepObjects = &v
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *ManagedResource) DeletePersistentVolumeClaims(v bool) *ManagedResource {
|
||||
m.resource.Spec.DeletePersistentVolumeClaims = &v
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *ManagedResource) Reconcile(ctx context.Context) error {
|
||||
resource := &resourcesv1alpha1.ManagedResource{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: m.resource.Name, Namespace: m.resource.Namespace},
|
||||
}
|
||||
|
||||
_, err := controllerutil.CreateOrUpdate(ctx, m.client, resource, func() error {
|
||||
resource.Labels = m.resource.Labels
|
||||
resource.Annotations = m.resource.Annotations
|
||||
resource.Spec = m.resource.Spec
|
||||
return nil
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *ManagedResource) Delete(ctx context.Context) error {
|
||||
if err := m.client.Delete(ctx, m.resource); err != nil && !apierrors.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Generated
Vendored
+124
@@ -0,0 +1,124 @@
|
||||
// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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 manager
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
|
||||
)
|
||||
|
||||
type Secret struct {
|
||||
client client.Client
|
||||
|
||||
keyValues map[string]string
|
||||
secret *corev1.Secret
|
||||
}
|
||||
|
||||
func NewSecret(client client.Client) *Secret {
|
||||
return &Secret{
|
||||
client: client,
|
||||
keyValues: make(map[string]string),
|
||||
secret: &corev1.Secret{},
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Secret) WithNamespacedName(namespace, name string) *Secret {
|
||||
s.secret.Namespace = namespace
|
||||
s.secret.Name = name
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *Secret) WithLabels(labels map[string]string) *Secret {
|
||||
s.secret.Labels = labels
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *Secret) WithAnnotations(annotations map[string]string) *Secret {
|
||||
s.secret.Annotations = annotations
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *Secret) WithKeyValues(keyValues map[string][]byte) *Secret {
|
||||
s.secret.Data = keyValues
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *Secret) Reconcile(ctx context.Context) error {
|
||||
secret := &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: s.secret.Name, Namespace: s.secret.Namespace},
|
||||
}
|
||||
|
||||
_, err := controllerutil.CreateOrUpdate(ctx, s.client, secret, func() error {
|
||||
secret.Labels = s.secret.Labels
|
||||
secret.Annotations = s.secret.Annotations
|
||||
secret.Type = corev1.SecretTypeOpaque
|
||||
secret.Data = s.secret.Data
|
||||
return nil
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *Secret) Delete(ctx context.Context) error {
|
||||
if err := s.client.Delete(ctx, s.secret); err != nil && !apierrors.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Secrets struct {
|
||||
client client.Client
|
||||
|
||||
secrets []Secret
|
||||
}
|
||||
|
||||
func NewSecrets(client client.Client) *Secrets {
|
||||
return &Secrets{
|
||||
client: client,
|
||||
secrets: []Secret{},
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Secrets) WithSecretList(secrets []Secret) *Secrets {
|
||||
s.secrets = append(s.secrets, secrets...)
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *Secrets) WithSecret(secrets Secret) *Secrets {
|
||||
s.secrets = append(s.secrets, secrets)
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *Secrets) Reconcile(ctx context.Context) error {
|
||||
for _, secret := range s.secrets {
|
||||
if err := secret.Reconcile(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Secrets) Delete(ctx context.Context) error {
|
||||
for _, secret := range s.secrets {
|
||||
if err := secret.Delete(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
---
|
||||
name: Bug Report
|
||||
about: Report a bug encountered while operating Gardener
|
||||
labels: kind/bug
|
||||
|
||||
---
|
||||
|
||||
**How to categorize this issue?**
|
||||
<!--
|
||||
Please select area, kind, and priority for this issue. This helps the community categorizing it.
|
||||
Replace below TODOs or exchange the existing identifiers with those that fit best in your opinion.
|
||||
If multiple identifiers make sense you can also state the commands multiple times, e.g.
|
||||
/area control-plane
|
||||
/area auto-scaling
|
||||
...
|
||||
|
||||
"/area" identifiers: audit-logging|auto-scaling|backup|certification|control-plane-migration|control-plane|cost|delivery|dev-productivity|disaster-recovery|documentation|high-availability|logging|metering|monitoring|networking|open-source|operations|ops-productivity|os|performance|quality|robustness|scalability|security|storage|testing|usability|user-management
|
||||
"/kind" identifiers: api-change|bug|cleanup|discussion|enhancement|epic|impediment|poc|post-mortem|question|regression|task|technical-debt|test
|
||||
"/priority" identifiers: normal|critical|blocker
|
||||
-->
|
||||
/area TODO
|
||||
/kind bug
|
||||
/priority normal
|
||||
|
||||
**What happened**:
|
||||
|
||||
**What you expected to happen**:
|
||||
|
||||
**How to reproduce it (as minimally and precisely as possible)**:
|
||||
|
||||
**Anything else we need to know?**:
|
||||
|
||||
**Environment**:
|
||||
|
||||
- Gardener version:
|
||||
- Kubernetes version (use `kubectl version`):
|
||||
- Cloud provider or hardware configuration:
|
||||
- Others:
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// Copyright (c) 2020 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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.
|
||||
|
||||
// This package imports GitHub related templates - it is to force `go mod` to see them as dependencies.
|
||||
package issue_template
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
---
|
||||
name: Enhancement Request
|
||||
about: Suggest an enhancement to the Gardener project
|
||||
labels: kind/enhancement
|
||||
|
||||
---
|
||||
|
||||
**How to categorize this issue?**
|
||||
<!--
|
||||
Please select area, kind, and priority for this issue. This helps the community categorizing it.
|
||||
Replace below TODOs or exchange the existing identifiers with those that fit best in your opinion.
|
||||
If multiple identifiers make sense you can also state the commands multiple times, e.g.
|
||||
/area control-plane
|
||||
/area auto-scaling
|
||||
...
|
||||
|
||||
"/area" identifiers: audit-logging|auto-scaling|backup|certification|control-plane-migration|control-plane|cost|delivery|dev-productivity|disaster-recovery|documentation|high-availability|logging|metering|monitoring|networking|open-source|operations|ops-productivity|os|performance|quality|robustness|scalability|security|storage|testing|usability|user-management
|
||||
"/kind" identifiers: api-change|bug|cleanup|discussion|enhancement|epic|impediment|poc|post-mortem|question|regression|task|technical-debt|test
|
||||
"/priority" identifiers: normal|critical|blocker
|
||||
-->
|
||||
/area TODO
|
||||
/kind enhancement
|
||||
/priority normal
|
||||
|
||||
**What would you like to be added**:
|
||||
|
||||
**Why is this needed**:
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
---
|
||||
name: Flaking Test
|
||||
about: Report flaky tests or jobs in Gardener CI
|
||||
title: "[Flaky Test] FLAKING TEST/SUITE"
|
||||
labels: kind/flake
|
||||
|
||||
---
|
||||
|
||||
<!-- Please only use this template for submitting reports about flaky tests or jobs (pass or fail with no underlying change in code) in Gardener CI -->
|
||||
|
||||
**How to categorize this issue?**
|
||||
<!--
|
||||
Please select area, kind, and priority for this issue. This helps the community categorizing it.
|
||||
Replace below TODOs or exchange the existing identifiers with those that fit best in your opinion.
|
||||
If multiple identifiers make sense you can also state the commands multiple times, e.g.
|
||||
/area control-plane
|
||||
/area auto-scaling
|
||||
...
|
||||
|
||||
"/area" identifiers: audit-logging|auto-scaling|backup|certification|control-plane-migration|control-plane|cost|delivery|dev-productivity|disaster-recovery|documentation|high-availability|logging|metering|monitoring|networking|open-source|operations|ops-productivity|os|performance|quality|robustness|scalability|security|storage|testing|usability|user-management
|
||||
"/kind" identifiers: api-change|bug|cleanup|discussion|enhancement|epic|impediment|poc|post-mortem|question|regression|task|technical-debt|test
|
||||
"/priority" identifiers: normal|critical|blocker
|
||||
-->
|
||||
/area testing
|
||||
/kind flake
|
||||
/priority normal
|
||||
|
||||
**Which test(s)/suite(s) are flaking**:
|
||||
|
||||
**CI link**:
|
||||
|
||||
**Reason for failure**:
|
||||
|
||||
**Anything else we need to know**:
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
---
|
||||
name: Support Request
|
||||
about: Support request or question relating to Gardener
|
||||
labels: kind/question
|
||||
|
||||
---
|
||||
|
||||
<!--
|
||||
STOP -- PLEASE READ!
|
||||
|
||||
GitHub is not the right place for support requests.
|
||||
|
||||
If you're looking for help, please post your question on the [Kubernetes Slack](http://slack.k8s.io/) ([#gardener](https://kubernetes.slack.com/messages/gardener) channel) or join our [weekly meetings](https://github.com/gardener/documentation/blob/master/CONTRIBUTING.md#weekly-meeting).
|
||||
-->
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// Copyright (c) 2020 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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.
|
||||
|
||||
// This package imports GitHub related templates - it is to force `go mod` to see them as dependencies.
|
||||
package github
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
**How to categorize this PR?**
|
||||
<!--
|
||||
Please select area, kind, and priority for this pull request. This helps the community categorizing it.
|
||||
Replace below TODOs or exchange the existing identifiers with those that fit best in your opinion.
|
||||
If multiple identifiers make sense you can also state the commands multiple times, e.g.
|
||||
/area control-plane
|
||||
/area auto-scaling
|
||||
...
|
||||
|
||||
"/area" identifiers: audit-logging|auto-scaling|backup|certification|control-plane-migration|control-plane|cost|delivery|dev-productivity|disaster-recovery|documentation|high-availability|logging|metering|monitoring|networking|open-source|ops-productivity|os|performance|quality|robustness|scalability|security|storage|testing|usability|user-management
|
||||
"/kind" identifiers: api-change|bug|cleanup|discussion|enhancement|epic|impediment|poc|post-mortem|question|regression|task|technical-debt|test
|
||||
"/priority" identifiers: normal|critical|blocker
|
||||
|
||||
For Gardener Enhancement Proposals (GEPs), please check the following [documentation](https://github.com/gardener/gardener/tree/master/docs/proposals/README.md) before submitting this pull request.
|
||||
-->
|
||||
/area TODO
|
||||
/kind TODO
|
||||
/priority normal
|
||||
|
||||
**What this PR does / why we need it**:
|
||||
|
||||
**Which issue(s) this PR fixes**:
|
||||
Fixes #
|
||||
|
||||
**Special notes for your reviewer**:
|
||||
|
||||
**Release note**:
|
||||
<!--
|
||||
Write your release note:
|
||||
1. Enter your release note in the below block.
|
||||
2. If no release note is required, just write "NONE" within the block.
|
||||
|
||||
Format of block header: <category> <target_group>
|
||||
Possible values:
|
||||
- category: breaking|feature|bugfix|doc|other
|
||||
- target_group: user|operator|developer|dependency
|
||||
-->
|
||||
```other operator
|
||||
|
||||
```
|
||||
+714
@@ -0,0 +1,714 @@
|
||||
```
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
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.
|
||||
```
|
||||
|
||||
## APIs
|
||||
|
||||
This project may include APIs to SAP or third party products or services. The use of these APIs, products and services may be subject to additional agreements. In no event shall the application of the Apache Software License, v.2 to this project grant any rights in or to these APIs, products or services that would alter, expand, be inconsistent with, or supersede any terms of these additional agreements. API means application programming interfaces, as well as their respective specifications and implementing code that allows other software products to communicate with or call on SAP or third party products or services (for example, SAP Enterprise Services, BAPIs, Idocs, RFCs and ABAP calls or other user exits) and may be made available through SAP or third party products, SDKs, documentation or other media.
|
||||
|
||||
## Subcomponents
|
||||
|
||||
This project includes the following subcomponents that are subject to separate license terms.
|
||||
Your use of these subcomponents is subject to the separate license terms applicable to
|
||||
each subcomponent.
|
||||
|
||||
API.
|
||||
https://git.k8s.io/api.
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
Apache 2 license (https://git.k8s.io/api/LICENSE).
|
||||
|
||||
APIMachinery.
|
||||
https://git.k8s.io/apimachinery.
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
Apache 2 license (https://git.k8s.io/apimachinery/LICENSE).
|
||||
|
||||
APIServer.
|
||||
https://git.k8s.io/apiserver.
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
Apache 2 license (https://git.k8s.io/apiserver/LICENSE).
|
||||
|
||||
Client-Go.
|
||||
https://git.k8s.io/client-go.
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
Apache 2 license (https://git.k8s.io/client-go/LICENSE).
|
||||
|
||||
Code-Generator.
|
||||
https://git.k8s.io/code-generator.
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
Apache 2 license (https://git.k8s.io/code-generator/LICENSE)
|
||||
|
||||
Gengo.
|
||||
https://git.k8s.io/gengo.
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
Apache 2 license (https://git.k8s.io/gengo/LICENSE)
|
||||
|
||||
Helm.
|
||||
https://git.k8s.io/helm.
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
Apache 2 license (https://git.k8s.io/helm/LICENSE)
|
||||
|
||||
controller-runtime
|
||||
https://github.com/kubernetes-sigs/controller-runtime
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
Apache 2 license (https://github.com/kubernetes-sigs/controller-runtime/blob/master/LICENSE).
|
||||
|
||||
Cobra
|
||||
https://github.com/spf13/cobra.
|
||||
Copyright 2015 Steve Francia.
|
||||
Apache 2 license (https://github.com/spf13/cobra/blob/master/LICENSE.txt)
|
||||
|
||||
YAML marshaling and unmarshaling support for Go
|
||||
https://github.com/ghodss/yaml.
|
||||
Copyright (c) 2014 Sam Ghods
|
||||
MIT license (https://github.com/ghodss/yaml/blob/master/LICENSE)
|
||||
|
||||
Logrus
|
||||
https://github.com/sirupsen/logrus.
|
||||
Copyright (c) 2014 Simon Eskildsen
|
||||
MIT license (https://github.com/sirupsen/logrus/blob/master/LICENSE)
|
||||
|
||||
Prometheus Go Client Library.
|
||||
https://github.com/prometheus/client_golang.
|
||||
Copyright 2015 The Prometheus Authors.
|
||||
Apache 2 license (https://github.com/prometheus/client_golang/blob/master/LICENSE)
|
||||
|
||||
SemVer
|
||||
https://github.com/Masterminds/semver.
|
||||
Copyright (C) 2014-2015, Matt Butcher and Matt Farina
|
||||
MIT license (https://github.com/Masterminds/semver/blob/master/LICENSE.txt)
|
||||
|
||||
Cron.
|
||||
https://github.com/robfig/cron.
|
||||
Copyright (C) 2012 Rob Figueiredo.
|
||||
MIT license (https://github.com/robfig/cron/blob/master/LICENSE)
|
||||
|
||||
errors
|
||||
https://github.com/pkg/errors
|
||||
Copyright (c) 2015, Dave Cheney.
|
||||
BSD 2-Clause "Simplified" License (https://github.com/pkg/errors/blob/master/LICENSE)
|
||||
|
||||
go-multierror
|
||||
https://github.com/hashicorp/go-multierror
|
||||
Copyright (c) 2015, Hashicorp.
|
||||
MPL-2.0 (https://github.com/hashicorp/go-multierror/blob/master/LICENSE)
|
||||
|
||||
go-jmespath
|
||||
https://github.com/jmespath/go-jmespath
|
||||
Copyright 2015 James Saryerwinnie
|
||||
Apache License, Version 2 (https://github.com/jmespath/go-jmespath/blob/master/LICENSE)
|
||||
|
||||
------
|
||||
## MIT License
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) <year> <owner>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
------
|
||||
## MPL-2.0 License
|
||||
|
||||
Mozilla Public License Version 2.0
|
||||
==================================
|
||||
|
||||
1. Definitions
|
||||
--------------
|
||||
|
||||
1.1. "Contributor"
|
||||
means each individual or legal entity that creates, contributes to
|
||||
the creation of, or owns Covered Software.
|
||||
|
||||
1.2. "Contributor Version"
|
||||
means the combination of the Contributions of others (if any) used
|
||||
by a Contributor and that particular Contributor's Contribution.
|
||||
|
||||
1.3. "Contribution"
|
||||
means Covered Software of a particular Contributor.
|
||||
|
||||
1.4. "Covered Software"
|
||||
means Source Code Form to which the initial Contributor has attached
|
||||
the notice in Exhibit A, the Executable Form of such Source Code
|
||||
Form, and Modifications of such Source Code Form, in each case
|
||||
including portions thereof.
|
||||
|
||||
1.5. "Incompatible With Secondary Licenses"
|
||||
means
|
||||
|
||||
(a) that the initial Contributor has attached the notice described
|
||||
in Exhibit B to the Covered Software; or
|
||||
|
||||
(b) that the Covered Software was made available under the terms of
|
||||
version 1.1 or earlier of the License, but not also under the
|
||||
terms of a Secondary License.
|
||||
|
||||
1.6. "Executable Form"
|
||||
means any form of the work other than Source Code Form.
|
||||
|
||||
1.7. "Larger Work"
|
||||
means a work that combines Covered Software with other material, in
|
||||
a separate file or files, that is not Covered Software.
|
||||
|
||||
1.8. "License"
|
||||
means this document.
|
||||
|
||||
1.9. "Licensable"
|
||||
means having the right to grant, to the maximum extent possible,
|
||||
whether at the time of the initial grant or subsequently, any and
|
||||
all of the rights conveyed by this License.
|
||||
|
||||
1.10. "Modifications"
|
||||
means any of the following:
|
||||
|
||||
(a) any file in Source Code Form that results from an addition to,
|
||||
deletion from, or modification of the contents of Covered
|
||||
Software; or
|
||||
|
||||
(b) any new file in Source Code Form that contains any Covered
|
||||
Software.
|
||||
|
||||
1.11. "Patent Claims" of a Contributor
|
||||
means any patent claim(s), including without limitation, method,
|
||||
process, and apparatus claims, in any patent Licensable by such
|
||||
Contributor that would be infringed, but for the grant of the
|
||||
License, by the making, using, selling, offering for sale, having
|
||||
made, import, or transfer of either its Contributions or its
|
||||
Contributor Version.
|
||||
|
||||
1.12. "Secondary License"
|
||||
means either the GNU General Public License, Version 2.0, the GNU
|
||||
Lesser General Public License, Version 2.1, the GNU Affero General
|
||||
Public License, Version 3.0, or any later versions of those
|
||||
licenses.
|
||||
|
||||
1.13. "Source Code Form"
|
||||
means the form of the work preferred for making modifications.
|
||||
|
||||
1.14. "You" (or "Your")
|
||||
means an individual or a legal entity exercising rights under this
|
||||
License. For legal entities, "You" includes any entity that
|
||||
controls, is controlled by, or is under common control with You. For
|
||||
purposes of this definition, "control" means (a) the power, direct
|
||||
or indirect, to cause the direction or management of such entity,
|
||||
whether by contract or otherwise, or (b) ownership of more than
|
||||
fifty percent (50%) of the outstanding shares or beneficial
|
||||
ownership of such entity.
|
||||
|
||||
2. License Grants and Conditions
|
||||
--------------------------------
|
||||
|
||||
2.1. Grants
|
||||
|
||||
Each Contributor hereby grants You a world-wide, royalty-free,
|
||||
non-exclusive license:
|
||||
|
||||
(a) under intellectual property rights (other than patent or trademark)
|
||||
Licensable by such Contributor to use, reproduce, make available,
|
||||
modify, display, perform, distribute, and otherwise exploit its
|
||||
Contributions, either on an unmodified basis, with Modifications, or
|
||||
as part of a Larger Work; and
|
||||
|
||||
(b) under Patent Claims of such Contributor to make, use, sell, offer
|
||||
for sale, have made, import, and otherwise transfer either its
|
||||
Contributions or its Contributor Version.
|
||||
|
||||
2.2. Effective Date
|
||||
|
||||
The licenses granted in Section 2.1 with respect to any Contribution
|
||||
become effective for each Contribution on the date the Contributor first
|
||||
distributes such Contribution.
|
||||
|
||||
2.3. Limitations on Grant Scope
|
||||
|
||||
The licenses granted in this Section 2 are the only rights granted under
|
||||
this License. No additional rights or licenses will be implied from the
|
||||
distribution or licensing of Covered Software under this License.
|
||||
Notwithstanding Section 2.1(b) above, no patent license is granted by a
|
||||
Contributor:
|
||||
|
||||
(a) for any code that a Contributor has removed from Covered Software;
|
||||
or
|
||||
|
||||
(b) for infringements caused by: (i) Your and any other third party's
|
||||
modifications of Covered Software, or (ii) the combination of its
|
||||
Contributions with other software (except as part of its Contributor
|
||||
Version); or
|
||||
|
||||
(c) under Patent Claims infringed by Covered Software in the absence of
|
||||
its Contributions.
|
||||
|
||||
This License does not grant any rights in the trademarks, service marks,
|
||||
or logos of any Contributor (except as may be necessary to comply with
|
||||
the notice requirements in Section 3.4).
|
||||
|
||||
2.4. Subsequent Licenses
|
||||
|
||||
No Contributor makes additional grants as a result of Your choice to
|
||||
distribute the Covered Software under a subsequent version of this
|
||||
License (see Section 10.2) or under the terms of a Secondary License (if
|
||||
permitted under the terms of Section 3.3).
|
||||
|
||||
2.5. Representation
|
||||
|
||||
Each Contributor represents that the Contributor believes its
|
||||
Contributions are its original creation(s) or it has sufficient rights
|
||||
to grant the rights to its Contributions conveyed by this License.
|
||||
|
||||
2.6. Fair Use
|
||||
|
||||
This License is not intended to limit any rights You have under
|
||||
applicable copyright doctrines of fair use, fair dealing, or other
|
||||
equivalents.
|
||||
|
||||
2.7. Conditions
|
||||
|
||||
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
|
||||
in Section 2.1.
|
||||
|
||||
3. Responsibilities
|
||||
-------------------
|
||||
|
||||
3.1. Distribution of Source Form
|
||||
|
||||
All distribution of Covered Software in Source Code Form, including any
|
||||
Modifications that You create or to which You contribute, must be under
|
||||
the terms of this License. You must inform recipients that the Source
|
||||
Code Form of the Covered Software is governed by the terms of this
|
||||
License, and how they can obtain a copy of this License. You may not
|
||||
attempt to alter or restrict the recipients' rights in the Source Code
|
||||
Form.
|
||||
|
||||
3.2. Distribution of Executable Form
|
||||
|
||||
If You distribute Covered Software in Executable Form then:
|
||||
|
||||
(a) such Covered Software must also be made available in Source Code
|
||||
Form, as described in Section 3.1, and You must inform recipients of
|
||||
the Executable Form how they can obtain a copy of such Source Code
|
||||
Form by reasonable means in a timely manner, at a charge no more
|
||||
than the cost of distribution to the recipient; and
|
||||
|
||||
(b) You may distribute such Executable Form under the terms of this
|
||||
License, or sublicense it under different terms, provided that the
|
||||
license for the Executable Form does not attempt to limit or alter
|
||||
the recipients' rights in the Source Code Form under this License.
|
||||
|
||||
3.3. Distribution of a Larger Work
|
||||
|
||||
You may create and distribute a Larger Work under terms of Your choice,
|
||||
provided that You also comply with the requirements of this License for
|
||||
the Covered Software. If the Larger Work is a combination of Covered
|
||||
Software with a work governed by one or more Secondary Licenses, and the
|
||||
Covered Software is not Incompatible With Secondary Licenses, this
|
||||
License permits You to additionally distribute such Covered Software
|
||||
under the terms of such Secondary License(s), so that the recipient of
|
||||
the Larger Work may, at their option, further distribute the Covered
|
||||
Software under the terms of either this License or such Secondary
|
||||
License(s).
|
||||
|
||||
3.4. Notices
|
||||
|
||||
You may not remove or alter the substance of any license notices
|
||||
(including copyright notices, patent notices, disclaimers of warranty,
|
||||
or limitations of liability) contained within the Source Code Form of
|
||||
the Covered Software, except that You may alter any license notices to
|
||||
the extent required to remedy known factual inaccuracies.
|
||||
|
||||
3.5. Application of Additional Terms
|
||||
|
||||
You may choose to offer, and to charge a fee for, warranty, support,
|
||||
indemnity or liability obligations to one or more recipients of Covered
|
||||
Software. However, You may do so only on Your own behalf, and not on
|
||||
behalf of any Contributor. You must make it absolutely clear that any
|
||||
such warranty, support, indemnity, or liability obligation is offered by
|
||||
You alone, and You hereby agree to indemnify every Contributor for any
|
||||
liability incurred by such Contributor as a result of warranty, support,
|
||||
indemnity or liability terms You offer. You may include additional
|
||||
disclaimers of warranty and limitations of liability specific to any
|
||||
jurisdiction.
|
||||
|
||||
4. Inability to Comply Due to Statute or Regulation
|
||||
---------------------------------------------------
|
||||
|
||||
If it is impossible for You to comply with any of the terms of this
|
||||
License with respect to some or all of the Covered Software due to
|
||||
statute, judicial order, or regulation then You must: (a) comply with
|
||||
the terms of this License to the maximum extent possible; and (b)
|
||||
describe the limitations and the code they affect. Such description must
|
||||
be placed in a text file included with all distributions of the Covered
|
||||
Software under this License. Except to the extent prohibited by statute
|
||||
or regulation, such description must be sufficiently detailed for a
|
||||
recipient of ordinary skill to be able to understand it.
|
||||
|
||||
5. Termination
|
||||
--------------
|
||||
|
||||
5.1. The rights granted under this License will terminate automatically
|
||||
if You fail to comply with any of its terms. However, if You become
|
||||
compliant, then the rights granted under this License from a particular
|
||||
Contributor are reinstated (a) provisionally, unless and until such
|
||||
Contributor explicitly and finally terminates Your grants, and (b) on an
|
||||
ongoing basis, if such Contributor fails to notify You of the
|
||||
non-compliance by some reasonable means prior to 60 days after You have
|
||||
come back into compliance. Moreover, Your grants from a particular
|
||||
Contributor are reinstated on an ongoing basis if such Contributor
|
||||
notifies You of the non-compliance by some reasonable means, this is the
|
||||
first time You have received notice of non-compliance with this License
|
||||
from such Contributor, and You become compliant prior to 30 days after
|
||||
Your receipt of the notice.
|
||||
|
||||
5.2. If You initiate litigation against any entity by asserting a patent
|
||||
infringement claim (excluding declaratory judgment actions,
|
||||
counter-claims, and cross-claims) alleging that a Contributor Version
|
||||
directly or indirectly infringes any patent, then the rights granted to
|
||||
You by any and all Contributors for the Covered Software under Section
|
||||
2.1 of this License shall terminate.
|
||||
|
||||
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
|
||||
end user license agreements (excluding distributors and resellers) which
|
||||
have been validly granted by You or Your distributors under this License
|
||||
prior to termination shall survive termination.
|
||||
|
||||
************************************************************************
|
||||
* *
|
||||
* 6. Disclaimer of Warranty *
|
||||
* ------------------------- *
|
||||
* *
|
||||
* Covered Software is provided under this License on an "as is" *
|
||||
* basis, without warranty of any kind, either expressed, implied, or *
|
||||
* statutory, including, without limitation, warranties that the *
|
||||
* Covered Software is free of defects, merchantable, fit for a *
|
||||
* particular purpose or non-infringing. The entire risk as to the *
|
||||
* quality and performance of the Covered Software is with You. *
|
||||
* Should any Covered Software prove defective in any respect, You *
|
||||
* (not any Contributor) assume the cost of any necessary servicing, *
|
||||
* repair, or correction. This disclaimer of warranty constitutes an *
|
||||
* essential part of this License. No use of any Covered Software is *
|
||||
* authorized under this License except under this disclaimer. *
|
||||
* *
|
||||
************************************************************************
|
||||
|
||||
************************************************************************
|
||||
* *
|
||||
* 7. Limitation of Liability *
|
||||
* -------------------------- *
|
||||
* *
|
||||
* Under no circumstances and under no legal theory, whether tort *
|
||||
* (including negligence), contract, or otherwise, shall any *
|
||||
* Contributor, or anyone who distributes Covered Software as *
|
||||
* permitted above, be liable to You for any direct, indirect, *
|
||||
* special, incidental, or consequential damages of any character *
|
||||
* including, without limitation, damages for lost profits, loss of *
|
||||
* goodwill, work stoppage, computer failure or malfunction, or any *
|
||||
* and all other commercial damages or losses, even if such party *
|
||||
* shall have been informed of the possibility of such damages. This *
|
||||
* limitation of liability shall not apply to liability for death or *
|
||||
* personal injury resulting from such party's negligence to the *
|
||||
* extent applicable law prohibits such limitation. Some *
|
||||
* jurisdictions do not allow the exclusion or limitation of *
|
||||
* incidental or consequential damages, so this exclusion and *
|
||||
* limitation may not apply to You. *
|
||||
* *
|
||||
************************************************************************
|
||||
|
||||
8. Litigation
|
||||
-------------
|
||||
|
||||
Any litigation relating to this License may be brought only in the
|
||||
courts of a jurisdiction where the defendant maintains its principal
|
||||
place of business and such litigation shall be governed by laws of that
|
||||
jurisdiction, without reference to its conflict-of-law provisions.
|
||||
Nothing in this Section shall prevent a party's ability to bring
|
||||
cross-claims or counter-claims.
|
||||
|
||||
9. Miscellaneous
|
||||
----------------
|
||||
|
||||
This License represents the complete agreement concerning the subject
|
||||
matter hereof. If any provision of this License is held to be
|
||||
unenforceable, such provision shall be reformed only to the extent
|
||||
necessary to make it enforceable. Any law or regulation which provides
|
||||
that the language of a contract shall be construed against the drafter
|
||||
shall not be used to construe this License against a Contributor.
|
||||
|
||||
10. Versions of the License
|
||||
---------------------------
|
||||
|
||||
10.1. New Versions
|
||||
|
||||
Mozilla Foundation is the license steward. Except as provided in Section
|
||||
10.3, no one other than the license steward has the right to modify or
|
||||
publish new versions of this License. Each version will be given a
|
||||
distinguishing version number.
|
||||
|
||||
10.2. Effect of New Versions
|
||||
|
||||
You may distribute the Covered Software under the terms of the version
|
||||
of the License under which You originally received the Covered Software,
|
||||
or under the terms of any subsequent version published by the license
|
||||
steward.
|
||||
|
||||
10.3. Modified Versions
|
||||
|
||||
If you create software not governed by this License, and you want to
|
||||
create a new license for such software, you may create and use a
|
||||
modified version of this License if you rename the license and remove
|
||||
any references to the name of the license steward (except to note that
|
||||
such modified license differs from this License).
|
||||
|
||||
10.4. Distributing Source Code Form that is Incompatible With Secondary
|
||||
Licenses
|
||||
|
||||
If You choose to distribute Source Code Form that is Incompatible With
|
||||
Secondary Licenses under the terms of this version of the License, the
|
||||
notice described in Exhibit B of this License must be attached.
|
||||
|
||||
Exhibit A - Source Code Form License Notice
|
||||
-------------------------------------------
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public
|
||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular
|
||||
file, then You may include the notice in a location (such as a LICENSE
|
||||
file in a relevant directory) where a recipient would be likely to look
|
||||
for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
|
||||
Exhibit B - "Incompatible With Secondary Licenses" Notice
|
||||
---------------------------------------------------------
|
||||
|
||||
This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
defined by the Mozilla Public License, v. 2.0.
|
||||
|
||||
------
|
||||
## BSD 2-Clause "Simplified" License
|
||||
|
||||
Copyright <YEAR> <COPYRIGHT HOLDER>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
## Gardener
|
||||
Copyright (c) 2017-2019 SAP SE or an SAP affiliate company. All rights reserved.
|
||||
|
||||
## Seed Source
|
||||
|
||||
The source code of this component was seeded based on a copy of the following files from [github.com/kubernetes](github.com/kubernetes):
|
||||
|
||||
Sample APIServer.
|
||||
http://git.k8s.io/sample-apiserver.
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
Apache 2 license (https://git.k8s.io/sample-apiserver/LICENSE).
|
||||
|
||||
Release: 1.9.
|
||||
Commit-ID: 7c9967f6de296b968505885781e9ed9fc65156c3
|
||||
Commit-Message: Merge remote-tracking branch 'origin/master' into release-1.9
|
||||
|
||||
Kubernetes.
|
||||
https://git.k8s.io/kubernetes.
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
Apache 2 license (https://git.k8s.io/kubernetes/LICENSE).
|
||||
|
||||
The following charts of the [`charts`](charts) directory were seeded based on a copy of the following origins:
|
||||
|
||||
* [git.k8s.io/charts/stable/kube-state-metrics](https://git.k8s.io/charts/stable/kube-state-metrics)
|
||||
* [git.k8s.io/charts/stable/nginx-ingress](https://git.k8s.io/charts/stable/nginx-ingress)
|
||||
* [git.k8s.io/charts/stable/prometheus](https://git.k8s.io/charts/stable/prometheus)
|
||||
* [git.k8s.io/charts/stable/kubernetes-dashboard](https://git.k8s.io/charts/stable/kubernetes-dashboard)
|
||||
* [github.com/grafana/loki/blob/master/production/helm/loki/templates/statefulset.yaml](https://github.com/grafana/loki/blob/master/production/helm/loki/templates/statefulset.yaml)
|
||||
* [github.com/grafana/loki/blob/master/production/helm/loki/templates/service.yaml](https://github.com/grafana/loki/blob/master/production/helm/loki/templates/service.yaml)
|
||||
|
||||
## Container Images
|
||||
|
||||
The list of container images and versions deployed by the Gardener can be found [here](charts/images.yaml).
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
// Copyright (c) 2020 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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 controller
|
||||
|
||||
import "github.com/gardener/gardener/pkg/extensions"
|
||||
|
||||
// Cluster contains the decoded resources of Gardener's extension Cluster resource.
|
||||
type Cluster = extensions.Cluster
|
||||
|
||||
var (
|
||||
// NewGardenDecoder returns a new Garden API decoder.
|
||||
NewGardenDecoder = extensions.NewGardenDecoder
|
||||
// GetCluster tries to read Gardener's Cluster extension resource in the given namespace.
|
||||
GetCluster = extensions.GetCluster
|
||||
// CloudProfileFromCluster returns the CloudProfile resource inside the Cluster resource.
|
||||
CloudProfileFromCluster = extensions.CloudProfileFromCluster
|
||||
// SeedFromCluster returns the Seed resource inside the Cluster resource.
|
||||
SeedFromCluster = extensions.SeedFromCluster
|
||||
// ShootFromCluster returns the Shoot resource inside the Cluster resource.
|
||||
ShootFromCluster = extensions.ShootFromCluster
|
||||
// GetShoot tries to read Gardener's Cluster extension resource in the given namespace and return the embedded Shoot resource.
|
||||
GetShoot = extensions.GetShoot
|
||||
)
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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 cmd
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"sigs.k8s.io/controller-runtime/pkg/log"
|
||||
)
|
||||
|
||||
var (
|
||||
// Log is log.Log. Exposed for testing.
|
||||
Log = log.Log
|
||||
// Exit calls os.Exit. Exposed for testing.
|
||||
Exit = os.Exit
|
||||
)
|
||||
|
||||
// LogErrAndExit logs the given error with msg and keysAndValues and calls `os.Exit(1)`.
|
||||
func LogErrAndExit(err error, msg string, keysAndValues ...interface{}) {
|
||||
Log.Error(err, msg, keysAndValues...)
|
||||
Exit(1)
|
||||
}
|
||||
+396
@@ -0,0 +1,396 @@
|
||||
// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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 cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
extensionscontroller "github.com/gardener/gardener/extensions/pkg/controller"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
"sigs.k8s.io/controller-runtime/pkg/controller"
|
||||
"sigs.k8s.io/controller-runtime/pkg/manager"
|
||||
)
|
||||
|
||||
const (
|
||||
// LeaderElectionFlag is the name of the command line flag to specify whether to do leader election or not.
|
||||
LeaderElectionFlag = "leader-election"
|
||||
// LeaderElectionIDFlag is the name of the command line flag to specify the leader election ID.
|
||||
LeaderElectionIDFlag = "leader-election-id"
|
||||
// LeaderElectionNamespaceFlag is the name of the command line flag to specify the leader election namespace.
|
||||
LeaderElectionNamespaceFlag = "leader-election-namespace"
|
||||
// WebhookServerHostFlag is the name of the command line flag to specify the webhook config host for 'url' mode.
|
||||
WebhookServerHostFlag = "webhook-config-server-host"
|
||||
// WebhookServerPortFlag is the name of the command line flag to specify the webhook server port.
|
||||
WebhookServerPortFlag = "webhook-config-server-port"
|
||||
// WebhookCertDirFlag is the name of the command line flag to specify the webhook certificate directory.
|
||||
WebhookCertDirFlag = "webhook-config-cert-dir"
|
||||
|
||||
// MaxConcurrentReconcilesFlag is the name of the command line flag to specify the maximum number of
|
||||
// concurrent reconciliations a controller can do.
|
||||
MaxConcurrentReconcilesFlag = "max-concurrent-reconciles"
|
||||
|
||||
// KubeconfigFlag is the name of the command line flag to specify a kubeconfig used to retrieve
|
||||
// a rest.Config for a manager.Manager.
|
||||
KubeconfigFlag = clientcmd.RecommendedConfigPathFlag
|
||||
// MasterURLFlag is the name of the command line flag to specify the master URL override for
|
||||
// a rest.Config of a manager.Manager.
|
||||
MasterURLFlag = "master"
|
||||
|
||||
// DisableFlag is the name of the command line flag to disable individual controllers.
|
||||
DisableFlag = "disable-controllers"
|
||||
)
|
||||
|
||||
// LeaderElectionNameID returns a leader election ID for the given name.
|
||||
func LeaderElectionNameID(name string) string {
|
||||
return fmt.Sprintf("%s-leader-election", name)
|
||||
}
|
||||
|
||||
// Flagger adds flags to a given FlagSet.
|
||||
type Flagger interface {
|
||||
// AddFlags adds the flags of this Flagger to the given FlagSet.
|
||||
AddFlags(*pflag.FlagSet)
|
||||
}
|
||||
|
||||
type prefixedFlagger struct {
|
||||
prefix string
|
||||
flagger Flagger
|
||||
}
|
||||
|
||||
// AddFlags implements Flagger.AddFlags.
|
||||
func (p *prefixedFlagger) AddFlags(fs *pflag.FlagSet) {
|
||||
temp := pflag.NewFlagSet("", pflag.ExitOnError)
|
||||
p.flagger.AddFlags(temp)
|
||||
temp.VisitAll(func(flag *pflag.Flag) {
|
||||
flag.Name = fmt.Sprintf("%s%s", p.prefix, flag.Name)
|
||||
})
|
||||
fs.AddFlagSet(temp)
|
||||
}
|
||||
|
||||
// PrefixFlagger creates a flagger that prefixes all its flags with the given prefix.
|
||||
func PrefixFlagger(prefix string, flagger Flagger) Flagger {
|
||||
return &prefixedFlagger{prefix, flagger}
|
||||
}
|
||||
|
||||
// PrefixOption creates an option that prefixes all its flags with the given prefix.
|
||||
func PrefixOption(prefix string, option Option) Option {
|
||||
return struct {
|
||||
Flagger
|
||||
Completer
|
||||
}{PrefixFlagger(prefix, option), option}
|
||||
}
|
||||
|
||||
// Completer completes some work.
|
||||
type Completer interface {
|
||||
// Complete completes the work, optionally returning an error.
|
||||
Complete() error
|
||||
}
|
||||
|
||||
// Option is a Flagger and Completer.
|
||||
// It sets command line flags and does some work when the flags have been parsed, optionally producing
|
||||
// an error.
|
||||
type Option interface {
|
||||
Flagger
|
||||
Completer
|
||||
}
|
||||
|
||||
// OptionAggregator is a builder that aggregates multiple options.
|
||||
type OptionAggregator []Option
|
||||
|
||||
// NewOptionAggregator instantiates a new OptionAggregator and registers all given options.
|
||||
func NewOptionAggregator(options ...Option) OptionAggregator {
|
||||
var builder OptionAggregator
|
||||
builder.Register(options...)
|
||||
return builder
|
||||
}
|
||||
|
||||
// Register registers the given options in this OptionAggregator.
|
||||
func (b *OptionAggregator) Register(options ...Option) {
|
||||
*b = append(*b, options...)
|
||||
}
|
||||
|
||||
// AddFlags implements Flagger.AddFlags.
|
||||
func (b *OptionAggregator) AddFlags(fs *pflag.FlagSet) {
|
||||
for _, option := range *b {
|
||||
option.AddFlags(fs)
|
||||
}
|
||||
}
|
||||
|
||||
// Complete implements Completer.Complete.
|
||||
func (b *OptionAggregator) Complete() error {
|
||||
for _, option := range *b {
|
||||
if err := option.Complete(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ManagerOptions are command line options that can be set for manager.Options.
|
||||
type ManagerOptions struct {
|
||||
// LeaderElection is whether leader election is turned on or not.
|
||||
LeaderElection bool
|
||||
// LeaderElectionID is the id to do leader election with.
|
||||
LeaderElectionID string
|
||||
// LeaderElectionNamespace is the namespace to do leader election in.
|
||||
LeaderElectionNamespace string
|
||||
// WebhookServerHost is the host for the webhook server.
|
||||
WebhookServerHost string
|
||||
// WebhookServerPort is the port for the webhook server.
|
||||
WebhookServerPort int
|
||||
// WebhookCertDir is the directory that contains the webhook server key and certificate.
|
||||
WebhookCertDir string
|
||||
|
||||
config *ManagerConfig
|
||||
}
|
||||
|
||||
// AddFlags implements Flagger.AddFlags.
|
||||
func (m *ManagerOptions) AddFlags(fs *pflag.FlagSet) {
|
||||
fs.BoolVar(&m.LeaderElection, LeaderElectionFlag, m.LeaderElection, "Whether to use leader election or not when running this controller manager.")
|
||||
fs.StringVar(&m.LeaderElectionID, LeaderElectionIDFlag, m.LeaderElectionID, "The leader election id to use.")
|
||||
fs.StringVar(&m.LeaderElectionNamespace, LeaderElectionNamespaceFlag, m.LeaderElectionNamespace, "The namespace to do leader election in.")
|
||||
fs.StringVar(&m.WebhookServerHost, WebhookServerHostFlag, m.WebhookServerHost, "The webhook server host.")
|
||||
fs.IntVar(&m.WebhookServerPort, WebhookServerPortFlag, m.WebhookServerPort, "The webhook server port.")
|
||||
fs.StringVar(&m.WebhookCertDir, WebhookCertDirFlag, m.WebhookCertDir, "The directory that contains the webhook server key and certificate.")
|
||||
}
|
||||
|
||||
// Complete implements Completer.Complete.
|
||||
func (m *ManagerOptions) Complete() error {
|
||||
m.config = &ManagerConfig{m.LeaderElection, m.LeaderElectionID, m.LeaderElectionNamespace, m.WebhookServerHost, m.WebhookServerPort, m.WebhookCertDir}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Completed returns the completed ManagerConfig. Only call this if `Complete` was successful.
|
||||
func (m *ManagerOptions) Completed() *ManagerConfig {
|
||||
return m.config
|
||||
}
|
||||
|
||||
// ManagerConfig is a completed manager configuration.
|
||||
type ManagerConfig struct {
|
||||
// LeaderElection is whether leader election is turned on or not.
|
||||
LeaderElection bool
|
||||
// LeaderElectionID is the id to do leader election with.
|
||||
LeaderElectionID string
|
||||
// LeaderElectionNamespace is the namespace to do leader election in.
|
||||
LeaderElectionNamespace string
|
||||
// WebhookServerHost is the host for the webhook server.
|
||||
WebhookServerHost string
|
||||
// WebhookServerPort is the port for the webhook server.
|
||||
WebhookServerPort int
|
||||
// WebhookCertDir is the directory that contains the webhook server key and certificate.
|
||||
WebhookCertDir string
|
||||
}
|
||||
|
||||
// Apply sets the values of this ManagerConfig in the given manager.Options.
|
||||
func (c *ManagerConfig) Apply(opts *manager.Options) {
|
||||
opts.LeaderElection = c.LeaderElection
|
||||
opts.LeaderElectionID = c.LeaderElectionID
|
||||
opts.LeaderElectionNamespace = c.LeaderElectionNamespace
|
||||
opts.Host = c.WebhookServerHost
|
||||
opts.Port = c.WebhookServerPort
|
||||
opts.CertDir = c.WebhookCertDir
|
||||
}
|
||||
|
||||
// Options initializes empty manager.Options, applies the set values and returns it.
|
||||
func (c *ManagerConfig) Options() manager.Options {
|
||||
var opts manager.Options
|
||||
c.Apply(&opts)
|
||||
return opts
|
||||
}
|
||||
|
||||
// ControllerOptions are command line options that can be set for controller.Options.
|
||||
type ControllerOptions struct {
|
||||
// MaxConcurrentReconciles are the maximum concurrent reconciles.
|
||||
MaxConcurrentReconciles int
|
||||
|
||||
config *ControllerConfig
|
||||
}
|
||||
|
||||
// AddFlags implements Flagger.AddFlags.
|
||||
func (c *ControllerOptions) AddFlags(fs *pflag.FlagSet) {
|
||||
fs.IntVar(&c.MaxConcurrentReconciles, MaxConcurrentReconcilesFlag, c.MaxConcurrentReconciles, "The maximum number of concurrent reconciliations.")
|
||||
}
|
||||
|
||||
// Complete implements Completer.Complete.
|
||||
func (c *ControllerOptions) Complete() error {
|
||||
c.config = &ControllerConfig{c.MaxConcurrentReconciles}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Completed returns the completed ControllerConfig. Only call this if `Complete` was successful.
|
||||
func (c *ControllerOptions) Completed() *ControllerConfig {
|
||||
return c.config
|
||||
}
|
||||
|
||||
// ControllerConfig is a completed controller configuration.
|
||||
type ControllerConfig struct {
|
||||
// MaxConcurrentReconciles is the maximum number of concurrent reconciles.
|
||||
MaxConcurrentReconciles int
|
||||
}
|
||||
|
||||
// Apply sets the values of this ControllerConfig in the given controller.Options.
|
||||
func (c *ControllerConfig) Apply(opts *controller.Options) {
|
||||
opts.MaxConcurrentReconciles = c.MaxConcurrentReconciles
|
||||
}
|
||||
|
||||
// Options initializes empty controller.Options, applies the set values and returns it.
|
||||
func (c *ControllerConfig) Options() controller.Options {
|
||||
var opts controller.Options
|
||||
c.Apply(&opts)
|
||||
return opts
|
||||
}
|
||||
|
||||
// RESTOptions are command line options that can be set for rest.Config.
|
||||
type RESTOptions struct {
|
||||
// Kubeconfig is the path to a kubeconfig.
|
||||
Kubeconfig string
|
||||
// MasterURL is an override for the URL in a kubeconfig. Only used if out-of-cluster.
|
||||
MasterURL string
|
||||
|
||||
config *RESTConfig
|
||||
}
|
||||
|
||||
// RESTConfig is a completed REST configuration.
|
||||
type RESTConfig struct {
|
||||
// Config is the rest.Config.
|
||||
Config *rest.Config
|
||||
}
|
||||
|
||||
var (
|
||||
// BuildConfigFromFlags creates a build configuration from the given flags. Exposed for testing.
|
||||
BuildConfigFromFlags = clientcmd.BuildConfigFromFlags
|
||||
// InClusterConfig obtains the current in-cluster config. Exposed for testing.
|
||||
InClusterConfig = rest.InClusterConfig
|
||||
// Getenv obtains the environment variable with the given name. Exposed for testing.
|
||||
Getenv = os.Getenv
|
||||
// RecommendedHomeFile is the recommended location of the kubeconfig. Exposed for testing.
|
||||
RecommendedHomeFile = clientcmd.RecommendedHomeFile
|
||||
)
|
||||
|
||||
func (r *RESTOptions) buildConfig() (*rest.Config, error) {
|
||||
// If a flag is specified with the config location, use that
|
||||
if len(r.Kubeconfig) > 0 {
|
||||
return BuildConfigFromFlags(r.MasterURL, r.Kubeconfig)
|
||||
}
|
||||
// If an env variable is specified with the config location, use that
|
||||
if kubeconfig := Getenv(clientcmd.RecommendedConfigPathEnvVar); len(kubeconfig) > 0 {
|
||||
return BuildConfigFromFlags(r.MasterURL, kubeconfig)
|
||||
}
|
||||
// If no explicit location, try the in-cluster config
|
||||
if c, err := InClusterConfig(); err == nil {
|
||||
return c, nil
|
||||
}
|
||||
|
||||
return BuildConfigFromFlags("", RecommendedHomeFile)
|
||||
}
|
||||
|
||||
// Complete implements RESTCompleter.Complete.
|
||||
func (r *RESTOptions) Complete() error {
|
||||
config, err := r.buildConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
r.config = &RESTConfig{config}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Completed returns the completed RESTConfig. Only call this if `Complete` was successful.
|
||||
func (r *RESTOptions) Completed() *RESTConfig {
|
||||
return r.config
|
||||
}
|
||||
|
||||
// AddFlags implements Flagger.AddFlags.
|
||||
func (r *RESTOptions) AddFlags(fs *pflag.FlagSet) {
|
||||
fs.StringVar(&r.Kubeconfig, KubeconfigFlag, "", "Paths to a kubeconfig. Only required if out-of-cluster.")
|
||||
fs.StringVar(&r.MasterURL, MasterURLFlag, "", "The address of the Kubernetes API server. Overrides any value in kubeconfig. Only required if out-of-cluster.")
|
||||
}
|
||||
|
||||
// SwitchOptions are options to build an AddToManager function that filters the disabled controllers.
|
||||
type SwitchOptions struct {
|
||||
Disabled []string
|
||||
|
||||
nameToAddToManager map[string]func(manager.Manager) error
|
||||
addToManagerBuilder extensionscontroller.AddToManagerBuilder
|
||||
}
|
||||
|
||||
// Register registers the given NameToControllerFuncs in the options.
|
||||
func (d *SwitchOptions) Register(pairs ...NameToAddToManagerFunc) {
|
||||
for _, pair := range pairs {
|
||||
d.nameToAddToManager[pair.Name] = pair.Func
|
||||
}
|
||||
}
|
||||
|
||||
// NameToAddToManagerFunc binds a specific name to a controller's AddToManager function.
|
||||
type NameToAddToManagerFunc struct {
|
||||
Name string
|
||||
Func func(manager.Manager) error
|
||||
}
|
||||
|
||||
// Switch binds the given name to the given AddToManager function.
|
||||
func Switch(name string, f func(manager.Manager) error) NameToAddToManagerFunc {
|
||||
return NameToAddToManagerFunc{
|
||||
Name: name,
|
||||
Func: f,
|
||||
}
|
||||
}
|
||||
|
||||
// NewSwitchOptions creates new SwitchOptions with the given initial pairs.
|
||||
func NewSwitchOptions(pairs ...NameToAddToManagerFunc) *SwitchOptions {
|
||||
opts := SwitchOptions{nameToAddToManager: make(map[string]func(manager.Manager) error)}
|
||||
opts.Register(pairs...)
|
||||
return &opts
|
||||
}
|
||||
|
||||
// AddFlags implements Option.
|
||||
func (d *SwitchOptions) AddFlags(fs *pflag.FlagSet) {
|
||||
controllerNames := make([]string, 0, len(d.nameToAddToManager))
|
||||
for name := range d.nameToAddToManager {
|
||||
controllerNames = append(controllerNames, name)
|
||||
}
|
||||
fs.StringSliceVar(&d.Disabled, DisableFlag, d.Disabled, fmt.Sprintf("List of controllers to disable %v", controllerNames))
|
||||
}
|
||||
|
||||
// Complete implements Option.
|
||||
func (d *SwitchOptions) Complete() error {
|
||||
disabled := sets.NewString()
|
||||
for _, disabledName := range d.Disabled {
|
||||
if _, ok := d.nameToAddToManager[disabledName]; !ok {
|
||||
return fmt.Errorf("cannot disable unknown controller %q", disabledName)
|
||||
}
|
||||
disabled.Insert(disabledName)
|
||||
}
|
||||
|
||||
for name, addToManager := range d.nameToAddToManager {
|
||||
if !disabled.Has(name) {
|
||||
d.addToManagerBuilder.Register(addToManager)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Completed returns the completed SwitchConfig. Call this only after successfully calling `Completed`.
|
||||
func (d *SwitchOptions) Completed() *SwitchConfig {
|
||||
return &SwitchConfig{d.addToManagerBuilder.AddToManager}
|
||||
}
|
||||
|
||||
// SwitchConfig is the completed configuration of SwitchOptions.
|
||||
type SwitchConfig struct {
|
||||
AddToManager func(manager.Manager) error
|
||||
}
|
||||
Generated
Vendored
+60
@@ -0,0 +1,60 @@
|
||||
// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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 cmd
|
||||
|
||||
import (
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
const (
|
||||
// IgnoreOperationAnnotationFlag is the name of the command line flag to specify whether the operation annotation
|
||||
// is ignored or not.
|
||||
IgnoreOperationAnnotationFlag = "ignore-operation-annotation"
|
||||
)
|
||||
|
||||
// ReconcilerOptions are command line options that can be set for controller.Options.
|
||||
type ReconcilerOptions struct {
|
||||
// IgnoreOperationAnnotation defines whether to ignore the operation annotation or not.
|
||||
IgnoreOperationAnnotation bool
|
||||
|
||||
config *ReconcilerConfig
|
||||
}
|
||||
|
||||
// AddFlags implements Flagger.AddFlags.
|
||||
func (c *ReconcilerOptions) AddFlags(fs *pflag.FlagSet) {
|
||||
fs.BoolVar(&c.IgnoreOperationAnnotation, IgnoreOperationAnnotationFlag, c.IgnoreOperationAnnotation, "Ignore the operation annotation or not.")
|
||||
}
|
||||
|
||||
// Complete implements Completer.Complete.
|
||||
func (c *ReconcilerOptions) Complete() error {
|
||||
c.config = &ReconcilerConfig{c.IgnoreOperationAnnotation}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Completed returns the completed ReconcilerConfig. Only call this if `Complete` was successful.
|
||||
func (c *ReconcilerOptions) Completed() *ReconcilerConfig {
|
||||
return c.config
|
||||
}
|
||||
|
||||
// ReconcilerConfig is a completed controller configuration.
|
||||
type ReconcilerConfig struct {
|
||||
// IgnoreOperationAnnotation defines whether to ignore the operation annotation or not.
|
||||
IgnoreOperationAnnotation bool
|
||||
}
|
||||
|
||||
// Apply sets the values of this ReconcilerConfig in the given controller.Options.
|
||||
func (c *ReconcilerConfig) Apply(ignore *bool) {
|
||||
*ignore = c.IgnoreOperationAnnotation
|
||||
}
|
||||
Generated
Vendored
+37
@@ -0,0 +1,37 @@
|
||||
// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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 error
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
// RequeueAfterError is an error that indicates that an actuator wants a reconcile operation
|
||||
// to be requeued again after RequeueAfter has passed.
|
||||
type RequeueAfterError struct {
|
||||
// Cause is an optional cause that may be returned together with a time for requeueing.
|
||||
Cause error
|
||||
// RequeueAfter is the duration after which the request should be enqueued again.
|
||||
RequeueAfter time.Duration
|
||||
}
|
||||
|
||||
func (e *RequeueAfterError) Error() string {
|
||||
if e.Cause == nil {
|
||||
return fmt.Sprintf("requeue in %s", e.RequeueAfter)
|
||||
}
|
||||
|
||||
return fmt.Sprintf("requeue in %s due to %+v", e.RequeueAfter, e.Cause)
|
||||
}
|
||||
Generated
Vendored
+33
@@ -0,0 +1,33 @@
|
||||
// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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 extension
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
extensionsv1alpha1 "github.com/gardener/gardener/pkg/apis/extensions/v1alpha1"
|
||||
)
|
||||
|
||||
// Actuator acts upon Extension resources.
|
||||
type Actuator interface {
|
||||
// Reconcile the Extension resource.
|
||||
Reconcile(ctx context.Context, ex *extensionsv1alpha1.Extension) error
|
||||
// Delete the Extension resource.
|
||||
Delete(ctx context.Context, ex *extensionsv1alpha1.Extension) error
|
||||
// Restore the Extension resource.
|
||||
Restore(ctx context.Context, ex *extensionsv1alpha1.Extension) error
|
||||
// Migrate the Extension resource.
|
||||
Migrate(ctx context.Context, ex *extensionsv1alpha1.Extension) error
|
||||
}
|
||||
Generated
Vendored
+29
@@ -0,0 +1,29 @@
|
||||
// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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 extension
|
||||
|
||||
import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/predicate"
|
||||
|
||||
extensionshandler "github.com/gardener/gardener/extensions/pkg/handler"
|
||||
extensionsv1alpha1 "github.com/gardener/gardener/pkg/apis/extensions/v1alpha1"
|
||||
)
|
||||
|
||||
// ClusterToExtensionMapper returns a mapper that returns requests for Extensions whose
|
||||
// referenced clusters have been modified.
|
||||
func ClusterToExtensionMapper(predicates ...predicate.Predicate) extensionshandler.Mapper {
|
||||
return extensionshandler.ClusterToObjectMapper(func() client.ObjectList { return &extensionsv1alpha1.ExtensionList{} }, predicates)
|
||||
}
|
||||
Generated
Vendored
+320
@@ -0,0 +1,320 @@
|
||||
// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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 extension
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/client-go/util/retry"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/controller"
|
||||
"sigs.k8s.io/controller-runtime/pkg/handler"
|
||||
"sigs.k8s.io/controller-runtime/pkg/log"
|
||||
"sigs.k8s.io/controller-runtime/pkg/manager"
|
||||
"sigs.k8s.io/controller-runtime/pkg/predicate"
|
||||
"sigs.k8s.io/controller-runtime/pkg/reconcile"
|
||||
"sigs.k8s.io/controller-runtime/pkg/runtime/inject"
|
||||
"sigs.k8s.io/controller-runtime/pkg/source"
|
||||
|
||||
extensionscontroller "github.com/gardener/gardener/extensions/pkg/controller"
|
||||
extensionshandler "github.com/gardener/gardener/extensions/pkg/handler"
|
||||
extensionspredicate "github.com/gardener/gardener/extensions/pkg/predicate"
|
||||
gardencorev1beta1 "github.com/gardener/gardener/pkg/apis/core/v1beta1"
|
||||
v1beta1constants "github.com/gardener/gardener/pkg/apis/core/v1beta1/constants"
|
||||
gardencorev1beta1helper "github.com/gardener/gardener/pkg/apis/core/v1beta1/helper"
|
||||
extensionsv1alpha1 "github.com/gardener/gardener/pkg/apis/extensions/v1alpha1"
|
||||
)
|
||||
|
||||
const (
|
||||
// FinalizerPrefix is the prefix name of the finalizer written by this controller.
|
||||
FinalizerPrefix = "extensions.gardener.cloud"
|
||||
)
|
||||
|
||||
// AddArgs are arguments for adding an Extension resources controller to a manager.
|
||||
type AddArgs struct {
|
||||
// Actuator is an Extension resource actuator.
|
||||
Actuator Actuator
|
||||
// Name is the name of the controller.
|
||||
Name string
|
||||
// FinalizerSuffix is the suffix for the finalizer name.
|
||||
FinalizerSuffix string
|
||||
// ControllerOptions are the controller options used for creating a controller.
|
||||
// The options.Reconciler is always overridden with a reconciler created from the
|
||||
// given actuator.
|
||||
ControllerOptions controller.Options
|
||||
// Predicates are the predicates to use.
|
||||
Predicates []predicate.Predicate
|
||||
// Resync determines the requeue interval.
|
||||
Resync time.Duration
|
||||
// Type is the type of the resource considered for reconciliation.
|
||||
Type string
|
||||
// IgnoreOperationAnnotation specifies whether to ignore the operation annotation or not.
|
||||
// If the annotation is not ignored, the extension controller will only reconcile
|
||||
// with a present operation annotation typically set during a reconcile (e.g in the maintenance time) by the Gardenlet
|
||||
IgnoreOperationAnnotation bool
|
||||
}
|
||||
|
||||
// Add adds an Extension controller to the given manager using the given AddArgs.
|
||||
func Add(mgr manager.Manager, args AddArgs) error {
|
||||
args.ControllerOptions.Reconciler = NewReconciler(args)
|
||||
return add(mgr, args)
|
||||
}
|
||||
|
||||
// DefaultPredicates returns the default predicates for an extension reconciler.
|
||||
func DefaultPredicates(ignoreOperationAnnotation bool) []predicate.Predicate {
|
||||
if ignoreOperationAnnotation {
|
||||
return []predicate.Predicate{
|
||||
predicate.GenerationChangedPredicate{},
|
||||
}
|
||||
}
|
||||
return []predicate.Predicate{
|
||||
predicate.Or(
|
||||
extensionspredicate.HasOperationAnnotation(),
|
||||
extensionspredicate.LastOperationNotSuccessful(),
|
||||
extensionspredicate.IsDeleting(),
|
||||
),
|
||||
extensionspredicate.ShootNotFailed(),
|
||||
}
|
||||
}
|
||||
|
||||
func add(mgr manager.Manager, args AddArgs) error {
|
||||
ctrl, err := controller.New(args.Name, mgr, args.ControllerOptions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
predicates := extensionspredicate.AddTypePredicate(args.Predicates, args.Type)
|
||||
|
||||
if args.IgnoreOperationAnnotation {
|
||||
if err := ctrl.Watch(
|
||||
&source.Kind{Type: &extensionsv1alpha1.Cluster{}},
|
||||
extensionshandler.EnqueueRequestsFromMapper(ClusterToExtensionMapper(predicates...), extensionshandler.UpdateWithNew),
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return ctrl.Watch(&source.Kind{Type: &extensionsv1alpha1.Extension{}}, &handler.EnqueueRequestForObject{}, predicates...)
|
||||
}
|
||||
|
||||
// reconciler reconciles Extension resources of Gardener's
|
||||
// `extensions.gardener.cloud` API group.
|
||||
type reconciler struct {
|
||||
logger logr.Logger
|
||||
actuator Actuator
|
||||
finalizerName string
|
||||
|
||||
client client.Client
|
||||
|
||||
resync time.Duration
|
||||
}
|
||||
|
||||
// NewReconciler creates a new reconcile.Reconciler that reconciles
|
||||
// Extension resources of Gardener's `extensions.gardener.cloud` API group.
|
||||
func NewReconciler(args AddArgs) reconcile.Reconciler {
|
||||
logger := log.Log.WithName(args.Name)
|
||||
finalizer := fmt.Sprintf("%s/%s", FinalizerPrefix, args.FinalizerSuffix)
|
||||
return extensionscontroller.OperationAnnotationWrapper(
|
||||
func() client.Object { return &extensionsv1alpha1.Extension{} },
|
||||
&reconciler{
|
||||
logger: logger,
|
||||
actuator: args.Actuator,
|
||||
finalizerName: finalizer,
|
||||
resync: args.Resync,
|
||||
})
|
||||
}
|
||||
|
||||
// InjectFunc enables dependency injection into the actuator.
|
||||
func (r *reconciler) InjectFunc(f inject.Func) error {
|
||||
return f(r.actuator)
|
||||
}
|
||||
|
||||
// InjectClient injects the controller runtime client into the reconciler.
|
||||
func (r *reconciler) InjectClient(client client.Client) error {
|
||||
r.client = client
|
||||
return nil
|
||||
}
|
||||
|
||||
// Reconcile is the reconciler function that gets executed in case there are new events for `Extension` resources.
|
||||
func (r *reconciler) Reconcile(ctx context.Context, request reconcile.Request) (reconcile.Result, error) {
|
||||
ex := &extensionsv1alpha1.Extension{}
|
||||
if err := r.client.Get(ctx, request.NamespacedName, ex); err != nil {
|
||||
if apierrors.IsNotFound(err) {
|
||||
return reconcile.Result{}, nil
|
||||
}
|
||||
return reconcile.Result{}, fmt.Errorf("could not fetch Extension resource: %+v", err)
|
||||
}
|
||||
|
||||
var result reconcile.Result
|
||||
|
||||
shoot, err := extensionscontroller.GetShoot(ctx, r.client, request.Namespace)
|
||||
if err != nil {
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
|
||||
if extensionscontroller.IsShootFailed(shoot) {
|
||||
r.logger.Info("Stop reconciling Extension of failed Shoot.", "namespace", request.Namespace, "name", ex.Name)
|
||||
return reconcile.Result{}, nil
|
||||
}
|
||||
|
||||
operationType := gardencorev1beta1helper.ComputeOperationType(ex.ObjectMeta, ex.Status.LastOperation)
|
||||
|
||||
switch {
|
||||
case extensionscontroller.IsMigrated(ex):
|
||||
return reconcile.Result{}, nil
|
||||
case operationType == gardencorev1beta1.LastOperationTypeMigrate:
|
||||
return r.migrate(ctx, ex)
|
||||
case ex.DeletionTimestamp != nil:
|
||||
return r.delete(ctx, ex)
|
||||
case ex.Annotations[v1beta1constants.GardenerOperation] == v1beta1constants.GardenerOperationRestore:
|
||||
return r.restore(ctx, ex, operationType)
|
||||
default:
|
||||
if result, err = r.reconcile(ctx, ex, operationType); err != nil {
|
||||
return result, err
|
||||
}
|
||||
return reconcile.Result{Requeue: r.resync != 0, RequeueAfter: r.resync}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (r *reconciler) reconcile(ctx context.Context, ex *extensionsv1alpha1.Extension, operationType gardencorev1beta1.LastOperationType) (reconcile.Result, error) {
|
||||
if err := extensionscontroller.EnsureFinalizer(ctx, r.client, ex, r.finalizerName); err != nil {
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
|
||||
if err := r.updateStatusProcessing(ctx, ex, operationType, "Reconciling Extension resource"); err != nil {
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
|
||||
if err := r.actuator.Reconcile(ctx, ex); err != nil {
|
||||
_ = r.updateStatusError(ctx, extensionscontroller.ReconcileErrCauseOrErr(err), ex, operationType, "Unable to reconcile Extension resource")
|
||||
return extensionscontroller.ReconcileErr(err)
|
||||
}
|
||||
|
||||
if err := r.updateStatusSuccess(ctx, ex, operationType, "Successfully reconciled Extension resource"); err != nil {
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
return reconcile.Result{}, nil
|
||||
}
|
||||
|
||||
func (r *reconciler) delete(ctx context.Context, ex *extensionsv1alpha1.Extension) (reconcile.Result, error) {
|
||||
hasFinalizer, err := extensionscontroller.HasFinalizer(ex, r.finalizerName)
|
||||
if err != nil {
|
||||
return reconcile.Result{}, fmt.Errorf("could not instantiate finalizer deletion: %+v", err)
|
||||
}
|
||||
|
||||
if !hasFinalizer {
|
||||
r.logger.Info("Reconciling Extension resource causes a no-op as there is no finalizer.", "extension", ex.Name, "namespace", ex.Namespace)
|
||||
return reconcile.Result{}, nil
|
||||
}
|
||||
|
||||
if err := r.updateStatusProcessing(ctx, ex, gardencorev1beta1.LastOperationTypeDelete, "Deleting Extension resource."); err != nil {
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
|
||||
if err := r.actuator.Delete(ctx, ex); err != nil {
|
||||
_ = r.updateStatusError(ctx, extensionscontroller.ReconcileErrCauseOrErr(err), ex, gardencorev1beta1.LastOperationTypeDelete, "Error deleting Extension resource")
|
||||
return extensionscontroller.ReconcileErr(err)
|
||||
}
|
||||
|
||||
if err := r.updateStatusSuccess(ctx, ex, gardencorev1beta1.LastOperationTypeDelete, "Successfully deleted Extension resource"); err != nil {
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
|
||||
if err := extensionscontroller.DeleteFinalizer(ctx, r.client, ex, r.finalizerName); err != nil {
|
||||
return reconcile.Result{}, fmt.Errorf("error removing finalizer from Extension resource: %+v", err)
|
||||
}
|
||||
return reconcile.Result{}, nil
|
||||
}
|
||||
|
||||
func (r *reconciler) restore(ctx context.Context, ex *extensionsv1alpha1.Extension, operationType gardencorev1beta1.LastOperationType) (reconcile.Result, error) {
|
||||
if err := extensionscontroller.EnsureFinalizer(ctx, r.client, ex, r.finalizerName); err != nil {
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
|
||||
if err := r.updateStatusProcessing(ctx, ex, operationType, "Restoring Extension resource"); err != nil {
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
|
||||
if err := r.actuator.Restore(ctx, ex); err != nil {
|
||||
_ = r.updateStatusError(ctx, extensionscontroller.ReconcileErrCauseOrErr(err), ex, operationType, "Unable to restore Extension resource")
|
||||
return extensionscontroller.ReconcileErr(err)
|
||||
}
|
||||
|
||||
if err := r.updateStatusSuccess(ctx, ex, operationType, "Successfully restored Extension resource"); err != nil {
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
|
||||
// remove operation annotation 'restore'
|
||||
if err := extensionscontroller.RemoveAnnotation(ctx, r.client, ex, v1beta1constants.GardenerOperation); err != nil {
|
||||
return reconcile.Result{}, fmt.Errorf("error removing annotation from Extension resource: %+v", err)
|
||||
}
|
||||
|
||||
return reconcile.Result{}, nil
|
||||
}
|
||||
|
||||
func (r *reconciler) migrate(ctx context.Context, ex *extensionsv1alpha1.Extension) (reconcile.Result, error) {
|
||||
if err := r.updateStatusProcessing(ctx, ex, gardencorev1beta1.LastOperationTypeMigrate, "Migrate Extension resource."); err != nil {
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
|
||||
if err := r.actuator.Migrate(ctx, ex); err != nil {
|
||||
_ = r.updateStatusError(ctx, extensionscontroller.ReconcileErrCauseOrErr(err), ex, gardencorev1beta1.LastOperationTypeMigrate, "Error migrating Extension resource")
|
||||
return extensionscontroller.ReconcileErr(err)
|
||||
}
|
||||
|
||||
if err := r.updateStatusSuccess(ctx, ex, gardencorev1beta1.LastOperationTypeMigrate, "Successfully migrated Extension resource"); err != nil {
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
|
||||
if err := extensionscontroller.DeleteAllFinalizers(ctx, r.client, ex); err != nil {
|
||||
return reconcile.Result{}, fmt.Errorf("error removing all finalizers from Extension resource: %+v", err)
|
||||
}
|
||||
|
||||
// remove operation annotation 'migrate'
|
||||
if err := extensionscontroller.RemoveAnnotation(ctx, r.client, ex, v1beta1constants.GardenerOperation); err != nil {
|
||||
return reconcile.Result{}, fmt.Errorf("error removing annotation from Extension resource: %+v", err)
|
||||
}
|
||||
|
||||
return reconcile.Result{}, nil
|
||||
}
|
||||
|
||||
func (r *reconciler) updateStatusProcessing(ctx context.Context, ex *extensionsv1alpha1.Extension, lastOperationType gardencorev1beta1.LastOperationType, description string) error {
|
||||
r.logger.Info(description, "extension", ex.Name, "namespace", ex.Namespace)
|
||||
return extensionscontroller.TryUpdateStatus(ctx, retry.DefaultBackoff, r.client, ex, func() error {
|
||||
ex.Status.LastOperation = extensionscontroller.LastOperation(lastOperationType, gardencorev1beta1.LastOperationStateProcessing, 1, description)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (r *reconciler) updateStatusError(ctx context.Context, err error, ex *extensionsv1alpha1.Extension, lastOperationType gardencorev1beta1.LastOperationType, description string) error {
|
||||
return extensionscontroller.TryUpdateStatus(ctx, retry.DefaultBackoff, r.client, ex, func() error {
|
||||
ex.Status.ObservedGeneration = ex.Generation
|
||||
ex.Status.LastOperation, ex.Status.LastError = extensionscontroller.ReconcileError(lastOperationType, gardencorev1beta1helper.FormatLastErrDescription(fmt.Errorf("%s: %v", description, err)), 50, gardencorev1beta1helper.ExtractErrorCodes(gardencorev1beta1helper.DetermineError(err, err.Error()))...)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (r *reconciler) updateStatusSuccess(ctx context.Context, ex *extensionsv1alpha1.Extension, lastOperationType gardencorev1beta1.LastOperationType, description string) error {
|
||||
r.logger.Info(description, "extension", ex.Name, "namespace", ex.Namespace)
|
||||
return extensionscontroller.TryUpdateStatus(ctx, retry.DefaultBackoff, r.client, ex, func() error {
|
||||
ex.Status.ObservedGeneration = ex.Generation
|
||||
ex.Status.LastOperation, ex.Status.LastError = extensionscontroller.ReconcileSucceeded(lastOperationType, description)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
Generated
Vendored
+137
@@ -0,0 +1,137 @@
|
||||
// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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 healthcheck
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
extensionscontroller "github.com/gardener/gardener/extensions/pkg/controller"
|
||||
gardencorev1beta1 "github.com/gardener/gardener/pkg/apis/core/v1beta1"
|
||||
extensionsv1alpha1 "github.com/gardener/gardener/pkg/apis/extensions/v1alpha1"
|
||||
)
|
||||
|
||||
/*
|
||||
Each extension can register multiple HealthCheckActuator with various HealthChecks for checking the API Objects it deploys.
|
||||
Each NewActuator is responsible for a single extension resource (e.g Worker) - predicates can be defined for fine-grained control over which objects to watch.
|
||||
|
||||
The HealthCheck Reconciler triggers the registered NewActuator to execute the health checks.
|
||||
After, the Reconciler writes Conditions to the extension resource. One condition per HealthConditionType (e.g multiple checks that contribute to the HealthConditionType XYZ result in one Condition with .type XYZ).
|
||||
To contribute to the Shoot's health, the Gardener/Gardenlet checks each extension for Conditions containing one of the following HealthConditionTypes: SystemComponentsHealthy, EveryNodeReady, ControlPlaneHealthy.
|
||||
However extensions are free to choose any healthCheckType.
|
||||
|
||||
Generic HealthCheck functions for various API Objects are provided and can be reused.
|
||||
Many providers deploy helm charts via managed resources that are picked up by the resource-manager making sure that
|
||||
the helm chart is applied and all its components (Deployments, StatefulSets, DeamonSets, ...) are healthy.
|
||||
To integrate, the health check controller can also check the health of managed resources.
|
||||
|
||||
More sophisticated checks should be implemented in the extension itself by using the HealthCheck interface.
|
||||
*/
|
||||
|
||||
// GetExtensionObjectFunc returns the extension object that should be registered with the health check controller.
|
||||
// For example: func() extensionsv1alpha1.Object {return &extensionsv1alpha1.Worker{}}
|
||||
type GetExtensionObjectFunc = func() extensionsv1alpha1.Object
|
||||
|
||||
// GetExtensionObjectFunc returns the extension object that should be registered with the health check controller. Has to be a List.
|
||||
// For example: func() client.ObjectList { return &extensionsv1alpha1.WorkerList{} }
|
||||
type GetExtensionObjectListFunc = func() client.ObjectList
|
||||
|
||||
// PreCheckFunc checks whether the health check shall be performed based on the given object and cluster.
|
||||
type PreCheckFunc = func(runtime.Object, *extensionscontroller.Cluster) bool
|
||||
|
||||
// ConditionTypeToHealthCheck registers a HealthCheck for the given ConditionType. If the PreCheckFunc is not nil it will
|
||||
// be executed with the given object before the health check if performed. Otherwise, the health check will always be
|
||||
// performed.
|
||||
type ConditionTypeToHealthCheck struct {
|
||||
ConditionType string
|
||||
PreCheckFunc PreCheckFunc
|
||||
HealthCheck HealthCheck
|
||||
}
|
||||
|
||||
// HealthCheckActuator acts upon registered resources.
|
||||
type HealthCheckActuator interface {
|
||||
// ExecuteHealthCheckFunctions is regularly called by the health check controller
|
||||
// Executes all registered Health Checks and aggregates the result
|
||||
// Returns Result for each healthConditionTypes registered with the individual health checks.
|
||||
// returns an error if it could not execute the health checks
|
||||
// returning an error results in a condition with with type "Unknown" with reason "ConditionCheckError"
|
||||
ExecuteHealthCheckFunctions(context.Context, types.NamespacedName) (*[]Result, error)
|
||||
}
|
||||
|
||||
// Result represents an aggregated health status for the health checks performed on the dependent API Objects of an extension resource.
|
||||
// An Result refers to a single healthConditionTypes (e.g SystemComponentsHealthy) of an extension Resource.
|
||||
type Result struct {
|
||||
// HealthConditionType is being used as the .type field of the Condition that the HealthCheck controller writes to the extension Resource.
|
||||
// To contribute to the Shoot's health, the Gardener checks each extension for a Health Condition Type of SystemComponentsHealthy, EveryNodeReady, ControlPlaneHealthy.
|
||||
HealthConditionType string
|
||||
// Status contains the status for the health checks that have been performed for an extension resource
|
||||
Status gardencorev1beta1.ConditionStatus
|
||||
// Detail contains details for health checks being unsuccessful
|
||||
Detail *string
|
||||
// SuccessfulChecks is the amount of successful health checks
|
||||
SuccessfulChecks int
|
||||
// ProgressingChecks is the amount of health checks that were progressing
|
||||
ProgressingChecks int
|
||||
// UnsuccessfulChecks is the amount of health checks that were not successful
|
||||
UnsuccessfulChecks int
|
||||
// FailedChecks is the amount of health checks that could not be performed (e.g client could not reach Api Server)
|
||||
// Results in a condition with with type "Unknown" with reason "ConditionCheckError" for this healthConditionType
|
||||
FailedChecks int
|
||||
// Codes is an optional list of error codes that were produced by the health checks.
|
||||
Codes []gardencorev1beta1.ErrorCode
|
||||
// ProgressingThreshold is the threshold duration after which a health check that reported the `Progressing` status
|
||||
// shall be transitioned to `False`
|
||||
ProgressingThreshold *time.Duration
|
||||
}
|
||||
|
||||
// GetDetails returns the details of the health check result
|
||||
func (h *Result) GetDetails() string {
|
||||
if h.Detail == nil {
|
||||
return ""
|
||||
}
|
||||
return *h.Detail
|
||||
}
|
||||
|
||||
// HealthCheck represents a single health check
|
||||
// Each health check gets the shoot and seed clients injected
|
||||
// returns isHealthy, conditionReason, conditionDetail and error
|
||||
// returning an error means the health check could not be conducted and will result in a condition with with type "Unknown" and reason "ConditionCheckError"
|
||||
type HealthCheck interface {
|
||||
// Check is the function that executes the actual health check
|
||||
Check(context.Context, types.NamespacedName) (*SingleCheckResult, error)
|
||||
// SetLoggerSuffix injects the logger
|
||||
SetLoggerSuffix(string, string)
|
||||
// DeepCopy clones the healthCheck
|
||||
DeepCopy() HealthCheck
|
||||
}
|
||||
|
||||
// SingleCheckResult is the result for a health check
|
||||
type SingleCheckResult struct {
|
||||
// Status contains the status for the health check that has been performed for an extension resource
|
||||
Status gardencorev1beta1.ConditionStatus
|
||||
// Detail contains details for the health check being unsuccessful
|
||||
Detail string
|
||||
// Reason contains the reason for the health check being unsuccessful
|
||||
Reason string
|
||||
// Codes optionally contains a list of error codes related to the health check
|
||||
Codes []gardencorev1beta1.ErrorCode
|
||||
// ProgressingThreshold is the threshold duration after which a health check that reported the `Progressing` status
|
||||
// shall be transitioned to `False`
|
||||
ProgressingThreshold *time.Duration
|
||||
}
|
||||
Generated
Vendored
+25
@@ -0,0 +1,25 @@
|
||||
// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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 config
|
||||
|
||||
import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
type HealthCheckConfig struct {
|
||||
// SyncPeriod is the duration how often the existing resources are reconciled (how
|
||||
// often the health check of Shoot clusters is performed (only if no operation is
|
||||
// already running on them).
|
||||
// defaults to 30 sec
|
||||
SyncPeriod metav1.Duration
|
||||
}
|
||||
Generated
Vendored
+191
@@ -0,0 +1,191 @@
|
||||
// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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 healthcheck
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
healthcheckconfig "github.com/gardener/gardener/extensions/pkg/controller/healthcheck/config"
|
||||
extensionshandler "github.com/gardener/gardener/extensions/pkg/handler"
|
||||
extensionspredicate "github.com/gardener/gardener/extensions/pkg/predicate"
|
||||
"github.com/gardener/gardener/pkg/api/extensions"
|
||||
extensionsv1alpha1 "github.com/gardener/gardener/pkg/apis/extensions/v1alpha1"
|
||||
"github.com/gardener/gardener/pkg/utils"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"sigs.k8s.io/controller-runtime/pkg/controller"
|
||||
"sigs.k8s.io/controller-runtime/pkg/handler"
|
||||
"sigs.k8s.io/controller-runtime/pkg/log"
|
||||
"sigs.k8s.io/controller-runtime/pkg/manager"
|
||||
"sigs.k8s.io/controller-runtime/pkg/predicate"
|
||||
"sigs.k8s.io/controller-runtime/pkg/source"
|
||||
)
|
||||
|
||||
const (
|
||||
// ControllerName is the name of the controller.
|
||||
ControllerName = "healthcheck_controller"
|
||||
)
|
||||
|
||||
// AddArgs are arguments for adding an health check controller to a controller-runtime manager.
|
||||
type AddArgs struct {
|
||||
// ControllerOptions are the controller options used for creating a controller.
|
||||
// The options.Reconciler is always overridden with a reconciler created from the
|
||||
// given actuator.
|
||||
ControllerOptions controller.Options
|
||||
// Predicates are the predicates to use.
|
||||
// If unset, GenerationChanged will be used.
|
||||
Predicates []predicate.Predicate
|
||||
// Type is the type of the resource considered for reconciliation.
|
||||
Type string
|
||||
// SyncPeriod is the duration how often the registered extension is being reconciled
|
||||
SyncPeriod metav1.Duration
|
||||
// registeredExtension is the registered extensions that the HealthCheck Controller watches and writes HealthConditions for.
|
||||
// The Gardenlet reads the conditions on the extension Resource.
|
||||
// Through this mechanism, the extension can contribute to the Shoot's HealthStatus.
|
||||
registeredExtension *RegisteredExtension
|
||||
// GetExtensionObjListFunc returns a list of the runtime.Object representation of the extension to register
|
||||
GetExtensionObjListFunc GetExtensionObjectListFunc
|
||||
}
|
||||
|
||||
// DefaultAddArgs are the default Args for the health check controller.
|
||||
type DefaultAddArgs struct {
|
||||
// Controller are the controller.Options.
|
||||
Controller controller.Options
|
||||
// HealthCheckConfig contains additional config for the health check controller
|
||||
HealthCheckConfig healthcheckconfig.HealthCheckConfig
|
||||
}
|
||||
|
||||
// RegisteredExtension is a registered extensions that the HealthCheck Controller watches.
|
||||
// The field extension contains any extension object
|
||||
// The field healthConditionTypes contains all distinct healthCondition types (extracted from the healthCheck).
|
||||
// They are being used as the .type field of the Condition that the HealthCheck controller writes to the extension Resource.
|
||||
// The field groupVersionKind stores the GroupVersionKind of the extension resource
|
||||
type RegisteredExtension struct {
|
||||
extension extensionsv1alpha1.Object
|
||||
getExtensionObjFunc GetExtensionObjectFunc
|
||||
healthConditionTypes []string
|
||||
groupVersionKind schema.GroupVersionKind
|
||||
}
|
||||
|
||||
// DefaultRegistration configures the default health check NewActuator to execute the provided health checks and adds it to the provided controller-runtime manager.
|
||||
// the NewActuator reconciles a single extension with a specific type and writes conditions for each distinct healthConditionTypes.
|
||||
// extensionType (e.g aws) defines the spec.type of the extension to watch
|
||||
// kind defines the GroupVersionKind of the extension
|
||||
// GetExtensionObjListFunc returns a list of the runtime.Object representation of the extension to register
|
||||
// getExtensionObjFunc returns a runtime.Object representation of the extension to register
|
||||
// mgr is the controller runtime manager
|
||||
// opts contain config for the healthcheck controller
|
||||
// custom predicates allow for fine-grained control which resources to watch
|
||||
// healthChecks defines the checks to execute mapped to the healthConditionTypes its contributing to (e.g checkDeployment in Seed -> ControlPlaneHealthy).
|
||||
// register returns a runtime representation of the extension resource to register it with the controller-runtime
|
||||
func DefaultRegistration(extensionType string, kind schema.GroupVersionKind, getExtensionObjListFunc GetExtensionObjectListFunc, getExtensionObjFunc GetExtensionObjectFunc, mgr manager.Manager, opts DefaultAddArgs, customPredicates []predicate.Predicate, healthChecks []ConditionTypeToHealthCheck) error {
|
||||
predicates := append(DefaultPredicates(), customPredicates...)
|
||||
|
||||
args := AddArgs{
|
||||
ControllerOptions: opts.Controller,
|
||||
Predicates: predicates,
|
||||
Type: extensionType,
|
||||
SyncPeriod: opts.HealthCheckConfig.SyncPeriod,
|
||||
GetExtensionObjListFunc: getExtensionObjListFunc,
|
||||
}
|
||||
|
||||
if err := args.RegisterExtension(getExtensionObjFunc, getHealthCheckTypes(healthChecks), kind); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
healthCheckActuator := NewActuator(args.Type, args.GetExtensionGroupVersionKind().Kind, getExtensionObjFunc, healthChecks)
|
||||
return Register(mgr, args, healthCheckActuator)
|
||||
}
|
||||
|
||||
// RegisterExtension registered a resource and its corresponding healthCheckTypes.
|
||||
// throws and error if the extensionResources is not a extensionsv1alpha1.Object
|
||||
// The controller writes the healthCheckTypes as a condition.type into the extension resource.
|
||||
// To contribute to the Shoot's health, the Gardener checks each extension for a Health Condition Type of SystemComponentsHealthy, EveryNodeReady, ControlPlaneHealthy.
|
||||
// However extensions are free to choose any healthCheckType
|
||||
func (a *AddArgs) RegisterExtension(getExtensionObjFunc GetExtensionObjectFunc, conditionTypes []string, kind schema.GroupVersionKind) error {
|
||||
acc, err := extensions.Accessor(getExtensionObjFunc())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
a.registeredExtension = &RegisteredExtension{
|
||||
extension: acc,
|
||||
healthConditionTypes: conditionTypes,
|
||||
groupVersionKind: kind,
|
||||
getExtensionObjFunc: getExtensionObjFunc,
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *AddArgs) GetExtensionGroupVersionKind() schema.GroupVersionKind {
|
||||
return a.registeredExtension.groupVersionKind
|
||||
}
|
||||
|
||||
// DefaultPredicates returns the default predicates.
|
||||
func DefaultPredicates() []predicate.Predicate {
|
||||
return []predicate.Predicate{
|
||||
// watch: only requeue on spec change to prevent infinite loop
|
||||
// health checks are being executed every 'sync period' anyways
|
||||
predicate.GenerationChangedPredicate{},
|
||||
}
|
||||
}
|
||||
|
||||
// Register the extension resource. Must be of type extensionsv1alpha1.Object
|
||||
// Add creates a new Reconciler and adds it to the Manager.
|
||||
// and Start it when the Manager is Started.
|
||||
func Register(mgr manager.Manager, args AddArgs, actuator HealthCheckActuator) error {
|
||||
args.ControllerOptions.Reconciler = NewReconciler(mgr, actuator, *args.registeredExtension, args.SyncPeriod)
|
||||
return add(mgr, args)
|
||||
}
|
||||
|
||||
func add(mgr manager.Manager, args AddArgs) error {
|
||||
// generate random string to create unique manager name, in case multiple managers register the same extension resource
|
||||
str, err := utils.GenerateRandomString(10)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
controllerName := fmt.Sprintf("%s-%s-%s-%s-%s", ControllerName, args.registeredExtension.groupVersionKind.Kind, args.registeredExtension.groupVersionKind.Group, args.registeredExtension.groupVersionKind.Version, str)
|
||||
ctrl, err := controller.New(controllerName, mgr, args.ControllerOptions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Log.Info("Registered health check controller", "kind", args.registeredExtension.groupVersionKind.Kind, "type", args.Type, "health check type", args.registeredExtension.healthConditionTypes, "sync period", args.SyncPeriod.Duration.String())
|
||||
|
||||
// add type predicate to only watch registered resource (e.g ControlPlane) with a certain type (e.g aws)
|
||||
predicates := extensionspredicate.AddTypePredicate(args.Predicates, args.Type)
|
||||
|
||||
if err := ctrl.Watch(&source.Kind{Type: args.registeredExtension.getExtensionObjFunc()}, &handler.EnqueueRequestForObject{}, predicates...); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// watch Cluster of Shoot provider type (e.g aws)
|
||||
// this is to be notified when the Shoot is being hibernated (stop health checks) and wakes up (start health checks again)
|
||||
return ctrl.Watch(
|
||||
&source.Kind{Type: &extensionsv1alpha1.Cluster{}},
|
||||
extensionshandler.EnqueueRequestsFromMapper(extensionshandler.ClusterToObjectMapper(args.GetExtensionObjListFunc, predicates), extensionshandler.UpdateWithNew),
|
||||
)
|
||||
}
|
||||
|
||||
func getHealthCheckTypes(healthChecks []ConditionTypeToHealthCheck) []string {
|
||||
types := sets.NewString()
|
||||
for _, healthCheck := range healthChecks {
|
||||
types.Insert(healthCheck.ConditionType)
|
||||
}
|
||||
return types.UnsortedList()
|
||||
}
|
||||
Generated
Vendored
+284
@@ -0,0 +1,284 @@
|
||||
// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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 healthcheck
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
extensionscontroller "github.com/gardener/gardener/extensions/pkg/controller"
|
||||
"github.com/gardener/gardener/extensions/pkg/util"
|
||||
gardencorev1beta1 "github.com/gardener/gardener/pkg/apis/core/v1beta1"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/utils/pointer"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/log"
|
||||
)
|
||||
|
||||
// Actuator contains all the health checks and the means to execute them
|
||||
type Actuator struct {
|
||||
logger logr.Logger
|
||||
|
||||
restConfig *rest.Config
|
||||
seedClient client.Client
|
||||
scheme *runtime.Scheme
|
||||
decoder runtime.Decoder
|
||||
|
||||
provider string
|
||||
extensionKind string
|
||||
getExtensionObjFunc GetExtensionObjectFunc
|
||||
healthChecks []ConditionTypeToHealthCheck
|
||||
}
|
||||
|
||||
// NewActuator creates a new Actuator.
|
||||
func NewActuator(provider, extensionKind string, getExtensionObjFunc GetExtensionObjectFunc, healthChecks []ConditionTypeToHealthCheck) HealthCheckActuator {
|
||||
return &Actuator{
|
||||
healthChecks: healthChecks,
|
||||
getExtensionObjFunc: getExtensionObjFunc,
|
||||
provider: provider,
|
||||
extensionKind: extensionKind,
|
||||
logger: log.Log.WithName(fmt.Sprintf("%s-%s-healthcheck-actuator", provider, extensionKind)),
|
||||
}
|
||||
}
|
||||
|
||||
func (a *Actuator) InjectScheme(scheme *runtime.Scheme) error {
|
||||
a.scheme = scheme
|
||||
a.decoder = serializer.NewCodecFactory(a.scheme).UniversalDecoder()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *Actuator) InjectClient(client client.Client) error {
|
||||
a.seedClient = client
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *Actuator) InjectConfig(config *rest.Config) error {
|
||||
a.restConfig = config
|
||||
return nil
|
||||
}
|
||||
|
||||
type healthCheckUnsuccessful struct {
|
||||
reason string
|
||||
detail string
|
||||
}
|
||||
|
||||
type healthCheckProgressing struct {
|
||||
reason string
|
||||
detail string
|
||||
threshold *time.Duration
|
||||
}
|
||||
|
||||
type channelResult struct {
|
||||
healthConditionType string
|
||||
healthCheckResult *SingleCheckResult
|
||||
error error
|
||||
}
|
||||
|
||||
type checkResultForConditionType struct {
|
||||
failedChecks []error
|
||||
unsuccessfulChecks []healthCheckUnsuccessful
|
||||
progressingChecks []healthCheckProgressing
|
||||
successfulChecks int
|
||||
codes []gardencorev1beta1.ErrorCode
|
||||
}
|
||||
|
||||
// ExecuteHealthCheckFunctions executes all the health check functions, injects clients and logger & aggregates the results.
|
||||
// returns an Result for each HealthConditionType (e.g ControlPlaneHealthy)
|
||||
func (a *Actuator) ExecuteHealthCheckFunctions(ctx context.Context, request types.NamespacedName) (*[]Result, error) {
|
||||
var (
|
||||
shootClient client.Client
|
||||
channel = make(chan channelResult)
|
||||
wg sync.WaitGroup
|
||||
)
|
||||
|
||||
wg.Add(len(a.healthChecks))
|
||||
for _, hc := range a.healthChecks {
|
||||
// clone to avoid problems during parallel execution
|
||||
check := hc.HealthCheck.DeepCopy()
|
||||
SeedClientInto(a.seedClient, check)
|
||||
if _, ok := check.(ShootClient); ok {
|
||||
if shootClient == nil {
|
||||
var err error
|
||||
_, shootClient, err = util.NewClientForShoot(ctx, a.seedClient, request.Namespace, client.Options{})
|
||||
if err != nil {
|
||||
msg := fmt.Errorf("failed to create shoot client in namespace '%s': %v", request.Namespace, err)
|
||||
a.logger.Error(err, msg.Error())
|
||||
return nil, msg
|
||||
}
|
||||
}
|
||||
ShootClientInto(shootClient, check)
|
||||
}
|
||||
|
||||
check.SetLoggerSuffix(a.provider, a.extensionKind)
|
||||
|
||||
go func(ctx context.Context, request types.NamespacedName, check HealthCheck, preCheckFunc PreCheckFunc, healthConditionType string) {
|
||||
defer wg.Done()
|
||||
|
||||
if preCheckFunc != nil {
|
||||
obj := a.getExtensionObjFunc()
|
||||
if err := a.seedClient.Get(ctx, client.ObjectKey{Namespace: request.Namespace, Name: request.Name}, obj); err != nil {
|
||||
channel <- channelResult{
|
||||
healthCheckResult: &SingleCheckResult{
|
||||
Status: gardencorev1beta1.ConditionFalse,
|
||||
Detail: err.Error(),
|
||||
Reason: "ReadExtensionObjectFailed",
|
||||
},
|
||||
error: err,
|
||||
healthConditionType: healthConditionType,
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
cluster, err := extensionscontroller.GetCluster(ctx, a.seedClient, request.Namespace)
|
||||
if err != nil {
|
||||
channel <- channelResult{
|
||||
healthCheckResult: &SingleCheckResult{
|
||||
Status: gardencorev1beta1.ConditionFalse,
|
||||
Detail: err.Error(),
|
||||
Reason: "ReadClusterObjectFailed",
|
||||
},
|
||||
error: err,
|
||||
healthConditionType: healthConditionType,
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if !preCheckFunc(obj, cluster) {
|
||||
a.logger.V(6).Info("Skipping health check as pre check function returned false", "condition type", healthConditionType)
|
||||
channel <- channelResult{
|
||||
healthCheckResult: &SingleCheckResult{
|
||||
Status: gardencorev1beta1.ConditionTrue,
|
||||
},
|
||||
error: nil,
|
||||
healthConditionType: healthConditionType,
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
healthCheckResult, err := check.Check(ctx, request)
|
||||
channel <- channelResult{
|
||||
healthCheckResult: healthCheckResult,
|
||||
error: err,
|
||||
healthConditionType: healthConditionType,
|
||||
}
|
||||
}(ctx, request, check, hc.PreCheckFunc, hc.ConditionType)
|
||||
}
|
||||
|
||||
// close channel when wait group has 0 counter
|
||||
go func() {
|
||||
wg.Wait()
|
||||
close(channel)
|
||||
}()
|
||||
|
||||
groupedHealthCheckResults := make(map[string]*checkResultForConditionType)
|
||||
// loop runs until channel is closed
|
||||
for channelResult := range channel {
|
||||
if groupedHealthCheckResults[channelResult.healthConditionType] == nil {
|
||||
groupedHealthCheckResults[channelResult.healthConditionType] = &checkResultForConditionType{}
|
||||
}
|
||||
if channelResult.error != nil {
|
||||
groupedHealthCheckResults[channelResult.healthConditionType].failedChecks = append(groupedHealthCheckResults[channelResult.healthConditionType].failedChecks, channelResult.error)
|
||||
continue
|
||||
}
|
||||
if channelResult.healthCheckResult.Status == gardencorev1beta1.ConditionFalse {
|
||||
groupedHealthCheckResults[channelResult.healthConditionType].unsuccessfulChecks = append(groupedHealthCheckResults[channelResult.healthConditionType].unsuccessfulChecks, healthCheckUnsuccessful{reason: channelResult.healthCheckResult.Reason, detail: channelResult.healthCheckResult.Detail})
|
||||
groupedHealthCheckResults[channelResult.healthConditionType].codes = append(groupedHealthCheckResults[channelResult.healthConditionType].codes, channelResult.healthCheckResult.Codes...)
|
||||
continue
|
||||
}
|
||||
if channelResult.healthCheckResult.Status == gardencorev1beta1.ConditionProgressing {
|
||||
groupedHealthCheckResults[channelResult.healthConditionType].progressingChecks = append(groupedHealthCheckResults[channelResult.healthConditionType].progressingChecks, healthCheckProgressing{reason: channelResult.healthCheckResult.Reason, detail: channelResult.healthCheckResult.Detail, threshold: channelResult.healthCheckResult.ProgressingThreshold})
|
||||
groupedHealthCheckResults[channelResult.healthConditionType].codes = append(groupedHealthCheckResults[channelResult.healthConditionType].codes, channelResult.healthCheckResult.Codes...)
|
||||
continue
|
||||
}
|
||||
groupedHealthCheckResults[channelResult.healthConditionType].successfulChecks++
|
||||
}
|
||||
|
||||
var checkResults []Result
|
||||
for conditionType, result := range groupedHealthCheckResults {
|
||||
if len(result.unsuccessfulChecks) > 0 || len(result.failedChecks) > 0 {
|
||||
var details strings.Builder
|
||||
if len(result.unsuccessfulChecks) > 0 {
|
||||
details.WriteString("Unsuccessful checks: ")
|
||||
}
|
||||
for index, check := range result.unsuccessfulChecks {
|
||||
details.WriteString(fmt.Sprintf("%d) %s: %s. ", index+1, check.reason, check.detail))
|
||||
}
|
||||
if len(result.progressingChecks) > 0 {
|
||||
details.WriteString("Progressing checks: ")
|
||||
}
|
||||
for index, check := range result.progressingChecks {
|
||||
details.WriteString(fmt.Sprintf("%d) %s: %s. ", index+1, check.reason, check.detail))
|
||||
}
|
||||
if len(result.failedChecks) > 0 {
|
||||
details.WriteString("Failed checks: ")
|
||||
}
|
||||
for index, err := range result.failedChecks {
|
||||
details.WriteString(fmt.Sprintf("%d) %s. ", index+1, err.Error()))
|
||||
}
|
||||
checkResults = append(checkResults, Result{
|
||||
HealthConditionType: conditionType,
|
||||
Status: gardencorev1beta1.ConditionFalse,
|
||||
Detail: pointer.StringPtr(details.String()),
|
||||
SuccessfulChecks: result.successfulChecks,
|
||||
UnsuccessfulChecks: len(result.unsuccessfulChecks),
|
||||
FailedChecks: len(result.failedChecks),
|
||||
Codes: result.codes,
|
||||
})
|
||||
continue
|
||||
}
|
||||
|
||||
if len(result.progressingChecks) > 0 {
|
||||
var (
|
||||
details strings.Builder
|
||||
threshold *time.Duration
|
||||
)
|
||||
|
||||
details.WriteString("Progressing checks: ")
|
||||
for index, check := range result.progressingChecks {
|
||||
details.WriteString(fmt.Sprintf("%d) %s: %s. ", index+1, check.reason, check.detail))
|
||||
if check.threshold != nil && (threshold == nil || *threshold > *check.threshold) {
|
||||
threshold = check.threshold
|
||||
}
|
||||
}
|
||||
checkResults = append(checkResults, Result{
|
||||
HealthConditionType: conditionType,
|
||||
Status: gardencorev1beta1.ConditionProgressing,
|
||||
ProgressingThreshold: threshold,
|
||||
Detail: pointer.StringPtr(details.String()),
|
||||
SuccessfulChecks: result.successfulChecks,
|
||||
ProgressingChecks: len(result.progressingChecks),
|
||||
Codes: result.codes,
|
||||
})
|
||||
continue
|
||||
}
|
||||
|
||||
checkResults = append(checkResults, Result{
|
||||
HealthConditionType: conditionType,
|
||||
Status: gardencorev1beta1.ConditionTrue,
|
||||
SuccessfulChecks: result.successfulChecks,
|
||||
})
|
||||
}
|
||||
|
||||
return &checkResults, nil
|
||||
}
|
||||
Generated
Vendored
+49
@@ -0,0 +1,49 @@
|
||||
// Copyright (c) 2020 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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 healthcheck
|
||||
|
||||
import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
)
|
||||
|
||||
// ShootClient is an interface to be used to receive a shoot client.
|
||||
type ShootClient interface {
|
||||
// InjectShootClient injects the shoot client
|
||||
InjectShootClient(client.Client)
|
||||
}
|
||||
|
||||
// ShootClient is an interface to be used to receive a seed client.
|
||||
type SeedClient interface {
|
||||
// InjectSeedClient injects the seed client
|
||||
InjectSeedClient(client.Client)
|
||||
}
|
||||
|
||||
// ShootClientInto will set the shoot client on i if i implements ShootClient.
|
||||
func ShootClientInto(client client.Client, i interface{}) bool {
|
||||
if s, ok := i.(ShootClient); ok {
|
||||
s.InjectShootClient(client)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// SeedClientInto will set the seed client on i if i implements SeedClient.
|
||||
func SeedClientInto(client client.Client, i interface{}) bool {
|
||||
if s, ok := i.(SeedClient); ok {
|
||||
s.InjectSeedClient(client)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
Generated
Vendored
+304
@@ -0,0 +1,304 @@
|
||||
// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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 healthcheck
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/tools/record"
|
||||
"k8s.io/client-go/util/retry"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/log"
|
||||
"sigs.k8s.io/controller-runtime/pkg/manager"
|
||||
"sigs.k8s.io/controller-runtime/pkg/reconcile"
|
||||
"sigs.k8s.io/controller-runtime/pkg/runtime/inject"
|
||||
|
||||
extensionscontroller "github.com/gardener/gardener/extensions/pkg/controller"
|
||||
"github.com/gardener/gardener/pkg/api/extensions"
|
||||
gardencorev1beta1 "github.com/gardener/gardener/pkg/apis/core/v1beta1"
|
||||
gardenv1beta1constants "github.com/gardener/gardener/pkg/apis/core/v1beta1/constants"
|
||||
gardencorev1beta1helper "github.com/gardener/gardener/pkg/apis/core/v1beta1/helper"
|
||||
extensionsv1alpha1 "github.com/gardener/gardener/pkg/apis/extensions/v1alpha1"
|
||||
)
|
||||
|
||||
type reconciler struct {
|
||||
logger logr.Logger
|
||||
actuator HealthCheckActuator
|
||||
client client.Client
|
||||
recorder record.EventRecorder
|
||||
registeredExtension RegisteredExtension
|
||||
syncPeriod metav1.Duration
|
||||
}
|
||||
|
||||
const (
|
||||
// ReasonUnsuccessful is the reason phrase for the health check condition if one or more of its tests failed.
|
||||
ReasonUnsuccessful = "HealthCheckUnsuccessful"
|
||||
// ReasonProgressing is the reason phrase for the health check condition if one or more of its tests are progressing.
|
||||
ReasonProgressing = "HealthCheckProgressing"
|
||||
// ReasonSuccessful is the reason phrase for the health check condition if all tests are successful.
|
||||
ReasonSuccessful = "HealthCheckSuccessful"
|
||||
)
|
||||
|
||||
// NewReconciler creates a new performHealthCheck.Reconciler that reconciles
|
||||
// the registered extension resources (Gardener's `extensions.gardener.cloud` API group).
|
||||
func NewReconciler(mgr manager.Manager, actuator HealthCheckActuator, registeredExtension RegisteredExtension, syncPeriod metav1.Duration) reconcile.Reconciler {
|
||||
return &reconciler{
|
||||
logger: log.Log.WithName(ControllerName),
|
||||
actuator: actuator,
|
||||
recorder: mgr.GetEventRecorderFor(ControllerName),
|
||||
registeredExtension: registeredExtension,
|
||||
syncPeriod: syncPeriod,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *reconciler) InjectFunc(f inject.Func) error {
|
||||
return f(r.actuator)
|
||||
}
|
||||
|
||||
func (r *reconciler) InjectClient(client client.Client) error {
|
||||
r.client = client
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *reconciler) Reconcile(ctx context.Context, request reconcile.Request) (reconcile.Result, error) {
|
||||
extension := r.registeredExtension.getExtensionObjFunc()
|
||||
|
||||
if err := r.client.Get(ctx, request.NamespacedName, extension); err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
return r.resultWithRequeue(), nil
|
||||
}
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
|
||||
acc, err := extensions.Accessor(extension.DeepCopyObject())
|
||||
if err != nil {
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
|
||||
if acc.GetDeletionTimestamp() != nil {
|
||||
r.logger.V(6).Info("Do not perform HealthCheck for extension resource. Extension is being deleted.", "name", acc.GetName(), "namespace", acc.GetNamespace())
|
||||
return reconcile.Result{}, nil
|
||||
}
|
||||
|
||||
if isInMigration(acc) {
|
||||
r.logger.Info("Do not perform HealthCheck for extension resource. Extension is being migrated.", "name", acc.GetName(), "namespace", acc.GetNamespace())
|
||||
return reconcile.Result{}, nil
|
||||
}
|
||||
|
||||
cluster, err := extensionscontroller.GetCluster(ctx, r.client, acc.GetNamespace())
|
||||
if err != nil {
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
|
||||
if extensionscontroller.IsHibernated(cluster) {
|
||||
var conditions []condition
|
||||
for _, healthConditionType := range r.registeredExtension.healthConditionTypes {
|
||||
conditionBuilder, err := gardencorev1beta1helper.NewConditionBuilder(gardencorev1beta1.ConditionType(healthConditionType))
|
||||
if err != nil {
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
|
||||
conditions = append(conditions, extensionConditionHibernated(conditionBuilder, healthConditionType))
|
||||
}
|
||||
if err := r.updateExtensionConditions(ctx, extension, conditions...); err != nil {
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
|
||||
r.logger.V(6).Info("Do not perform HealthCheck for extension resource. Shoot is hibernated.", "name", acc.GetName(), "namespace", acc.GetNamespace(), "kind", acc.GetObjectKind().GroupVersionKind().Kind)
|
||||
return reconcile.Result{}, nil
|
||||
}
|
||||
|
||||
r.logger.V(6).Info("Performing health check", "name", acc.GetName(), "namespace", acc.GetNamespace(), "kind", acc.GetObjectKind().GroupVersionKind().Kind)
|
||||
return r.performHealthCheck(ctx, request, extension)
|
||||
}
|
||||
|
||||
func (r *reconciler) performHealthCheck(ctx context.Context, request reconcile.Request, extension extensionsv1alpha1.Object) (reconcile.Result, error) {
|
||||
healthCheckResults, err := r.actuator.ExecuteHealthCheckFunctions(ctx, types.NamespacedName{Namespace: request.Namespace, Name: request.Name})
|
||||
if err != nil {
|
||||
var conditions []condition
|
||||
r.logger.Info("Failed to execute healthChecks. Updating each HealthCheckCondition for the extension resource to ConditionCheckError.", "kind", r.registeredExtension.groupVersionKind.Kind, "health condition types", r.registeredExtension.healthConditionTypes, "name", request.Name, "namespace", request.Namespace, "error", err.Error())
|
||||
for _, healthConditionType := range r.registeredExtension.healthConditionTypes {
|
||||
conditionBuilder, buildErr := gardencorev1beta1helper.NewConditionBuilder(gardencorev1beta1.ConditionType(healthConditionType))
|
||||
if buildErr != nil {
|
||||
return reconcile.Result{}, buildErr
|
||||
}
|
||||
|
||||
conditions = append(conditions, extensionConditionFailedToExecute(conditionBuilder, healthConditionType, r.registeredExtension.groupVersionKind.Kind, err))
|
||||
}
|
||||
if updateErr := r.updateExtensionConditions(ctx, extension, conditions...); updateErr != nil {
|
||||
return reconcile.Result{}, updateErr
|
||||
}
|
||||
return r.resultWithRequeue(), nil
|
||||
}
|
||||
|
||||
conditions := make([]condition, 0, len(*healthCheckResults))
|
||||
for _, healthCheckResult := range *healthCheckResults {
|
||||
conditionBuilder, err := gardencorev1beta1helper.NewConditionBuilder(gardencorev1beta1.ConditionType(healthCheckResult.HealthConditionType))
|
||||
if err != nil {
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
|
||||
var logger logr.Logger
|
||||
if healthCheckResult.Status == gardencorev1beta1.ConditionTrue || healthCheckResult.Status == gardencorev1beta1.ConditionProgressing {
|
||||
logger = r.logger.V(6)
|
||||
} else {
|
||||
logger = r.logger
|
||||
}
|
||||
|
||||
if healthCheckResult.Status == gardencorev1beta1.ConditionProgressing || healthCheckResult.Status == gardencorev1beta1.ConditionFalse {
|
||||
if healthCheckResult.FailedChecks > 0 {
|
||||
r.logger.Info("Updating HealthCheckCondition for extension resource to ConditionCheckError.", "kind", r.registeredExtension.groupVersionKind.Kind, "health condition type", healthCheckResult.HealthConditionType, "name", request.Name, "namespace", request.Namespace)
|
||||
conditions = append(conditions, extensionConditionCheckError(conditionBuilder, healthCheckResult.HealthConditionType, r.registeredExtension.groupVersionKind.Kind, healthCheckResult))
|
||||
continue
|
||||
}
|
||||
|
||||
logger.Info("Health check for extension resource progressing or unsuccessful.", "kind", fmt.Sprintf("%s.%s.%s", r.registeredExtension.groupVersionKind.Kind, r.registeredExtension.groupVersionKind.Group, r.registeredExtension.groupVersionKind.Version), "name", request.Name, "namespace", request.Namespace, "failed", healthCheckResult.FailedChecks, "progressing", healthCheckResult.ProgressingChecks, "successful", healthCheckResult.SuccessfulChecks, "details", healthCheckResult.GetDetails())
|
||||
conditions = append(conditions, extensionConditionUnsuccessful(conditionBuilder, healthCheckResult.HealthConditionType, extension, healthCheckResult))
|
||||
continue
|
||||
}
|
||||
|
||||
logger.Info("Health check for extension resource successful.", "kind", r.registeredExtension.groupVersionKind.Kind, "health condition type", healthCheckResult.HealthConditionType, "name", request.Name, "namespace", request.Namespace)
|
||||
conditions = append(conditions, extensionConditionSuccessful(conditionBuilder, healthCheckResult.HealthConditionType, healthCheckResult))
|
||||
}
|
||||
|
||||
if err := r.updateExtensionConditions(ctx, extension, conditions...); err != nil {
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
|
||||
return r.resultWithRequeue(), nil
|
||||
}
|
||||
|
||||
func extensionConditionFailedToExecute(conditionBuilder gardencorev1beta1helper.ConditionBuilder, healthConditionType string, kind string, executionError error) condition {
|
||||
conditionBuilder.
|
||||
WithStatus(gardencorev1beta1.ConditionUnknown).
|
||||
WithReason(gardencorev1beta1.ConditionCheckError).
|
||||
WithMessage(fmt.Sprintf("failed to execute health checks for '%s': %v", kind, executionError.Error()))
|
||||
return condition{
|
||||
builder: conditionBuilder,
|
||||
healthConditionType: healthConditionType,
|
||||
}
|
||||
}
|
||||
|
||||
func extensionConditionCheckError(conditionBuilder gardencorev1beta1helper.ConditionBuilder, healthConditionType string, kind string, healthCheckResult Result) condition {
|
||||
conditionBuilder.
|
||||
WithStatus(gardencorev1beta1.ConditionUnknown).
|
||||
WithReason(gardencorev1beta1.ConditionCheckError).
|
||||
WithMessage(fmt.Sprintf("failed to execute %d/%d health checks for '%s': %v", healthCheckResult.FailedChecks, healthCheckResult.SuccessfulChecks+healthCheckResult.UnsuccessfulChecks+healthCheckResult.FailedChecks, kind, healthCheckResult.GetDetails()))
|
||||
return condition{
|
||||
builder: conditionBuilder,
|
||||
healthConditionType: healthConditionType,
|
||||
}
|
||||
}
|
||||
|
||||
func extensionConditionUnsuccessful(conditionBuilder gardencorev1beta1helper.ConditionBuilder, healthConditionType string, extension extensionsv1alpha1.Object, healthCheckResult Result) condition {
|
||||
var (
|
||||
numberOfChecks = healthCheckResult.UnsuccessfulChecks + healthCheckResult.ProgressingChecks + healthCheckResult.SuccessfulChecks
|
||||
detail = fmt.Sprintf("Health check summary: %d/%d unsuccessful, %d/%d progressing, %d/%d successful. %v", healthCheckResult.UnsuccessfulChecks, numberOfChecks, healthCheckResult.ProgressingChecks, numberOfChecks, healthCheckResult.SuccessfulChecks, numberOfChecks, healthCheckResult.GetDetails())
|
||||
status = gardencorev1beta1.ConditionFalse
|
||||
reason = ReasonUnsuccessful
|
||||
)
|
||||
|
||||
if healthCheckResult.ProgressingChecks > 0 && healthCheckResult.ProgressingThreshold != nil {
|
||||
if oldCondition := gardencorev1beta1helper.GetCondition(extension.GetExtensionStatus().GetConditions(), gardencorev1beta1.ConditionType(healthConditionType)); oldCondition == nil {
|
||||
status = gardencorev1beta1.ConditionProgressing
|
||||
reason = ReasonProgressing
|
||||
} else if oldCondition.Status != gardencorev1beta1.ConditionFalse {
|
||||
delta := time.Now().UTC().Sub(oldCondition.LastTransitionTime.Time.UTC())
|
||||
if oldCondition.Status == gardencorev1beta1.ConditionTrue || delta <= *healthCheckResult.ProgressingThreshold {
|
||||
status = gardencorev1beta1.ConditionProgressing
|
||||
reason = ReasonProgressing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
conditionBuilder.
|
||||
WithStatus(status).
|
||||
WithReason(reason).
|
||||
WithCodes(healthCheckResult.Codes...).
|
||||
WithMessage(detail)
|
||||
return condition{
|
||||
builder: conditionBuilder,
|
||||
healthConditionType: healthConditionType,
|
||||
}
|
||||
}
|
||||
|
||||
func extensionConditionSuccessful(conditionBuilder gardencorev1beta1helper.ConditionBuilder, healthConditionType string, healthCheckResult Result) condition {
|
||||
conditionBuilder.
|
||||
WithStatus(gardencorev1beta1.ConditionTrue).
|
||||
WithReason(ReasonSuccessful).
|
||||
WithMessage(fmt.Sprintf("(%d/%d) Health checks successful", healthCheckResult.SuccessfulChecks, healthCheckResult.SuccessfulChecks))
|
||||
return condition{
|
||||
builder: conditionBuilder,
|
||||
healthConditionType: healthConditionType,
|
||||
}
|
||||
}
|
||||
|
||||
func extensionConditionHibernated(conditionBuilder gardencorev1beta1helper.ConditionBuilder, healthConditionType string) condition {
|
||||
conditionBuilder.
|
||||
WithStatus(gardencorev1beta1.ConditionTrue).
|
||||
WithReason(ReasonSuccessful).
|
||||
WithMessage("Shoot is hibernated")
|
||||
return condition{
|
||||
builder: conditionBuilder,
|
||||
healthConditionType: healthConditionType,
|
||||
}
|
||||
}
|
||||
|
||||
type condition struct {
|
||||
builder gardencorev1beta1helper.ConditionBuilder
|
||||
healthConditionType string
|
||||
}
|
||||
|
||||
func (r *reconciler) updateExtensionConditions(ctx context.Context, extension extensionsv1alpha1.Object, conditions ...condition) error {
|
||||
return extensionscontroller.TryPatchStatus(ctx, retry.DefaultBackoff, r.client, extension, func() error {
|
||||
for _, cond := range conditions {
|
||||
now := metav1.Now()
|
||||
if c := gardencorev1beta1helper.GetCondition(extension.GetExtensionStatus().GetConditions(), gardencorev1beta1.ConditionType(cond.healthConditionType)); c != nil {
|
||||
cond.builder.WithOldCondition(*c)
|
||||
}
|
||||
updatedCondition, _ := cond.builder.WithNowFunc(func() metav1.Time { return now }).Build()
|
||||
// always update - the Gardenlet expects a recent health check
|
||||
updatedCondition.LastUpdateTime = now
|
||||
extension.GetExtensionStatus().SetConditions(gardencorev1beta1helper.MergeConditions(extension.GetExtensionStatus().GetConditions(), updatedCondition))
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (r *reconciler) resultWithRequeue() reconcile.Result {
|
||||
return reconcile.Result{RequeueAfter: r.syncPeriod.Duration}
|
||||
}
|
||||
|
||||
func isInMigration(accessor extensionsv1alpha1.Object) bool {
|
||||
annotations := accessor.GetAnnotations()
|
||||
if annotations != nil &&
|
||||
annotations[gardenv1beta1constants.GardenerOperation] == gardenv1beta1constants.GardenerOperationMigrate {
|
||||
return true
|
||||
}
|
||||
|
||||
status := accessor.GetExtensionStatus()
|
||||
if status == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
lastOperation := status.GetLastOperation()
|
||||
return lastOperation != nil && lastOperation.Type == gardencorev1beta1.LastOperationTypeMigrate
|
||||
}
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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 controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/event"
|
||||
)
|
||||
|
||||
// CreateEventLogger creates a Logger with keys and values from the given CreateEvent.
|
||||
func CreateEventLogger(log logr.Logger, event event.CreateEvent) logr.Logger {
|
||||
return log.WithValues(CreateEventLogValues(event)...)
|
||||
}
|
||||
|
||||
// UpdateEventLogger creates a Logger with keys and values from the given UpdateEvent.
|
||||
func UpdateEventLogger(log logr.Logger, event event.UpdateEvent) logr.Logger {
|
||||
return log.WithValues(UpdateEventLogValues(event)...)
|
||||
}
|
||||
|
||||
// DeleteEventLogger creates a Logger with keys and values from the given DeleteEvent.
|
||||
func DeleteEventLogger(log logr.Logger, event event.DeleteEvent) logr.Logger {
|
||||
return log.WithValues(DeleteEventLogValues(event)...)
|
||||
}
|
||||
|
||||
// GenericEventLogger creates a Logger with keys and values from the given GenericEvent.
|
||||
func GenericEventLogger(log logr.Logger, event event.GenericEvent) logr.Logger {
|
||||
return log.WithValues(GenericEventLogValues(event)...)
|
||||
}
|
||||
|
||||
// PrefixLogValues prefixes the keys of the given logValues with the given prefix.
|
||||
func PrefixLogValues(prefix string, logValues []interface{}) []interface{} {
|
||||
if prefix == "" {
|
||||
return logValues
|
||||
}
|
||||
if logValues == nil {
|
||||
return logValues
|
||||
}
|
||||
|
||||
out := make([]interface{}, 0, len(logValues))
|
||||
for i := 0; i < len(logValues); i += 2 {
|
||||
key := logValues[i]
|
||||
value := logValues[i+1]
|
||||
out = append(out, fmt.Sprintf("%s.%s", prefix, key), value)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// CreateEventLogValues extracts the log values from the given CreateEvent.
|
||||
func CreateEventLogValues(event event.CreateEvent) []interface{} {
|
||||
return ObjectLogValues(event.Object)
|
||||
}
|
||||
|
||||
// DeleteEventLogValues extracts the log values from the given DeleteEvent.
|
||||
func DeleteEventLogValues(event event.DeleteEvent) []interface{} {
|
||||
return append(ObjectLogValues(event.Object), "delete-state-unknown", event.DeleteStateUnknown)
|
||||
}
|
||||
|
||||
// GenericEventLogValues extracts the log values from the given GenericEvent.
|
||||
func GenericEventLogValues(event event.GenericEvent) []interface{} {
|
||||
return ObjectLogValues(event.Object)
|
||||
}
|
||||
|
||||
// UpdateEventLogValues extracts the log values from the given UpdateEvent.
|
||||
func UpdateEventLogValues(event event.UpdateEvent) []interface{} {
|
||||
var values []interface{}
|
||||
values = append(values, PrefixLogValues("old", ObjectLogValues(event.ObjectOld))...)
|
||||
values = append(values, PrefixLogValues("new", ObjectLogValues(event.ObjectNew))...)
|
||||
return values
|
||||
}
|
||||
|
||||
// ObjectLogValues extracts the log values from the given client.Object.
|
||||
func ObjectLogValues(obj client.Object) []interface{} {
|
||||
values := []interface{}{"meta.name", obj.GetName()}
|
||||
if namespace := obj.GetNamespace(); namespace != "" {
|
||||
values = append(values, "meta.namespace", namespace)
|
||||
}
|
||||
apiVersion, kind := obj.GetObjectKind().GroupVersionKind().ToAPIVersionAndKind()
|
||||
values = append(values, "object.apiVersion", apiVersion, "object.kind", kind)
|
||||
return values
|
||||
}
|
||||
Generated
Vendored
+44
@@ -0,0 +1,44 @@
|
||||
// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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 controller
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gardener/gardener/pkg/chartrenderer"
|
||||
"github.com/gardener/gardener/pkg/utils/chart"
|
||||
"github.com/gardener/gardener/pkg/utils/imagevector"
|
||||
"github.com/gardener/gardener/pkg/utils/managedresources"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
)
|
||||
|
||||
// RenderChartAndCreateManagedResource renders a chart and creates a ManagedResource for the gardener-resource-manager
|
||||
// out of the results.
|
||||
func RenderChartAndCreateManagedResource(ctx context.Context, namespace string, name string, client client.Client, chartRenderer chartrenderer.Interface, chart chart.Interface, values map[string]interface{}, imageVector imagevector.ImageVector, chartNamespace string, version string, withNoCleanupLabel bool, forceOverwriteAnnotations bool) error {
|
||||
chartName, data, err := chart.Render(chartRenderer, chartNamespace, imageVector, version, version, values)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "could not render chart")
|
||||
}
|
||||
|
||||
// Create or update managed resource referencing the previously created secret
|
||||
var injectedLabels map[string]string
|
||||
if withNoCleanupLabel {
|
||||
injectedLabels = map[string]string{ShootNoCleanupLabel: "true"}
|
||||
}
|
||||
|
||||
return managedresources.CreateManagedResource(ctx, client, namespace, name, "", chartName, data, false, injectedLabels, forceOverwriteAnnotations)
|
||||
}
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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 controller
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
v1beta1constants "github.com/gardener/gardener/pkg/apis/core/v1beta1/constants"
|
||||
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/reconcile"
|
||||
"sigs.k8s.io/controller-runtime/pkg/runtime/inject"
|
||||
)
|
||||
|
||||
type operationAnnotationWrapper struct {
|
||||
reconcile.Reconciler
|
||||
client client.Client
|
||||
newObjFunc func() client.Object
|
||||
}
|
||||
|
||||
// OperationAnnotationWrapper is a wrapper for an reconciler that
|
||||
// removes the Gardener operation annotation before `Reconcile` is called.
|
||||
//
|
||||
// This is useful in conjunction with the HasOperationAnnotationPredicate.
|
||||
func OperationAnnotationWrapper(newObjFunc func() client.Object, reconciler reconcile.Reconciler) reconcile.Reconciler {
|
||||
return &operationAnnotationWrapper{
|
||||
newObjFunc: newObjFunc,
|
||||
Reconciler: reconciler,
|
||||
}
|
||||
}
|
||||
|
||||
// InjectClient implements inject.Client.
|
||||
func (o *operationAnnotationWrapper) InjectClient(client client.Client) error {
|
||||
o.client = client
|
||||
return nil
|
||||
}
|
||||
|
||||
// InjectClient implements inject.Func.
|
||||
func (o *operationAnnotationWrapper) InjectFunc(f inject.Func) error {
|
||||
return f(o.Reconciler)
|
||||
}
|
||||
|
||||
// Reconcile removes the Gardener operation annotation if available and calls the inner `Reconcile`.
|
||||
func (o *operationAnnotationWrapper) Reconcile(ctx context.Context, request reconcile.Request) (reconcile.Result, error) {
|
||||
obj := o.newObjFunc()
|
||||
if err := o.client.Get(ctx, request.NamespacedName, obj); client.IgnoreNotFound(err) != nil {
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
|
||||
annotations := obj.GetAnnotations()
|
||||
if annotations[v1beta1constants.GardenerOperation] == v1beta1constants.GardenerOperationWaitForState {
|
||||
return reconcile.Result{}, nil
|
||||
}
|
||||
|
||||
if annotations[v1beta1constants.GardenerOperation] == v1beta1constants.GardenerOperationReconcile {
|
||||
withOpAnnotation := obj.DeepCopyObject()
|
||||
delete(annotations, v1beta1constants.GardenerOperation)
|
||||
obj.SetAnnotations(annotations)
|
||||
if err := o.client.Patch(ctx, obj, client.MergeFrom(withOpAnnotation)); err != nil {
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
}
|
||||
return o.Reconciler.Reconcile(ctx, request)
|
||||
}
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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 controller
|
||||
|
||||
import (
|
||||
gardencorev1beta1 "github.com/gardener/gardener/pkg/apis/core/v1beta1"
|
||||
"github.com/gardener/gardener/pkg/chartrenderer"
|
||||
)
|
||||
|
||||
const (
|
||||
// ShootNoCleanupLabel is a constant for a label on a resource indicating that the Gardener cleaner should not delete this
|
||||
// resource when cleaning a shoot during the deletion flow.
|
||||
ShootNoCleanupLabel = "shoot.gardener.cloud/no-cleanup"
|
||||
)
|
||||
|
||||
// ChartRendererFactory creates chartrenderer.Interface to be used by this actuator.
|
||||
type ChartRendererFactory interface {
|
||||
// NewChartRendererForShoot creates a new chartrenderer.Interface for the shoot cluster.
|
||||
NewChartRendererForShoot(string) (chartrenderer.Interface, error)
|
||||
}
|
||||
|
||||
// ChartRendererFactoryFunc is a function that satisfies ChartRendererFactory.
|
||||
type ChartRendererFactoryFunc func(string) (chartrenderer.Interface, error)
|
||||
|
||||
// NewChartRendererForShoot creates a new chartrenderer.Interface for the shoot cluster.
|
||||
func (f ChartRendererFactoryFunc) NewChartRendererForShoot(version string) (chartrenderer.Interface, error) {
|
||||
return f(version)
|
||||
}
|
||||
|
||||
// GetPodNetwork returns the pod network CIDR of the given Shoot.
|
||||
func GetPodNetwork(cluster *Cluster) string {
|
||||
if cluster.Shoot.Spec.Networking.Pods != nil {
|
||||
return *cluster.Shoot.Spec.Networking.Pods
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// GetServiceNetwork returns the service network CIDR of the given Shoot.
|
||||
func GetServiceNetwork(cluster *Cluster) string {
|
||||
if cluster.Shoot.Spec.Networking.Services != nil {
|
||||
return *cluster.Shoot.Spec.Networking.Services
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// IsHibernated returns true if the shoot is hibernated, or false otherwise.
|
||||
func IsHibernated(cluster *Cluster) bool {
|
||||
return cluster.Shoot.Spec.Hibernation != nil && cluster.Shoot.Spec.Hibernation.Enabled != nil && *cluster.Shoot.Spec.Hibernation.Enabled
|
||||
}
|
||||
|
||||
// IsFailed returns true if the embedded shoot is failed, or false otherwise.
|
||||
func IsFailed(cluster *Cluster) bool {
|
||||
return IsShootFailed(cluster.Shoot)
|
||||
}
|
||||
|
||||
// IsShootFailed returns true if the shoot is failed, or false otherwise.
|
||||
func IsShootFailed(shoot *gardencorev1beta1.Shoot) bool {
|
||||
if shoot == nil {
|
||||
return false
|
||||
}
|
||||
lastOperation := shoot.Status.LastOperation
|
||||
return lastOperation != nil && lastOperation.State == gardencorev1beta1.LastOperationStateFailed
|
||||
}
|
||||
|
||||
// IsUnmanagedDNSProvider returns true if the shoot uses an unmanaged DNS provider.
|
||||
func IsUnmanagedDNSProvider(cluster *Cluster) bool {
|
||||
dns := cluster.Shoot.Spec.DNS
|
||||
return dns == nil || (dns.Domain == nil && len(dns.Providers) > 0 && dns.Providers[0].Type != nil && *dns.Providers[0].Type == "unmanaged")
|
||||
}
|
||||
|
||||
// GetReplicas returns the woken up replicas of the given Shoot.
|
||||
func GetReplicas(cluster *Cluster, wokenUp int) int {
|
||||
if IsHibernated(cluster) {
|
||||
return 0
|
||||
}
|
||||
return wokenUp
|
||||
}
|
||||
|
||||
// GetControlPlaneReplicas returns the woken up replicas for controlplane components of the given Shoot
|
||||
// that should only be scaled down at the end of the flow.
|
||||
func GetControlPlaneReplicas(cluster *Cluster, scaledDown bool, wokenUp int) int {
|
||||
if cluster.Shoot != nil && cluster.Shoot.DeletionTimestamp == nil && IsHibernated(cluster) && scaledDown {
|
||||
return 0
|
||||
}
|
||||
return wokenUp
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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 controller
|
||||
|
||||
import (
|
||||
gardencorev1beta1 "github.com/gardener/gardener/pkg/apis/core/v1beta1"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// LastOperation creates a new LastOperation from the given parameters.
|
||||
func LastOperation(t gardencorev1beta1.LastOperationType, state gardencorev1beta1.LastOperationState, progress int32, description string) *gardencorev1beta1.LastOperation {
|
||||
return &gardencorev1beta1.LastOperation{
|
||||
LastUpdateTime: metav1.Now(),
|
||||
Type: t,
|
||||
State: state,
|
||||
Description: description,
|
||||
Progress: progress,
|
||||
}
|
||||
}
|
||||
|
||||
// LastError creates a new LastError from the given parameters.
|
||||
func LastError(description string, codes ...gardencorev1beta1.ErrorCode) *gardencorev1beta1.LastError {
|
||||
now := metav1.Now()
|
||||
|
||||
return &gardencorev1beta1.LastError{
|
||||
Description: description,
|
||||
Codes: codes,
|
||||
LastUpdateTime: &now,
|
||||
}
|
||||
}
|
||||
|
||||
// ReconcileSucceeded returns a LastOperation with state succeeded at 100 percent and a nil LastError.
|
||||
func ReconcileSucceeded(t gardencorev1beta1.LastOperationType, description string) (*gardencorev1beta1.LastOperation, *gardencorev1beta1.LastError) {
|
||||
return LastOperation(t, gardencorev1beta1.LastOperationStateSucceeded, 100, description), nil
|
||||
}
|
||||
|
||||
// ReconcileError returns a LastOperation with state error and a LastError with the given description and codes.
|
||||
func ReconcileError(t gardencorev1beta1.LastOperationType, description string, progress int32, codes ...gardencorev1beta1.ErrorCode) (*gardencorev1beta1.LastOperation, *gardencorev1beta1.LastError) {
|
||||
return LastOperation(t, gardencorev1beta1.LastOperationStateError, progress, description), LastError(description, codes...)
|
||||
}
|
||||
+257
@@ -0,0 +1,257 @@
|
||||
// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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 controller
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
controllererror "github.com/gardener/gardener/extensions/pkg/controller/error"
|
||||
"github.com/gardener/gardener/pkg/api/extensions"
|
||||
gardencorev1beta1 "github.com/gardener/gardener/pkg/apis/core/v1beta1"
|
||||
v1beta1constants "github.com/gardener/gardener/pkg/apis/core/v1beta1/constants"
|
||||
extensionsv1alpha1 "github.com/gardener/gardener/pkg/apis/extensions/v1alpha1"
|
||||
"github.com/gardener/gardener/pkg/controllerutils"
|
||||
kutil "github.com/gardener/gardener/pkg/utils/kubernetes"
|
||||
|
||||
resourcemanagerv1alpha1 "github.com/gardener/gardener-resource-manager/pkg/apis/resources/v1alpha1"
|
||||
autoscalingv1 "k8s.io/api/autoscaling/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
autoscalingv1beta2 "k8s.io/autoscaler/vertical-pod-autoscaler/pkg/apis/autoscaling.k8s.io/v1beta2"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/client-go/util/retry"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/controller"
|
||||
"sigs.k8s.io/controller-runtime/pkg/manager"
|
||||
"sigs.k8s.io/controller-runtime/pkg/reconcile"
|
||||
)
|
||||
|
||||
var (
|
||||
localSchemeBuilder = runtime.NewSchemeBuilder(
|
||||
scheme.AddToScheme,
|
||||
extensionsv1alpha1.AddToScheme,
|
||||
resourcemanagerv1alpha1.AddToScheme,
|
||||
)
|
||||
|
||||
// AddToScheme adds the Kubernetes and extension scheme to the given scheme.
|
||||
AddToScheme = localSchemeBuilder.AddToScheme
|
||||
|
||||
// ExtensionsScheme is the default scheme for extensions, consisting of all Kubernetes built-in
|
||||
// schemes (client-go/kubernetes/scheme) and the extensions/v1alpha1 scheme.
|
||||
ExtensionsScheme = runtime.NewScheme()
|
||||
)
|
||||
|
||||
func init() {
|
||||
utilruntime.Must(AddToScheme(ExtensionsScheme))
|
||||
}
|
||||
|
||||
// ReconcileErr returns a reconcile.Result or an error, depending on whether the error is a
|
||||
// RequeueAfterError or not.
|
||||
func ReconcileErr(err error) (reconcile.Result, error) {
|
||||
if requeueAfter, ok := err.(*controllererror.RequeueAfterError); ok {
|
||||
return reconcile.Result{Requeue: true, RequeueAfter: requeueAfter.RequeueAfter}, nil
|
||||
}
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
|
||||
// ReconcileErrCause returns the cause in case the error is an RequeueAfterError. Otherwise,
|
||||
// it returns the input error.
|
||||
func ReconcileErrCause(err error) error {
|
||||
if requeueAfter, ok := err.(*controllererror.RequeueAfterError); ok {
|
||||
return requeueAfter.Cause
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// ReconcileErrCauseOrErr returns the cause of the error or the error if the cause is nil.
|
||||
func ReconcileErrCauseOrErr(err error) error {
|
||||
if cause := ReconcileErrCause(err); cause != nil {
|
||||
return cause
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// AddToManagerBuilder aggregates various AddToManager functions.
|
||||
type AddToManagerBuilder []func(manager.Manager) error
|
||||
|
||||
// NewAddToManagerBuilder creates a new AddToManagerBuilder and registers the given functions.
|
||||
func NewAddToManagerBuilder(funcs ...func(manager.Manager) error) AddToManagerBuilder {
|
||||
var builder AddToManagerBuilder
|
||||
builder.Register(funcs...)
|
||||
return builder
|
||||
}
|
||||
|
||||
// Register registers the given functions in this builder.
|
||||
func (a *AddToManagerBuilder) Register(funcs ...func(manager.Manager) error) {
|
||||
*a = append(*a, funcs...)
|
||||
}
|
||||
|
||||
// AddToManager traverses over all AddToManager-functions of this builder, sequentially applying
|
||||
// them. It exits on the first error and returns it.
|
||||
func (a *AddToManagerBuilder) AddToManager(m manager.Manager) error {
|
||||
for _, f := range *a {
|
||||
if err := f(m); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func finalizersAndAccessorOf(obj runtime.Object) (sets.String, metav1.Object, error) {
|
||||
accessor, err := meta.Accessor(obj)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return sets.NewString(accessor.GetFinalizers()...), accessor, nil
|
||||
}
|
||||
|
||||
// HasFinalizer checks if the given object has a finalizer with the given name.
|
||||
func HasFinalizer(obj runtime.Object, finalizerName string) (bool, error) {
|
||||
finalizers, _, err := finalizersAndAccessorOf(obj)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return finalizers.Has(finalizerName), nil
|
||||
}
|
||||
|
||||
// EnsureFinalizer ensures that a finalizer of the given name is set on the given object.
|
||||
// If the finalizer is not set, it adds it to the list of finalizers and updates the remote object.
|
||||
var EnsureFinalizer = controllerutils.EnsureFinalizer
|
||||
|
||||
// DeleteFinalizer ensures that the given finalizer is not present anymore in the given object.
|
||||
// If it is set, it removes it and issues an update.
|
||||
var DeleteFinalizer = controllerutils.RemoveFinalizer
|
||||
|
||||
// DeleteAllFinalizers removes all finalizers from the object and issues an update.
|
||||
func DeleteAllFinalizers(ctx context.Context, client client.Client, obj client.Object) error {
|
||||
return TryUpdate(ctx, retry.DefaultBackoff, client, obj, func() error {
|
||||
obj.SetFinalizers(nil)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// SecretReferenceToKey returns the key of the given SecretReference.
|
||||
func SecretReferenceToKey(ref *corev1.SecretReference) client.ObjectKey {
|
||||
return kutil.Key(ref.Namespace, ref.Name)
|
||||
}
|
||||
|
||||
// GetSecretByReference returns the Secret object matching the given SecretReference.
|
||||
func GetSecretByReference(ctx context.Context, c client.Client, ref *corev1.SecretReference) (*corev1.Secret, error) {
|
||||
secret := &corev1.Secret{}
|
||||
if err := c.Get(ctx, SecretReferenceToKey(ref), secret); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return secret, nil
|
||||
}
|
||||
|
||||
// TryPatch tries to apply the given transformation function onto the given object, and to patch it afterwards with optimistic locking.
|
||||
// It retries the patch with an exponential backoff.
|
||||
var TryPatch = kutil.TryPatch
|
||||
|
||||
// TryPatchStatus tries to apply the given transformation function onto the given object, and to patch its
|
||||
// status afterwards with optimistic locking. It retries the status patch with an exponential backoff.
|
||||
var TryPatchStatus = kutil.TryPatchStatus
|
||||
|
||||
// TryUpdate tries to apply the given transformation function onto the given object, and to update it afterwards.
|
||||
// It retries the update with an exponential backoff.
|
||||
var TryUpdate = kutil.TryUpdate
|
||||
|
||||
// TryUpdateStatus tries to apply the given transformation function onto the given object, and to update its
|
||||
// status afterwards. It retries the status update with an exponential backoff.
|
||||
var TryUpdateStatus = kutil.TryUpdateStatus
|
||||
|
||||
// WatchBuilder holds various functions which add watch controls to the passed Controller.
|
||||
type WatchBuilder []func(controller.Controller) error
|
||||
|
||||
// NewWatchBuilder creates a new WatchBuilder and registers the given functions.
|
||||
func NewWatchBuilder(funcs ...func(controller.Controller) error) WatchBuilder {
|
||||
var builder WatchBuilder
|
||||
builder.Register(funcs...)
|
||||
return builder
|
||||
}
|
||||
|
||||
// Register adds a function which add watch controls to the passed Controller to the WatchBuilder.
|
||||
func (w *WatchBuilder) Register(funcs ...func(controller.Controller) error) {
|
||||
*w = append(*w, funcs...)
|
||||
}
|
||||
|
||||
// AddToController adds the registered watches to the passed controller.
|
||||
func (w *WatchBuilder) AddToController(ctrl controller.Controller) error {
|
||||
for _, f := range *w {
|
||||
if err := f(ctrl); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnsafeGuessKind makes an unsafe guess what is the kind of the given object.
|
||||
//
|
||||
// The argument to this method _has_ to be a pointer, otherwise it panics.
|
||||
func UnsafeGuessKind(obj runtime.Object) string {
|
||||
t := reflect.TypeOf(obj)
|
||||
if t.Kind() != reflect.Ptr {
|
||||
panic(fmt.Sprintf("kind of obj %T is not pointer", obj))
|
||||
}
|
||||
|
||||
return t.Elem().Name()
|
||||
}
|
||||
|
||||
// GetVerticalPodAutoscalerObject returns unstructured.Unstructured representing autoscalingv1beta2.VerticalPodAutoscaler
|
||||
func GetVerticalPodAutoscalerObject() *unstructured.Unstructured {
|
||||
obj := &unstructured.Unstructured{}
|
||||
obj.SetAPIVersion(autoscalingv1beta2.SchemeGroupVersion.String())
|
||||
obj.SetKind("VerticalPodAutoscaler")
|
||||
return obj
|
||||
}
|
||||
|
||||
// RemoveAnnotation removes an annotation key passed as annotation
|
||||
func RemoveAnnotation(ctx context.Context, c client.Client, obj client.Object, annotation string) error {
|
||||
withAnnotation := obj.DeepCopyObject()
|
||||
|
||||
annotations := obj.GetAnnotations()
|
||||
delete(annotations, annotation)
|
||||
obj.SetAnnotations(annotations)
|
||||
|
||||
return c.Patch(ctx, obj, client.MergeFrom(withAnnotation))
|
||||
}
|
||||
|
||||
// IsMigrated checks if an extension object has been migrated
|
||||
func IsMigrated(obj runtime.Object) bool {
|
||||
acc, err := extensions.Accessor(obj)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
lastOp := acc.GetExtensionStatus().GetLastOperation()
|
||||
return lastOp != nil &&
|
||||
lastOp.Type == gardencorev1beta1.LastOperationTypeMigrate &&
|
||||
lastOp.State == gardencorev1beta1.LastOperationStateSucceeded
|
||||
}
|
||||
|
||||
// GetObjectByReference gets an object by the given reference, in the given namespace.
|
||||
// If the object kind doesn't match the given reference kind this will result in an error.
|
||||
func GetObjectByReference(ctx context.Context, c client.Client, ref *autoscalingv1.CrossVersionObjectReference, namespace string, obj client.Object) error {
|
||||
return c.Get(ctx, client.ObjectKey{Namespace: namespace, Name: v1beta1constants.ReferencedResourcesPrefix + ref.Name}, obj)
|
||||
}
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
// Copyright (c) 2021 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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 handler
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/event"
|
||||
"sigs.k8s.io/controller-runtime/pkg/handler"
|
||||
"sigs.k8s.io/controller-runtime/pkg/reconcile"
|
||||
"sigs.k8s.io/controller-runtime/pkg/runtime/inject"
|
||||
)
|
||||
|
||||
// Mapper maps an object to a collection of keys to be enqueued
|
||||
type Mapper interface {
|
||||
// Map maps an object
|
||||
Map(obj client.Object) []reconcile.Request
|
||||
}
|
||||
|
||||
var _ Mapper = MapFunc(nil)
|
||||
|
||||
// MapFunc is the signature required for enqueueing requests from a generic function.
|
||||
// This type is usually used with EnqueueRequestsFromMapFunc when registering an event handler.
|
||||
type MapFunc func(client.Object) []reconcile.Request
|
||||
|
||||
// Map implements Mapper.
|
||||
func (f MapFunc) Map(obj client.Object) []reconcile.Request {
|
||||
return f(obj)
|
||||
}
|
||||
|
||||
// EnqueueRequestsFromMapper is similar to controller-runtime's handler.EnqueueRequestsFromMapFunc.
|
||||
// Instead of taking only a MapFunc it also allows passing a Mapper interface. Also, it allows customizing the
|
||||
// behaviour on UpdateEvents.
|
||||
// For UpdateEvents, the given UpdateBehaviour decides if only the old, only the new or both objects should be mapped
|
||||
// and enqueued.
|
||||
func EnqueueRequestsFromMapper(m Mapper, updateBehavior UpdateBehavior) handler.EventHandler {
|
||||
return &enqueueRequestsFromMapFunc{
|
||||
mapper: m,
|
||||
updateBehavior: updateBehavior,
|
||||
}
|
||||
}
|
||||
|
||||
type enqueueRequestsFromMapFunc struct {
|
||||
// mapper transforms the argument into a slice of keys to be reconciled
|
||||
mapper Mapper
|
||||
// updateBehaviour decides which object(s) to map and enqueue on updates
|
||||
updateBehavior UpdateBehavior
|
||||
}
|
||||
|
||||
// Create implements EventHandler
|
||||
func (e *enqueueRequestsFromMapFunc) Create(evt event.CreateEvent, q workqueue.RateLimitingInterface) {
|
||||
e.mapAndEnqueue(q, evt.Object)
|
||||
}
|
||||
|
||||
// Update implements EventHandler
|
||||
func (e *enqueueRequestsFromMapFunc) Update(evt event.UpdateEvent, q workqueue.RateLimitingInterface) {
|
||||
switch e.updateBehavior {
|
||||
case UpdateWithOldAndNew:
|
||||
e.mapAndEnqueue(q, evt.ObjectOld)
|
||||
e.mapAndEnqueue(q, evt.ObjectNew)
|
||||
case UpdateWithOld:
|
||||
e.mapAndEnqueue(q, evt.ObjectOld)
|
||||
case UpdateWithNew:
|
||||
e.mapAndEnqueue(q, evt.ObjectNew)
|
||||
}
|
||||
}
|
||||
|
||||
// Delete implements EventHandler
|
||||
func (e *enqueueRequestsFromMapFunc) Delete(evt event.DeleteEvent, q workqueue.RateLimitingInterface) {
|
||||
e.mapAndEnqueue(q, evt.Object)
|
||||
}
|
||||
|
||||
// Generic implements EventHandler
|
||||
func (e *enqueueRequestsFromMapFunc) Generic(evt event.GenericEvent, q workqueue.RateLimitingInterface) {
|
||||
e.mapAndEnqueue(q, evt.Object)
|
||||
}
|
||||
|
||||
func (e *enqueueRequestsFromMapFunc) mapAndEnqueue(q workqueue.RateLimitingInterface, object client.Object) {
|
||||
for _, req := range e.mapper.Map(object) {
|
||||
q.Add(req)
|
||||
}
|
||||
}
|
||||
|
||||
// EnqueueRequestsFromMapper can inject fields into the mapper.
|
||||
|
||||
// InjectFunc implements inject.Injector.
|
||||
func (e *enqueueRequestsFromMapFunc) InjectFunc(f inject.Func) error {
|
||||
if f == nil {
|
||||
return nil
|
||||
}
|
||||
return f(e.mapper)
|
||||
}
|
||||
|
||||
// UpdateBehavior determines how an update should be handled.
|
||||
type UpdateBehavior uint8
|
||||
|
||||
const (
|
||||
// UpdateWithOldAndNew considers both, the old as well as the new object, in case of an update.
|
||||
UpdateWithOldAndNew UpdateBehavior = iota
|
||||
// UpdateWithOld considers only the old object in case of an update.
|
||||
UpdateWithOld
|
||||
// UpdateWithNew considers only the new object in case of an update.
|
||||
UpdateWithNew
|
||||
)
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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 handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/predicate"
|
||||
"sigs.k8s.io/controller-runtime/pkg/reconcile"
|
||||
"sigs.k8s.io/controller-runtime/pkg/runtime/inject"
|
||||
|
||||
extensionspredicate "github.com/gardener/gardener/extensions/pkg/predicate"
|
||||
extensionsv1alpha1 "github.com/gardener/gardener/pkg/apis/extensions/v1alpha1"
|
||||
contextutil "github.com/gardener/gardener/pkg/utils/context"
|
||||
)
|
||||
|
||||
type clusterToObjectMapper struct {
|
||||
ctx context.Context
|
||||
client client.Client
|
||||
newObjListFunc func() client.ObjectList
|
||||
predicates []predicate.Predicate
|
||||
}
|
||||
|
||||
func (m *clusterToObjectMapper) InjectClient(c client.Client) error {
|
||||
m.client = c
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *clusterToObjectMapper) InjectStopChannel(stopCh <-chan struct{}) error {
|
||||
m.ctx = contextutil.FromStopChannel(stopCh)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *clusterToObjectMapper) InjectFunc(f inject.Func) error {
|
||||
for _, p := range m.predicates {
|
||||
if err := f(p); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *clusterToObjectMapper) Map(obj client.Object) []reconcile.Request {
|
||||
cluster, ok := obj.(*extensionsv1alpha1.Cluster)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
objList := m.newObjListFunc()
|
||||
if err := m.client.List(m.ctx, objList, client.InNamespace(cluster.Name)); err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var requests []reconcile.Request
|
||||
|
||||
utilruntime.HandleError(meta.EachListItem(objList, func(obj runtime.Object) error {
|
||||
o := obj.(client.Object)
|
||||
if !extensionspredicate.EvalGeneric(o, m.predicates...) {
|
||||
return nil
|
||||
}
|
||||
|
||||
requests = append(requests, reconcile.Request{
|
||||
NamespacedName: types.NamespacedName{
|
||||
Namespace: o.GetNamespace(),
|
||||
Name: o.GetName(),
|
||||
},
|
||||
})
|
||||
return nil
|
||||
}))
|
||||
return requests
|
||||
}
|
||||
|
||||
// ClusterToObjectMapper returns a mapper that returns requests for objects whose
|
||||
// referenced clusters have been modified.
|
||||
func ClusterToObjectMapper(newObjListFunc func() client.ObjectList, predicates []predicate.Predicate) Mapper {
|
||||
return &clusterToObjectMapper{newObjListFunc: newObjListFunc, predicates: predicates}
|
||||
}
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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 inject
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
contextutil "github.com/gardener/gardener/pkg/utils/context"
|
||||
|
||||
"sigs.k8s.io/controller-runtime/pkg/cache"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
)
|
||||
|
||||
// WithClient contains an instance of `client.Client`.
|
||||
type WithClient struct {
|
||||
Client client.Client
|
||||
}
|
||||
|
||||
// InjectClient implements `inject.InjectClient`.
|
||||
func (w *WithClient) InjectClient(c client.Client) error {
|
||||
w.Client = c
|
||||
return nil
|
||||
}
|
||||
|
||||
// WithStopChannel contains a stop channel.
|
||||
type WithStopChannel struct {
|
||||
StopChannel <-chan struct{}
|
||||
}
|
||||
|
||||
// InjectStopChannel implements `inject.InjectStopChannel`.
|
||||
func (w *WithStopChannel) InjectStopChannel(stopChan <-chan struct{}) error {
|
||||
w.StopChannel = stopChan
|
||||
return nil
|
||||
}
|
||||
|
||||
// WithContext contains a `context.Context`.
|
||||
type WithContext struct {
|
||||
Context context.Context
|
||||
}
|
||||
|
||||
// InjectStopChannel implements `inject.InjectStopChannel`.
|
||||
func (w *WithContext) InjectStopChannel(stopChan <-chan struct{}) error {
|
||||
w.Context = contextutil.FromStopChannel(stopChan)
|
||||
return nil
|
||||
}
|
||||
|
||||
// WithCache contains an instance of `cache.Cache`.
|
||||
type WithCache struct {
|
||||
Cache cache.Cache
|
||||
}
|
||||
|
||||
// InjectCache implements `inject.InjectCache`.
|
||||
func (w *WithCache) InjectCache(cache cache.Cache) error {
|
||||
w.Cache = cache
|
||||
return nil
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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 log
|
||||
|
||||
import (
|
||||
"github.com/go-logr/logr"
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
logzap "sigs.k8s.io/controller-runtime/pkg/log/zap"
|
||||
)
|
||||
|
||||
// ZapLogger is a Logger implementation.
|
||||
// If development is true, a Zap development config will be used
|
||||
// (stacktraces on warnings, no sampling), otherwise a Zap production
|
||||
// config will be used (stacktraces on errors, sampling).
|
||||
// Additionally, the time encoding is adjusted to `zapcore.ISO8601TimeEncoder`.
|
||||
func ZapLogger(development bool) logr.Logger {
|
||||
return logzap.New(func(o *logzap.Options) {
|
||||
var encCfg zapcore.EncoderConfig
|
||||
if development {
|
||||
encCfg = zap.NewDevelopmentEncoderConfig()
|
||||
} else {
|
||||
encCfg = zap.NewProductionEncoderConfig()
|
||||
}
|
||||
encCfg.EncodeTime = zapcore.ISO8601TimeEncoder
|
||||
|
||||
o.Encoder = zapcore.NewJSONEncoder(encCfg)
|
||||
o.Development = development
|
||||
})
|
||||
}
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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 predicate
|
||||
|
||||
import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/event"
|
||||
"sigs.k8s.io/controller-runtime/pkg/predicate"
|
||||
"sigs.k8s.io/controller-runtime/pkg/runtime/inject"
|
||||
)
|
||||
|
||||
// MapperTrigger is a trigger a Mapper can react upon.
|
||||
type MapperTrigger uint8
|
||||
|
||||
const (
|
||||
// CreateTrigger is a MapperTrigger for create events.
|
||||
CreateTrigger MapperTrigger = iota
|
||||
// UpdateOldTrigger is a MapperTrigger for update events with the old meta and object.
|
||||
UpdateOldTrigger
|
||||
// UpdateNewTrigger is a MapperTrigger for update events with the new meta and object.
|
||||
UpdateNewTrigger
|
||||
// DeleteTrigger is a MapperTrigger for delete events.
|
||||
DeleteTrigger
|
||||
// GenericTrigger is a MapperTrigger for generic events.
|
||||
GenericTrigger
|
||||
)
|
||||
|
||||
// Mapper maps any event (in form of a GenericEvent) to a boolean whether the event shall be
|
||||
// propagated or not.
|
||||
type Mapper interface {
|
||||
Map(event event.GenericEvent) bool
|
||||
}
|
||||
|
||||
// MapperFunc is a function that implements Mapper.
|
||||
type MapperFunc func(event.GenericEvent) bool
|
||||
|
||||
// Map implements Mapper.
|
||||
func (f MapperFunc) Map(event event.GenericEvent) bool {
|
||||
return f(event)
|
||||
}
|
||||
|
||||
type mapperWithTriggers struct {
|
||||
triggers map[MapperTrigger]struct{}
|
||||
mapper Mapper
|
||||
}
|
||||
|
||||
// FromMapper creates a new predicate from the given Mapper that reacts on the given MapperTriggers.
|
||||
func FromMapper(mapper Mapper, triggers ...MapperTrigger) predicate.Predicate {
|
||||
t := make(map[MapperTrigger]struct{})
|
||||
for _, trigger := range triggers {
|
||||
t[trigger] = struct{}{}
|
||||
}
|
||||
return &mapperWithTriggers{t, mapper}
|
||||
}
|
||||
|
||||
// InjectFunc implements Injector.
|
||||
func (m *mapperWithTriggers) InjectFunc(f inject.Func) error {
|
||||
return f(m.mapper)
|
||||
}
|
||||
|
||||
// Create implements Predicate.
|
||||
func (m *mapperWithTriggers) Create(e event.CreateEvent) bool {
|
||||
if _, ok := m.triggers[CreateTrigger]; ok {
|
||||
return m.mapper.Map(event.GenericEvent(e))
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Delete implements Predicate.
|
||||
func (m *mapperWithTriggers) Delete(e event.DeleteEvent) bool {
|
||||
if _, ok := m.triggers[DeleteTrigger]; ok {
|
||||
return m.mapper.Map(event.GenericEvent{Object: e.Object})
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Update implements Predicate.
|
||||
func (m *mapperWithTriggers) Update(e event.UpdateEvent) bool {
|
||||
if _, ok := m.triggers[UpdateOldTrigger]; ok {
|
||||
return m.mapper.Map(event.GenericEvent{Object: e.ObjectOld})
|
||||
}
|
||||
if _, ok := m.triggers[UpdateNewTrigger]; ok {
|
||||
return m.mapper.Map(event.GenericEvent{Object: e.ObjectNew})
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Generic implements Predicate.
|
||||
func (m *mapperWithTriggers) Generic(e event.GenericEvent) bool {
|
||||
if _, ok := m.triggers[GenericTrigger]; ok {
|
||||
return m.mapper.Map(event.GenericEvent{Object: e.Object})
|
||||
}
|
||||
return true
|
||||
}
|
||||
+298
@@ -0,0 +1,298 @@
|
||||
// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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 predicate
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
extensionscontroller "github.com/gardener/gardener/extensions/pkg/controller"
|
||||
extensionsinject "github.com/gardener/gardener/extensions/pkg/inject"
|
||||
gardencore "github.com/gardener/gardener/pkg/api/core"
|
||||
"github.com/gardener/gardener/pkg/api/extensions"
|
||||
gardencorev1beta1 "github.com/gardener/gardener/pkg/apis/core/v1beta1"
|
||||
v1beta1constants "github.com/gardener/gardener/pkg/apis/core/v1beta1/constants"
|
||||
extensionsv1alpha1 "github.com/gardener/gardener/pkg/apis/extensions/v1alpha1"
|
||||
"github.com/gardener/gardener/pkg/utils/version"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/event"
|
||||
"sigs.k8s.io/controller-runtime/pkg/log"
|
||||
"sigs.k8s.io/controller-runtime/pkg/predicate"
|
||||
)
|
||||
|
||||
// Log is the logger for predicates.
|
||||
var Log logr.Logger = log.Log
|
||||
|
||||
// EvalGeneric returns true if all predicates match for the given object.
|
||||
func EvalGeneric(obj client.Object, predicates ...predicate.Predicate) bool {
|
||||
e := event.GenericEvent{Object: obj}
|
||||
for _, p := range predicates {
|
||||
if !p.Generic(e) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
type shootNotFailedMapper struct {
|
||||
log logr.Logger
|
||||
extensionsinject.WithClient
|
||||
extensionsinject.WithContext
|
||||
extensionsinject.WithCache
|
||||
}
|
||||
|
||||
func (s *shootNotFailedMapper) Map(e event.GenericEvent) bool {
|
||||
// Wait for cache sync because of backing client cache.
|
||||
if !s.Cache.WaitForCacheSync(s.Context) {
|
||||
err := errors.New("failed to wait for caches to sync")
|
||||
s.log.Error(err, "Could not wait for Cache to sync", "predicate", "ShootNotFailed")
|
||||
return false
|
||||
}
|
||||
|
||||
cluster, err := extensionscontroller.GetCluster(s.Context, s.Client, e.Object.GetNamespace())
|
||||
if err != nil {
|
||||
s.log.Error(err, "Could not retrieve corresponding cluster")
|
||||
return false
|
||||
}
|
||||
|
||||
if extensionscontroller.IsFailed(cluster) {
|
||||
return cluster.Shoot.Generation != cluster.Shoot.Status.ObservedGeneration
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// ShootNotFailed is a predicate for failed shoots.
|
||||
func ShootNotFailed() predicate.Predicate {
|
||||
return FromMapper(&shootNotFailedMapper{log: Log.WithName("shoot-not-failed")},
|
||||
CreateTrigger, UpdateNewTrigger, DeleteTrigger, GenericTrigger)
|
||||
}
|
||||
|
||||
// HasType filters the incoming OperatingSystemConfigs for ones that have the same type
|
||||
// as the given type.
|
||||
func HasType(typeName string) predicate.Predicate {
|
||||
return FromMapper(MapperFunc(func(e event.GenericEvent) bool {
|
||||
acc, err := extensions.Accessor(e.Object)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return acc.GetExtensionSpec().GetExtensionType() == typeName
|
||||
}), CreateTrigger, UpdateNewTrigger, DeleteTrigger, GenericTrigger)
|
||||
}
|
||||
|
||||
// HasName returns a predicate that matches the given name of a resource.
|
||||
func HasName(name string) predicate.Predicate {
|
||||
return FromMapper(MapperFunc(func(e event.GenericEvent) bool {
|
||||
return e.Object.GetName() == name
|
||||
}), CreateTrigger, UpdateNewTrigger, DeleteTrigger, GenericTrigger)
|
||||
}
|
||||
|
||||
// HasOperationAnnotation is a predicate for the operation annotation.
|
||||
func HasOperationAnnotation() predicate.Predicate {
|
||||
return FromMapper(MapperFunc(func(e event.GenericEvent) bool {
|
||||
return e.Object.GetAnnotations()[v1beta1constants.GardenerOperation] == v1beta1constants.GardenerOperationReconcile ||
|
||||
e.Object.GetAnnotations()[v1beta1constants.GardenerOperation] == v1beta1constants.GardenerOperationRestore ||
|
||||
e.Object.GetAnnotations()[v1beta1constants.GardenerOperation] == v1beta1constants.GardenerOperationMigrate
|
||||
}), CreateTrigger, UpdateNewTrigger, GenericTrigger)
|
||||
}
|
||||
|
||||
// LastOperationNotSuccessful is a predicate for unsuccessful last operations **only** for creation events.
|
||||
func LastOperationNotSuccessful() predicate.Predicate {
|
||||
operationNotSucceeded := func(obj runtime.Object) bool {
|
||||
acc, err := extensions.Accessor(obj)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
lastOp := acc.GetExtensionStatus().GetLastOperation()
|
||||
return lastOp == nil ||
|
||||
lastOp.State != gardencorev1beta1.LastOperationStateSucceeded
|
||||
}
|
||||
|
||||
return predicate.Funcs{
|
||||
CreateFunc: func(event event.CreateEvent) bool {
|
||||
return operationNotSucceeded(event.Object)
|
||||
},
|
||||
UpdateFunc: func(event event.UpdateEvent) bool {
|
||||
return false
|
||||
},
|
||||
GenericFunc: func(event event.GenericEvent) bool {
|
||||
return false
|
||||
},
|
||||
DeleteFunc: func(event event.DeleteEvent) bool {
|
||||
return false
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// IsDeleting is a predicate for objects having a deletion timestamp.
|
||||
func IsDeleting() predicate.Predicate {
|
||||
return FromMapper(MapperFunc(func(e event.GenericEvent) bool {
|
||||
return e.Object.GetDeletionTimestamp() != nil
|
||||
}), CreateTrigger, UpdateNewTrigger, GenericTrigger)
|
||||
}
|
||||
|
||||
// AddTypePredicate returns a new slice which contains a type predicate and the given `predicates`.
|
||||
// if more than one extensionTypes is given all given types are or combined
|
||||
func AddTypePredicate(predicates []predicate.Predicate, extensionTypes ...string) []predicate.Predicate {
|
||||
resultPredicates := make([]predicate.Predicate, 0, len(predicates)+1)
|
||||
resultPredicates = append(resultPredicates, predicates...)
|
||||
|
||||
if len(extensionTypes) == 1 {
|
||||
resultPredicates = append(resultPredicates, HasType(extensionTypes[0]))
|
||||
return resultPredicates
|
||||
}
|
||||
|
||||
orPreds := make([]predicate.Predicate, 0, len(extensionTypes))
|
||||
for _, extensionType := range extensionTypes {
|
||||
orPreds = append(orPreds, HasType(extensionType))
|
||||
}
|
||||
|
||||
return append(resultPredicates, predicate.Or(orPreds...))
|
||||
}
|
||||
|
||||
// HasPurpose filters the incoming Controlplanes for the given spec.purpose
|
||||
func HasPurpose(purpose extensionsv1alpha1.Purpose) predicate.Predicate {
|
||||
return FromMapper(MapperFunc(func(e event.GenericEvent) bool {
|
||||
controlPlane, ok := e.Object.(*extensionsv1alpha1.ControlPlane)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
// needed because ControlPlane of type "normal" has the spec.purpose field not set
|
||||
if controlPlane.Spec.Purpose == nil && purpose == extensionsv1alpha1.Normal {
|
||||
return true
|
||||
}
|
||||
|
||||
if controlPlane.Spec.Purpose == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return *controlPlane.Spec.Purpose == purpose
|
||||
}), CreateTrigger, UpdateNewTrigger, DeleteTrigger, GenericTrigger)
|
||||
}
|
||||
|
||||
// ClusterShootProviderType is a predicate for the provider type of the shoot in the cluster resource.
|
||||
func ClusterShootProviderType(decoder runtime.Decoder, providerType string) predicate.Predicate {
|
||||
f := func(obj runtime.Object) bool {
|
||||
if obj == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
cluster, ok := obj.(*extensionsv1alpha1.Cluster)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
shoot, err := extensionscontroller.ShootFromCluster(decoder, cluster)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return shoot.Spec.Provider.Type == providerType
|
||||
}
|
||||
|
||||
return predicate.Funcs{
|
||||
CreateFunc: func(event event.CreateEvent) bool {
|
||||
return f(event.Object)
|
||||
},
|
||||
UpdateFunc: func(event event.UpdateEvent) bool {
|
||||
return f(event.ObjectNew)
|
||||
},
|
||||
GenericFunc: func(event event.GenericEvent) bool {
|
||||
return f(event.Object)
|
||||
},
|
||||
DeleteFunc: func(event event.DeleteEvent) bool {
|
||||
return f(event.Object)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// GardenCoreProviderType is a predicate for the provider type of a `gardencore.Object` implementation.
|
||||
func GardenCoreProviderType(providerType string) predicate.Predicate {
|
||||
f := func(obj runtime.Object) bool {
|
||||
if obj == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
accessor, err := gardencore.Accessor(obj)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return accessor.GetProviderType() == providerType
|
||||
}
|
||||
|
||||
return predicate.Funcs{
|
||||
CreateFunc: func(event event.CreateEvent) bool {
|
||||
return f(event.Object)
|
||||
},
|
||||
UpdateFunc: func(event event.UpdateEvent) bool {
|
||||
return f(event.ObjectNew)
|
||||
},
|
||||
GenericFunc: func(event event.GenericEvent) bool {
|
||||
return f(event.Object)
|
||||
},
|
||||
DeleteFunc: func(event event.DeleteEvent) bool {
|
||||
return f(event.Object)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// ClusterShootKubernetesVersionAtLeast is a predicate for the kubernetes version of the shoot in the cluster resource.
|
||||
func ClusterShootKubernetesVersionAtLeast(decoder runtime.Decoder, kubernetesVersion string) predicate.Predicate {
|
||||
f := func(obj runtime.Object) bool {
|
||||
if obj == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
cluster, ok := obj.(*extensionsv1alpha1.Cluster)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
shoot, err := extensionscontroller.ShootFromCluster(decoder, cluster)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
constraint, err := version.CompareVersions(shoot.Spec.Kubernetes.Version, ">=", kubernetesVersion)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return constraint
|
||||
}
|
||||
|
||||
return predicate.Funcs{
|
||||
CreateFunc: func(event event.CreateEvent) bool {
|
||||
return f(event.Object)
|
||||
},
|
||||
UpdateFunc: func(event event.UpdateEvent) bool {
|
||||
return f(event.ObjectNew)
|
||||
},
|
||||
GenericFunc: func(event event.GenericEvent) bool {
|
||||
return f(event.Object)
|
||||
},
|
||||
DeleteFunc: func(event event.DeleteEvent) bool {
|
||||
return f(event.Object)
|
||||
},
|
||||
}
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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 util
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
componentbaseconfig "k8s.io/component-base/config"
|
||||
)
|
||||
|
||||
// NewRESTConfigFromKubeconfig creates a new REST config from a given Kubeconfig and returns it.
|
||||
func NewRESTConfigFromKubeconfig(kubeconfig []byte) (*rest.Config, error) {
|
||||
configObj, err := clientcmd.Load(kubeconfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
clientConfig := clientcmd.NewDefaultClientConfig(*configObj, &clientcmd.ConfigOverrides{})
|
||||
|
||||
return createRESTConfig(clientConfig, nil)
|
||||
}
|
||||
|
||||
// ApplyClientConnectionConfigurationToRESTConfig applies the given client connection configurations to the given
|
||||
// REST config.
|
||||
func ApplyClientConnectionConfigurationToRESTConfig(clientConnection *componentbaseconfig.ClientConnectionConfiguration, rest *rest.Config) {
|
||||
if clientConnection == nil {
|
||||
return
|
||||
}
|
||||
|
||||
rest.AcceptContentTypes = clientConnection.AcceptContentTypes
|
||||
rest.ContentType = clientConnection.ContentType
|
||||
rest.Burst = int(clientConnection.Burst)
|
||||
rest.QPS = clientConnection.QPS
|
||||
}
|
||||
|
||||
// createRESTConfig creates a Config object for a rest client. If a clientConnection configuration object is passed
|
||||
// as well then the specified fields will be taken over as well.
|
||||
func createRESTConfig(clientConfig clientcmd.ClientConfig, clientConnection *componentbaseconfig.ClientConnectionConfiguration) (*rest.Config, error) {
|
||||
config, err := clientConfig.ClientConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if clientConnection != nil {
|
||||
config.Burst = int(clientConnection.Burst)
|
||||
config.QPS = clientConnection.QPS
|
||||
config.AcceptContentTypes = clientConnection.AcceptContentTypes
|
||||
config.ContentType = clientConnection.ContentType
|
||||
}
|
||||
|
||||
return config, nil
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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 util
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// Decode takes a `decoder` and decodes the provided `data` into the provided object.
|
||||
// The underlying `into` address is used to assign the decoded object.
|
||||
func Decode(decoder runtime.Decoder, data []byte, into runtime.Object) error {
|
||||
// By not providing an `into` it is necessary that the serialized `data` is configured with
|
||||
// a proper `apiVersion` and `kind` field. This also makes sure that the conversion logic to
|
||||
// the internal version is called.
|
||||
output, _, err := decoder.Decode(data, nil, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
intoType := reflect.TypeOf(into)
|
||||
|
||||
if reflect.TypeOf(output) == intoType {
|
||||
reflect.ValueOf(into).Elem().Set(reflect.ValueOf(output).Elem())
|
||||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf("is not of type %s", intoType)
|
||||
}
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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 util
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
v1beta1constants "github.com/gardener/gardener/pkg/apis/core/v1beta1/constants"
|
||||
"github.com/gardener/gardener/pkg/utils"
|
||||
"github.com/gardener/gardener/pkg/utils/secrets"
|
||||
|
||||
"github.com/Masterminds/semver"
|
||||
"github.com/pkg/errors"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/version"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
|
||||
)
|
||||
|
||||
// CAChecksumAnnotation is a resource annotation used to store the checksum of a certificate authority.
|
||||
const CAChecksumAnnotation = "checksum/ca"
|
||||
|
||||
// GetOrCreateShootKubeconfig gets or creates a Kubeconfig for a Shoot cluster which has a running control plane in the given `namespace`.
|
||||
// If the CA of an existing Kubeconfig has changed, it creates a new Kubeconfig.
|
||||
// Newly generated Kubeconfigs are applied with the given `client` to the given `namespace`.
|
||||
func GetOrCreateShootKubeconfig(ctx context.Context, c client.Client, certificateConfig secrets.CertificateSecretConfig, namespace string) (*corev1.Secret, error) {
|
||||
caSecret, ca, err := secrets.LoadCAFromSecret(ctx, c, namespace, v1beta1constants.SecretNameCACluster)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error fetching CA secret %s/%s: %v", namespace, v1beta1constants.SecretNameCACluster, err)
|
||||
}
|
||||
|
||||
var (
|
||||
secret = corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Annotations: make(map[string]string),
|
||||
Name: certificateConfig.Name,
|
||||
Namespace: namespace,
|
||||
},
|
||||
}
|
||||
key = types.NamespacedName{
|
||||
Name: certificateConfig.Name,
|
||||
Namespace: namespace,
|
||||
}
|
||||
)
|
||||
if err := c.Get(ctx, key, &secret); client.IgnoreNotFound(err) != nil {
|
||||
return nil, fmt.Errorf("error preparing kubeconfig: %v", err)
|
||||
}
|
||||
|
||||
var (
|
||||
computedChecksum = utils.ComputeChecksum(caSecret.Data)
|
||||
storedChecksum, ok = secret.Annotations[CAChecksumAnnotation]
|
||||
)
|
||||
if ok && computedChecksum == storedChecksum {
|
||||
return &secret, nil
|
||||
}
|
||||
|
||||
certificateConfig.SigningCA = ca
|
||||
certificateConfig.CertType = secrets.ClientCert
|
||||
|
||||
config := secrets.ControlPlaneSecretConfig{
|
||||
CertificateSecretConfig: &certificateConfig,
|
||||
|
||||
KubeConfigRequest: &secrets.KubeConfigRequest{
|
||||
ClusterName: namespace,
|
||||
APIServerURL: kubeAPIServerServiceDNS(namespace),
|
||||
},
|
||||
}
|
||||
|
||||
controlPlane, err := config.GenerateControlPlane()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating kubeconfig: %v", err)
|
||||
}
|
||||
|
||||
_, err = controllerutil.CreateOrUpdate(ctx, c, &secret, func() error {
|
||||
secret.Data = controlPlane.SecretData()
|
||||
if secret.Annotations == nil {
|
||||
secret.Annotations = make(map[string]string)
|
||||
}
|
||||
secret.Annotations[CAChecksumAnnotation] = computedChecksum
|
||||
return nil
|
||||
})
|
||||
|
||||
return &secret, err
|
||||
}
|
||||
|
||||
// kubeAPIServerServiceDNS returns a domain name which can be used to contact
|
||||
// the Kube-Apiserver deployment of a Shoot within the Seed cluster.
|
||||
// e.g. kube-apiserver.shoot--project--prod.svc.cluster.local.
|
||||
func kubeAPIServerServiceDNS(namespace string) string {
|
||||
return fmt.Sprintf("%s.%s", v1beta1constants.DeploymentNameKubeAPIServer, namespace)
|
||||
}
|
||||
|
||||
// VersionMajorMinor extracts and returns the major and the minor part of the given version (input must be a semantic version).
|
||||
func VersionMajorMinor(version string) (string, error) {
|
||||
v, err := semver.NewVersion(version)
|
||||
if err != nil {
|
||||
return "", errors.Wrapf(err, "Invalid version string '%s'", version)
|
||||
}
|
||||
return fmt.Sprintf("%d.%d", v.Major(), v.Minor()), nil
|
||||
}
|
||||
|
||||
// VersionInfo converts the given version string to version.Info (input must be a semantic version).
|
||||
func VersionInfo(vs string) (*version.Info, error) {
|
||||
v, err := semver.NewVersion(vs)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "Invalid version string '%s'", vs)
|
||||
}
|
||||
return &version.Info{
|
||||
Major: fmt.Sprintf("%d", v.Major()),
|
||||
Minor: fmt.Sprintf("%d", v.Minor()),
|
||||
GitVersion: fmt.Sprintf("v%d.%d.%d", v.Major(), v.Minor(), v.Patch()),
|
||||
}, nil
|
||||
}
|
||||
+130
@@ -0,0 +1,130 @@
|
||||
// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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 util
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
v1beta1constants "github.com/gardener/gardener/pkg/apis/core/v1beta1/constants"
|
||||
"github.com/gardener/gardener/pkg/chartrenderer"
|
||||
gardenerkubernetes "github.com/gardener/gardener/pkg/client/kubernetes"
|
||||
kutil "github.com/gardener/gardener/pkg/utils/kubernetes"
|
||||
"github.com/gardener/gardener/pkg/utils/secrets"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/version"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/rest"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
)
|
||||
|
||||
// ShootClients bundles together several clients for the shoot cluster.
|
||||
type ShootClients interface {
|
||||
Client() client.Client
|
||||
Clientset() kubernetes.Interface
|
||||
GardenerClientset() gardenerkubernetes.Interface
|
||||
ChartApplier() gardenerkubernetes.ChartApplier
|
||||
Version() *version.Info
|
||||
}
|
||||
|
||||
type shootClients struct {
|
||||
c client.Client
|
||||
clientset kubernetes.Interface
|
||||
gardenerClientset gardenerkubernetes.Interface
|
||||
chartApplier gardenerkubernetes.ChartApplier
|
||||
version *version.Info
|
||||
}
|
||||
|
||||
func (s *shootClients) Client() client.Client { return s.c }
|
||||
func (s *shootClients) Clientset() kubernetes.Interface { return s.clientset }
|
||||
func (s *shootClients) GardenerClientset() gardenerkubernetes.Interface { return s.gardenerClientset }
|
||||
func (s *shootClients) ChartApplier() gardenerkubernetes.ChartApplier { return s.chartApplier }
|
||||
func (s *shootClients) Version() *version.Info { return s.version }
|
||||
|
||||
// NewShootClients creates a new shoot client interface based on the given clients.
|
||||
func NewShootClients(c client.Client, clientset kubernetes.Interface, gardenerClientset gardenerkubernetes.Interface, chartApplier gardenerkubernetes.ChartApplier, version *version.Info) ShootClients {
|
||||
return &shootClients{
|
||||
c: c,
|
||||
clientset: clientset,
|
||||
gardenerClientset: gardenerClientset,
|
||||
chartApplier: chartApplier,
|
||||
version: version,
|
||||
}
|
||||
}
|
||||
|
||||
// NewClientForShoot returns the rest config and the client for the given shoot namespace.
|
||||
func NewClientForShoot(ctx context.Context, c client.Client, namespace string, opts client.Options) (*rest.Config, client.Client, error) {
|
||||
var (
|
||||
gardenerSecret = &corev1.Secret{}
|
||||
err error
|
||||
)
|
||||
|
||||
if err = c.Get(ctx, kutil.Key(namespace, v1beta1constants.SecretNameGardenerInternal), gardenerSecret); err != nil && apierrors.IsNotFound(err) {
|
||||
err = c.Get(ctx, kutil.Key(namespace, v1beta1constants.SecretNameGardener), gardenerSecret)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
shootRESTConfig, err := NewRESTConfigFromKubeconfig(gardenerSecret.Data[secrets.DataKeyKubeconfig])
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
shootClient, err := client.New(shootRESTConfig, opts)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return shootRESTConfig, shootClient, nil
|
||||
}
|
||||
|
||||
// NewClientsForShoot is a utility function that creates a new clientset and a chart applier for the shoot cluster.
|
||||
// It uses the 'gardener' secret in the given shoot namespace. It also returns the Kubernetes version of the cluster.
|
||||
func NewClientsForShoot(ctx context.Context, c client.Client, namespace string, opts client.Options) (ShootClients, error) {
|
||||
shootRESTConfig, shootClient, err := NewClientForShoot(ctx, c, namespace, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
shootClientset, err := kubernetes.NewForConfig(shootRESTConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
shootGardenerClientset, err := gardenerkubernetes.NewWithConfig(gardenerkubernetes.WithRESTConfig(shootRESTConfig), gardenerkubernetes.WithClientOptions(opts))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
shootVersion, err := shootClientset.Discovery().ServerVersion()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
shootChartApplier := shootGardenerClientset.ChartApplier()
|
||||
|
||||
return &shootClients{
|
||||
c: shootClient,
|
||||
clientset: shootClientset,
|
||||
gardenerClientset: shootGardenerClientset,
|
||||
chartApplier: shootChartApplier,
|
||||
version: shootVersion,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// NewChartRendererForShoot creates a new chartrenderer.Interface for the shoot cluster.
|
||||
func NewChartRendererForShoot(version string) (chartrenderer.Interface, error) {
|
||||
v, err := VersionInfo(version)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return chartrenderer.NewWithServerVersion(v), nil
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
repo_root_dir="$1"
|
||||
repo_name="${2:-github.com/gardener/gardener}"
|
||||
descriptor_out_file="${COMPONENT_DESCRIPTOR_PATH}"
|
||||
|
||||
echo "enriching creating component descriptor from ${BASE_DEFINITION_PATH}"
|
||||
|
||||
if [[ -f "$repo_root_dir/charts/images.yaml" ]]; then
|
||||
images="$(yaml2json < "$repo_root_dir/charts/images.yaml")"
|
||||
eval "$(jq -r ".images |
|
||||
map(select(.sourceRepository != \"$repo_name\") |
|
||||
if (.name == \"hyperkube\" or .name == \"kube-apiserver\" or .name == \"kube-controller-manager\" or .name == \"kube-scheduler\" or .name == \"kube-proxy\" or .repository == \"k8s.gcr.io/hyperkube\") then
|
||||
\"--generic-dependencies '{\\\"name\\\": \\\"\" + .name + \"\\\", \\\"version\\\": \\\"\" + .tag + \"\\\"}'\"
|
||||
elif (.repository | startswith(\"eu.gcr.io/gardener-project/gardener\")) then
|
||||
\"--component-dependencies '{\\\"name\\\": \\\"\" + .sourceRepository + \"\\\", \\\"version\\\": \\\"\" + .tag + \"\\\"}'\"
|
||||
else
|
||||
\"--container-image-dependencies '{\\\"name\\\": \\\"\" + .name + \"\\\", \\\"image_reference\\\": \\\"\" + .repository + \":\" + .tag + \"\\\", \\\"version\\\": \\\"\" + .tag + \"\\\"}'\"
|
||||
end) |
|
||||
\"${ADD_DEPENDENCIES_CMD} \\\\\n\" +
|
||||
join(\" \\\\\n\")" <<< "$images")"
|
||||
fi
|
||||
|
||||
if [[ -d "$repo_root_dir/charts/" ]]; then
|
||||
for image_tpl_path in "$repo_root_dir/charts/"*"/templates/_images.tpl"; do
|
||||
if [[ ! -f "$image_tpl_path" ]]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
outputFile=$(sed 's/{{-//' $image_tpl_path | sed 's/}}//' | sed 's/define//' | sed 's/-//' | sed 's/end//' | sed 's/"//' | sed 's/"//' |sed 's/image.//' | sed -e 's/^[ \t]*//' | awk -v RS= '{for (i=1; i<=NF; i++) printf "%s%s", $i, (i==NF?"\n":" ")}')
|
||||
echo "enriching creating component descriptor from ${image_tpl_path}"
|
||||
|
||||
while read p; do
|
||||
line="$(echo -e "$p")"
|
||||
IFS=' ' read -r -a array <<< "$line"
|
||||
IFS=': ' read -r -a imageAndTag <<< ${array[1]}
|
||||
|
||||
NAME=${array[0]}
|
||||
REPOSITORY=${imageAndTag[0]}
|
||||
TAG=${imageAndTag[1]}
|
||||
|
||||
gardener="eu.gcr.io/gardener-project/gardener"
|
||||
if [[ "$NAME" == "hyperkube" ]]; then
|
||||
${ADD_DEPENDENCIES_CMD} --generic-dependencies "{\"name\": \"$NAME\", \"version\": \"$TAG\"}"
|
||||
elif [[ $REPOSITORY =~ "eu.gcr.io/gardener-project/gardener"* ]]; then
|
||||
${ADD_DEPENDENCIES_CMD} --generic-dependencies "{\"name\": \"$NAME\", \"version\": \"$TAG\"}"
|
||||
else
|
||||
${ADD_DEPENDENCIES_CMD} --container-image-dependencies "{\"name\": \"${NAME}\", \"image_reference\": \"${REPOSITORY}:${TAG}\", \"version\": \"$TAG\"}"
|
||||
fi
|
||||
done < <(echo "$outputFile")
|
||||
done
|
||||
fi
|
||||
|
||||
cp "${BASE_DEFINITION_PATH}" "${descriptor_out_file}"
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// Copyright (c) 2020 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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.
|
||||
|
||||
// This package imports CI related scripts - it is to force `go mod` to see them as dependencies.
|
||||
package ci
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
#!/usr/bin/env sh
|
||||
#
|
||||
# Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
#
|
||||
# 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.
|
||||
|
||||
set -e
|
||||
|
||||
repo_root_dir="$1"
|
||||
repo_base="$2"
|
||||
repo_name="$3"
|
||||
|
||||
apk update
|
||||
apk add --no-cache \
|
||||
ca-certificates \
|
||||
make \
|
||||
bash \
|
||||
go \
|
||||
git \
|
||||
musl-dev \
|
||||
curl \
|
||||
openssl \
|
||||
tar \
|
||||
gzip \
|
||||
gcc \
|
||||
sed
|
||||
|
||||
GOLANG_VERSION="$(sed -rn 's/FROM (eu\.gcr\.io\/gardener-project\/3rd\/golang|golang):([^ ]+).*/\2/p' < "$repo_root_dir/Dockerfile")"
|
||||
|
||||
export \
|
||||
GOROOT="$(go env GOROOT)" \
|
||||
GOOS="$(go env GOOS)" \
|
||||
GOARCH="$(go env GOARCH)" \
|
||||
GOHOSTOS="$(go env GOHOSTOS)" \
|
||||
GOHOSTARCH="$(go env GOHOSTARCH)"
|
||||
|
||||
echo "Downloading go $GOLANG_VERSION"
|
||||
wget -q -O - "https://golang.org/dl/go$GOLANG_VERSION.src.tar.gz" | tar zx -C /usr/local
|
||||
cd /usr/local/go/src
|
||||
echo "Executing make on go $GOLANG_VERSION"
|
||||
./make.bash > /dev/null 2>&1
|
||||
|
||||
export GOPATH="$(mktemp -d)"
|
||||
export GOBIN="$GOPATH/bin"
|
||||
export PATH="$GOBIN:$PATH"
|
||||
|
||||
REPO_BASE="$GOPATH/src/$repo_base"
|
||||
mkdir -p "$REPO_BASE"
|
||||
REPO_PATH="$REPO_BASE/$repo_name"
|
||||
cp -R "$repo_root_dir" "$REPO_PATH"
|
||||
|
||||
current_dir="$(pwd)"
|
||||
cd "$REPO_PATH"
|
||||
make install-requirements
|
||||
cd "$current_dir"
|
||||
|
||||
echo "$EFFECTIVE_VERSION" > "$REPO_PATH/VERSION"
|
||||
cur_dir="$(pwd)"
|
||||
cd "$REPO_PATH"
|
||||
if ! make generate; then
|
||||
cd "$cur_dir"
|
||||
exit 1
|
||||
fi
|
||||
cd "$cur_dir"
|
||||
cp -RT "$REPO_PATH/" "$repo_root_dir/"
|
||||
|
||||
+125
@@ -0,0 +1,125 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright (c) 2020 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
#
|
||||
# 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.
|
||||
|
||||
import pathlib
|
||||
import yaml
|
||||
|
||||
import util
|
||||
import product.model
|
||||
|
||||
dependency_type = util.check_env('DEPENDENCY_TYPE')
|
||||
if not dependency_type == 'component':
|
||||
util.fail('don\'t know how to upgrade dependency type: ' + str(dependency_type))
|
||||
|
||||
component_reference = product.model.ComponentReference.create(
|
||||
name=util.check_env('DEPENDENCY_NAME'),
|
||||
version=util.check_env('DEPENDENCY_VERSION'),
|
||||
)
|
||||
|
||||
images_file = pathlib.Path(
|
||||
util.check_env('REPO_DIR'),
|
||||
'charts',
|
||||
'images.yaml',
|
||||
)
|
||||
|
||||
class ImagesParser(object):
|
||||
'''
|
||||
a naive YAML-parser crafted for the special case of processing
|
||||
gardener's images.yaml file; crafted that way to preserve comments/empty lines
|
||||
'''
|
||||
def __init__(
|
||||
self,
|
||||
images_file,
|
||||
names,
|
||||
target_version,
|
||||
):
|
||||
self.images_file = images_file
|
||||
self.lines = images_file.read_text().split('\n')
|
||||
self.names = names
|
||||
self.target_version = target_version
|
||||
self._line_idx = 0
|
||||
|
||||
def _line(self):
|
||||
return self.lines[self._line_idx]
|
||||
|
||||
def _next_line(self):
|
||||
self._line_idx += 1
|
||||
return self._line()
|
||||
|
||||
def _skip_to_next_entry(self, names):
|
||||
while not self._line().startswith('-'):
|
||||
self._next_line()
|
||||
name = self._line().strip().split(':')[-1].strip()
|
||||
|
||||
if name not in names:
|
||||
self._next_line()
|
||||
return self._skip_to_next_entry(names)
|
||||
|
||||
# found one of the entries:
|
||||
return name
|
||||
|
||||
def _skip_to_next_tag(self):
|
||||
self._next_line()
|
||||
while not self._line().startswith('-'):
|
||||
if self._line().strip().startswith('tag:'):
|
||||
return
|
||||
self._next_line()
|
||||
raise RuntimeError('did not find tag attribute')
|
||||
|
||||
def set_versions(self):
|
||||
while self.names:
|
||||
try:
|
||||
name = self._skip_to_next_entry(self.names)
|
||||
except IndexError:
|
||||
print(str(self.names))
|
||||
util.fail('don\'t know how to update ' + str(self.names))
|
||||
self.names.remove(name)
|
||||
self._skip_to_next_tag()
|
||||
tag_line = self._line()
|
||||
indent = len(tag_line) - len(tag_line.lstrip())
|
||||
patched_line = ' ' * indent + 'tag: "{version}"'.format(version=self.target_version)
|
||||
self.lines[self._line_idx] = patched_line
|
||||
|
||||
def write_updated_file(self):
|
||||
self.images_file.write_text(
|
||||
'\n'.join(self.lines)
|
||||
)
|
||||
|
||||
|
||||
# handle special cases
|
||||
name = component_reference.github_repo()
|
||||
if name == 'autoscaler':
|
||||
names = ['cluster-autoscaler']
|
||||
elif name == 'vpn':
|
||||
names = ['vpn-seed', 'vpn-shoot']
|
||||
elif name == 'external-dns-management':
|
||||
names = ['dns-controller-manager']
|
||||
elif name == 'logging':
|
||||
names = ['fluent-bit-plugin-installer']
|
||||
elif name == 'etcd-custom-image':
|
||||
names = ['etcd']
|
||||
else:
|
||||
names = [name]
|
||||
|
||||
|
||||
parser = ImagesParser(
|
||||
images_file=images_file,
|
||||
names=names,
|
||||
target_version=str(component_reference.version()),
|
||||
)
|
||||
|
||||
parser.set_versions()
|
||||
parser.write_updated_file()
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
Copyright (c) YEAR SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
|
||||
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.
|
||||
*/
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
{{ define "members" }}
|
||||
|
||||
{{ range .Members }}
|
||||
{{ if not (hiddenMember .)}}
|
||||
<tr>
|
||||
<td>
|
||||
<code>{{ fieldName . }}</code></br>
|
||||
<em>
|
||||
{{ if linkForType .Type }}
|
||||
<a href="{{ linkForType .Type}}">
|
||||
{{ typeDisplayName .Type }}
|
||||
</a>
|
||||
{{ else }}
|
||||
{{ typeDisplayName .Type }}
|
||||
{{ end }}
|
||||
</em>
|
||||
</td>
|
||||
<td>
|
||||
{{ if fieldEmbedded . }}
|
||||
<p>
|
||||
(Members of <code>{{ fieldName . }}</code> are embedded into this type.)
|
||||
</p>
|
||||
{{ end}}
|
||||
|
||||
{{ if isOptionalMember .}}
|
||||
<em>(Optional)</em>
|
||||
{{ end }}
|
||||
|
||||
{{ safe (renderComments .CommentLines) }}
|
||||
|
||||
{{ if and (eq (.Type.Name.Name) "ObjectMeta") }}
|
||||
Refer to the Kubernetes API documentation for the fields of the
|
||||
<code>metadata</code> field.
|
||||
{{ end }}
|
||||
|
||||
{{ if or (eq (fieldName .) "spec") }}
|
||||
<br/>
|
||||
<br/>
|
||||
<table>
|
||||
{{ template "members" .Type }}
|
||||
</table>
|
||||
{{ end }}
|
||||
</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
{{ end }}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
{{ define "packages" }}
|
||||
|
||||
{{ with .packages}}
|
||||
<p>Packages:</p>
|
||||
<ul>
|
||||
{{ range . }}
|
||||
<li>
|
||||
<a href="#{{- packageAnchorID . -}}">{{ packageDisplayName . }}</a>
|
||||
</li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
{{ end}}
|
||||
|
||||
{{ range .packages }}
|
||||
<h2 id="{{- packageAnchorID . -}}">
|
||||
{{- packageDisplayName . -}}
|
||||
</h2>
|
||||
|
||||
{{ with (index .GoPackages 0 )}}
|
||||
{{ with .DocComments }}
|
||||
<p>
|
||||
{{ safe (renderComments .) }}
|
||||
</p>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
Resource Types:
|
||||
<ul>
|
||||
{{- range (visibleTypes (sortedTypes .Types)) -}}
|
||||
{{ if isExportedType . -}}
|
||||
<li>
|
||||
<a href="{{ linkForType . }}">{{ typeDisplayName . }}</a>
|
||||
</li>
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
</ul>
|
||||
|
||||
{{ range (visibleTypes (sortedTypes .Types))}}
|
||||
{{ template "type" . }}
|
||||
{{ end }}
|
||||
<hr/>
|
||||
{{ end }}
|
||||
|
||||
<p><em>
|
||||
Generated with <a href="https://github.com/ahmetb/gen-crd-api-reference-docs">gen-crd-api-reference-docs</a>
|
||||
</em></p>
|
||||
|
||||
{{ end }}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
// +build tools
|
||||
|
||||
// Copyright (c) 2020 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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.
|
||||
|
||||
// This package imports things required by build scripts, to force `go mod` to see them as dependencies
|
||||
package template
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
{{ define "type" }}
|
||||
|
||||
<h3 id="{{ anchorIDForType . }}">
|
||||
{{- .Name.Name }}
|
||||
{{ if eq .Kind "Alias" }}(<code>{{.Underlying}}</code> alias)</p>{{ end -}}
|
||||
</h3>
|
||||
{{ with (typeReferences .) }}
|
||||
<p>
|
||||
(<em>Appears on:</em>
|
||||
{{- $prev := "" -}}
|
||||
{{- range . -}}
|
||||
{{- if $prev -}}, {{ end -}}
|
||||
{{ $prev = . }}
|
||||
<a href="{{ linkForType . }}">{{ typeDisplayName . }}</a>
|
||||
{{- end -}}
|
||||
)
|
||||
</p>
|
||||
{{ end }}
|
||||
|
||||
|
||||
<p>
|
||||
{{ safe (renderComments .CommentLines) }}
|
||||
</p>
|
||||
|
||||
{{ if .Members }}
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Field</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{ if isExportedType . }}
|
||||
<tr>
|
||||
<td>
|
||||
<code>apiVersion</code></br>
|
||||
string</td>
|
||||
<td>
|
||||
<code>
|
||||
{{apiGroup .}}
|
||||
</code>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>kind</code></br>
|
||||
string
|
||||
</td>
|
||||
<td><code>{{.Name.Name}}</code></td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
{{ template "members" .}}
|
||||
</tbody>
|
||||
</table>
|
||||
{{ end }}
|
||||
|
||||
{{ end }}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
#
|
||||
# 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.
|
||||
|
||||
set -e
|
||||
|
||||
echo "> Check Helm charts"
|
||||
|
||||
if [[ -d "$1" ]]; then
|
||||
echo "Checking for chart symlink errors"
|
||||
BROKEN_SYMLINKS=$(find -L $1 -type l)
|
||||
if [[ "$BROKEN_SYMLINKS" ]]; then
|
||||
echo "Found broken symlinks:"
|
||||
echo "$BROKEN_SYMLINKS"
|
||||
exit 1
|
||||
fi
|
||||
echo "Checking whether all charts can be rendered"
|
||||
for chart_dir in $(find charts -type d -exec test -f '{}'/Chart.yaml \; -print -prune | sort); do
|
||||
[ -f "$chart_dir/values-test.yaml" ] && values_files="-f $chart_dir/values-test.yaml" || unset values_files
|
||||
helm template $values_files "$chart_dir" 1> /dev/null
|
||||
done
|
||||
fi
|
||||
|
||||
echo "All checks successful"
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
#
|
||||
# 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.
|
||||
|
||||
set -e
|
||||
|
||||
echo "> Generate / Vendor Check"
|
||||
|
||||
makefile="$1/Makefile"
|
||||
check_branch="__check"
|
||||
initialized_git=false
|
||||
stashed=false
|
||||
checked_out=false
|
||||
generated=false
|
||||
vendored=false
|
||||
|
||||
function delete-check-branch {
|
||||
git rev-parse --verify "$check_branch" &>/dev/null && git branch -q -D "$check_branch" || :
|
||||
}
|
||||
|
||||
function cleanup {
|
||||
if [[ "$generated" == true ]] || [[ "$vendored" == true ]]; then
|
||||
if ! clean_err="$(make -f "$makefile" clean && git reset --hard -q && git clean -qdf)"; then
|
||||
echo "Could not clean: $clean_err"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "$checked_out" == true ]]; then
|
||||
if ! checkout_err="$(git checkout -q -)"; then
|
||||
echo "Could not checkout to previous branch: $checkout_err"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "$stashed" == true ]]; then
|
||||
if ! stash_err="$(git stash pop -q)"; then
|
||||
echo "Could not pop stash: $stash_err"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "$initialized_git" == true ]]; then
|
||||
if ! rm_err="$(rm -rf .git)"; then
|
||||
echo "Could not delete git directory: $rm_err"
|
||||
fi
|
||||
fi
|
||||
|
||||
delete-check-branch
|
||||
}
|
||||
|
||||
trap cleanup EXIT SIGINT SIGTERM
|
||||
|
||||
if which git &>/dev/null; then
|
||||
if ! git rev-parse --git-dir &>/dev/null; then
|
||||
initialized_git=true
|
||||
git init -q
|
||||
git add --all
|
||||
git config --global user.name 'Gardener'
|
||||
git config --global user.email 'gardener@cloud'
|
||||
git commit -q --allow-empty -m 'initial commit'
|
||||
fi
|
||||
|
||||
if [[ "$(git rev-parse --abbrev-ref HEAD)" == "$check_branch" ]]; then
|
||||
echo "Already on check branch, aborting"
|
||||
exit 1
|
||||
fi
|
||||
delete-check-branch
|
||||
|
||||
if [[ "$(git status -s)" != "" ]]; then
|
||||
stashed=true
|
||||
git stash --include-untracked -q
|
||||
git stash apply -q &>/dev/null
|
||||
fi
|
||||
|
||||
checked_out=true
|
||||
git checkout -q -b "$check_branch"
|
||||
git add --all
|
||||
git commit -q --allow-empty -m 'checkpoint'
|
||||
|
||||
old_status="$(git status -s)"
|
||||
if ! out=$(make -f "$makefile" clean 2>&1); then
|
||||
echo "Error during calling make clean: $out"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ">> make generate"
|
||||
generated=true
|
||||
if ! out=$(make -f "$makefile" generate 2>&1); then
|
||||
echo "Error during calling make generate: $out"
|
||||
exit 1
|
||||
fi
|
||||
new_status="$(git status -s)"
|
||||
|
||||
if [[ "$old_status" != "$new_status" ]]; then
|
||||
echo "make generate needs to be run:"
|
||||
echo "$new_status"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ">> make revendor"
|
||||
vendored=true
|
||||
if ! out=$(make -f "$makefile" revendor 2>&1); then
|
||||
echo "Error during calling make revendor: $out"
|
||||
exit 1
|
||||
fi
|
||||
new_status="$(git status -s)"
|
||||
|
||||
if [[ "$old_status" != "$new_status" ]]; then
|
||||
echo "make revendor needs to be run:"
|
||||
echo "$new_status"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "No git detected, cannot run vendor check"
|
||||
fi
|
||||
exit 0
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
#
|
||||
# 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.
|
||||
|
||||
set -e
|
||||
|
||||
GOLANGCI_LINT_CONFIG_FILE=""
|
||||
|
||||
for arg in "$@"; do
|
||||
case $arg in
|
||||
--golangci-lint-config=*)
|
||||
GOLANGCI_LINT_CONFIG_FILE="-c ${arg#*=}"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
echo "> Check"
|
||||
|
||||
echo "Executing golangci-lint"
|
||||
golangci-lint run $GOLANGCI_LINT_CONFIG_FILE --timeout 10m $@
|
||||
|
||||
echo "Executing go vet"
|
||||
go vet -mod=vendor $@
|
||||
|
||||
echo "Executing gofmt/goimports"
|
||||
folders=()
|
||||
for f in $@; do
|
||||
folders+=( "$(echo $f | sed 's/\.\/\(.*\)\/\.\.\./\1/')" )
|
||||
done
|
||||
unformatted_files="$(goimports -l ${folders[*]})"
|
||||
if [[ "$unformatted_files" ]]; then
|
||||
echo "Unformatted files detected:"
|
||||
echo "$unformatted_files"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "All checks successful"
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
#
|
||||
# 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.
|
||||
|
||||
set -e
|
||||
|
||||
echo "> Clean"
|
||||
|
||||
for source_tree in $@; do
|
||||
find "$(dirname "$source_tree")" -type f -name "zz_*.go" -exec rm '{}' \;
|
||||
grep -lr --include="*.go" "//go:generate packr2" . | xargs -I {} packr2 clean "{}/.."
|
||||
done
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
#
|
||||
# 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.
|
||||
|
||||
set -e
|
||||
|
||||
echo "> Format"
|
||||
|
||||
goimports -l -w $@
|
||||
Generated
Vendored
Executable
+105
@@ -0,0 +1,105 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
#
|
||||
# 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.
|
||||
|
||||
set -e
|
||||
set -o pipefail
|
||||
|
||||
function usage {
|
||||
cat <<EOM
|
||||
Usage:
|
||||
generate-controller-registration <name> <chart-dir> <dest> <kind-and-type> [kinds-and-types ...]
|
||||
|
||||
<name> Name of the controller registration to generate.
|
||||
<chart-dir> Location of the chart directory.
|
||||
<version-file> Location of the VERSION file.
|
||||
<dest> The destination file to write the registration YAML to.
|
||||
<kind-and-type> A tuple of kind and type of the controller registration to generate.
|
||||
Separated by ':'.
|
||||
Example: OperatingSystemConfig:foobar
|
||||
<kinds-and-types> Further tuples of kind and type of the controller registration to generate.
|
||||
Separated by ':'.
|
||||
EOM
|
||||
exit 0
|
||||
}
|
||||
|
||||
if [ "$1" == "--optional" ]; then
|
||||
shift
|
||||
MODE=$'\n globallyEnabled: false'
|
||||
fi
|
||||
NAME="$1"
|
||||
CHART_DIR="$2"
|
||||
VERSION_FILE="$3"
|
||||
DEST="$4"
|
||||
KIND_AND_TYPE="$5"
|
||||
|
||||
VERSION="$(cat "$VERSION_FILE")"
|
||||
|
||||
( [[ -z "$NAME" ]] || [[ -z "$CHART_DIR" ]] || [[ -z "$DEST" ]] || [[ -z "$KIND_AND_TYPE" ]]) && usage
|
||||
|
||||
KINDS_AND_TYPES=("$KIND_AND_TYPE" "${@:6}")
|
||||
|
||||
# The following code is to make `helm package` idempotent: Usually, everytime `helm package` is invoked,
|
||||
# it produces a different `.tgz` due to modification timestamps and some special shasums of gzip. We
|
||||
# resolve this by unarchiving the `.tgz`, compressing it again with a constant `mtime` and no gzip
|
||||
# checksums.
|
||||
temp_dir="$(mktemp -d)"
|
||||
temp_helm_home="$(mktemp -d)"
|
||||
temp_extract_dir="$(mktemp -d)"
|
||||
function cleanup {
|
||||
rm -rf "$temp_dir"
|
||||
rm -rf "$temp_helm_home"
|
||||
rm -rf "$temp_extract_dir"
|
||||
}
|
||||
trap cleanup EXIT ERR INT TERM
|
||||
|
||||
export HELM_HOME="$temp_helm_home"
|
||||
[ "$(helm version --client --template "{{.Version}}" | head -c2 | tail -c1)" = "3" ] || helm init --client-only > /dev/null 2>&1
|
||||
helm package "$CHART_DIR" --version "$VERSION" --app-version "$VERSION" --destination "$temp_dir" > /dev/null
|
||||
gtar -xzm -C "$temp_extract_dir" -f "$temp_dir"/*
|
||||
chart="$(gtar --sort=name -c --owner=root:0 --group=root:0 --mtime='UTC 2019-01-01' -C "$temp_extract_dir" "$(basename "$temp_extract_dir"/*)" | gzip -n | base64 | tr -d '\n')"
|
||||
|
||||
mkdir -p "$(dirname "$DEST")"
|
||||
|
||||
cat <<EOM > "$DEST"
|
||||
---
|
||||
apiVersion: core.gardener.cloud/v1beta1
|
||||
kind: ControllerRegistration
|
||||
metadata:
|
||||
name: $NAME
|
||||
spec:
|
||||
resources:
|
||||
EOM
|
||||
|
||||
for kind_and_type in "${KINDS_AND_TYPES[@]}"; do
|
||||
KIND="$(echo "$kind_and_type" | cut -d ':' -f 1)"
|
||||
TYPE="$(echo "$kind_and_type" | cut -d ':' -f 2)"
|
||||
cat <<EOM >> "$DEST"
|
||||
- kind: $KIND
|
||||
type: $TYPE$MODE
|
||||
EOM
|
||||
done
|
||||
|
||||
cat <<EOM >> "$DEST"
|
||||
deployment:
|
||||
type: helm
|
||||
providerConfig:
|
||||
chart: $chart
|
||||
values:
|
||||
image:
|
||||
tag: $VERSION
|
||||
EOM
|
||||
|
||||
echo "Successfully generated controller registration at $DEST"
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
#
|
||||
# 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.
|
||||
|
||||
set -e
|
||||
|
||||
echo "> Generate"
|
||||
|
||||
GO111MODULE=on go generate -mod=vendor $@
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
#!/bin/bash -e
|
||||
#
|
||||
# Copyright (c) 2018 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
#
|
||||
# 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.
|
||||
|
||||
SOURCE_REPOSITORY="${1:-github.com/gardener/gardener}"
|
||||
VERSION_PATH="${2:-$(dirname $0)/../VERSION}"
|
||||
VERSION_VERSIONFILE="$(cat "$VERSION_PATH")"
|
||||
VERSION="${EFFECTIVE_VERSION:-$VERSION_VERSIONFILE}"
|
||||
|
||||
# .dockerignore ignores all files unrelevant for build (e.g. docs) to only copy relevant source files to the build
|
||||
# container. Hence, git will always detect a dirty work tree when building in a container (many deleted files).
|
||||
# This command filters out all deleted files that are ignored by .dockerignore to only detect changes to relevant files
|
||||
# as a dirty work tree.
|
||||
# Additionally, it filters out changes to the `VERSION` file, as this is currently the only way to inject the
|
||||
# version-to-build in our pipelines (see https://github.com/gardener/cc-utils/issues/431).
|
||||
TREE_STATE="$([ -z "$(git status --porcelain 2>/dev/null | grep -vf <(git ls-files --deleted --ignored --exclude-from=.dockerignore) -e 'VERSION')" ] && echo clean || echo dirty)"
|
||||
|
||||
echo "-X $SOURCE_REPOSITORY/pkg/version.gitVersion=$VERSION
|
||||
-X $SOURCE_REPOSITORY/pkg/version.gitTreeState=$TREE_STATE
|
||||
-X $SOURCE_REPOSITORY/pkg/version.gitCommit=$(git rev-parse --verify HEAD)
|
||||
-X $SOURCE_REPOSITORY/pkg/version.buildDate=$(date '+%Y-%m-%dT%H:%M:%S%z' | sed 's/\([0-9][0-9]\)$/:\1/g')"
|
||||
+306
@@ -0,0 +1,306 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Copyright (c) 2020 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
#
|
||||
# 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.
|
||||
|
||||
checkPrereqs() {
|
||||
command -v host > /dev/null || echo "please install host command for lookup"
|
||||
command -v inlets > /dev/null || echo "please install the inlets command. For mac, simply use \`brew install inlets\`, for linux \`curl -sLS https://get.inlets.dev | sudo sh\`"
|
||||
}
|
||||
|
||||
createOrUpdateWebhookSVC(){
|
||||
namespace=${1:-}
|
||||
[[ -z $namespace ]] && echo "Please specify extension namespace!" && exit 1
|
||||
|
||||
providerName=${2:-}
|
||||
[[ -z $providerName ]] && echo "Please specify the provider name (aws,gcp,azure,..etc.)!" && exit 1
|
||||
|
||||
tmpService=$(mktemp)
|
||||
kubectl get svc gardener-extension-provider-$providerName -o yaml > $tmpService
|
||||
|
||||
cat <<EOF | kubectl apply -f -
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
app: gardener-extension-provider-$providerName
|
||||
app.kubernetes.io/instance: provider-$providerName
|
||||
app.kubernetes.io/name: gardener-extension-provider-$providerName
|
||||
name: gardener-extension-provider-$providerName
|
||||
namespace: $namespace
|
||||
spec:
|
||||
ports:
|
||||
- port: 443
|
||||
protocol: TCP
|
||||
targetPort: 9443
|
||||
selector:
|
||||
app: inlets-server
|
||||
app.kubernetes.io/instance: provider-$providerName
|
||||
app.kubernetes.io/name: gardener-extension-provider-$providerName
|
||||
type: ClusterIP
|
||||
EOF
|
||||
}
|
||||
|
||||
|
||||
createInletsLB(){
|
||||
namespace=${1:-}
|
||||
[[ -z $namespace ]] && echo "Please specify extension namespace!" && exit 1
|
||||
|
||||
cat <<EOF | kubectl apply -f -
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
app: inlets-lb
|
||||
name: inlets-lb
|
||||
namespace: $namespace
|
||||
spec:
|
||||
externalTrafficPolicy: Cluster
|
||||
ports:
|
||||
- name: 8000-8080
|
||||
port: 8000
|
||||
protocol: TCP
|
||||
targetPort: 8080
|
||||
selector:
|
||||
app: inlets-server
|
||||
type: LoadBalancer
|
||||
EOF
|
||||
}
|
||||
|
||||
waitForInletsLBToBeReady(){
|
||||
namespace=${1:-}
|
||||
[[ -z $namespace ]] && echo "Please specify extension namespace!" && exit 1
|
||||
|
||||
providerName=${2:-}
|
||||
[[ -z $providerName ]] && echo "Please specify the provider name (aws,gcp,azure,..etc.)!" && exit 1
|
||||
|
||||
case $providerName in
|
||||
aws*)
|
||||
until host $(kubectl -n $namespace get svc inlets-lb -o go-template="{{ index (index .status.loadBalancer.ingress 0).hostname }}") 2>&1 > /dev/null
|
||||
do
|
||||
sleep 2s
|
||||
done
|
||||
echo $(kubectl -n $namespace get svc inlets-lb -o go-template="{{ index (index .status.loadBalancer.ingress 0).hostname }}")
|
||||
;;
|
||||
*)
|
||||
until host $(kubectl -n $namespace get svc inlets-lb -o go-template="{{ index (index .status.loadBalancer.ingress 0).ip }}") 2>&1 > /dev/null
|
||||
do
|
||||
sleep 2s
|
||||
done
|
||||
echo $(kubectl -n $namespace get svc inlets-lb -o go-template="{{ index (index .status.loadBalancer.ingress 0).ip }}") ;;
|
||||
esac
|
||||
}
|
||||
|
||||
createServerPod(){
|
||||
namespace=${1:-}
|
||||
[[ -z $namespace ]] && echo "Please specify extension namespace!" && exit 1
|
||||
|
||||
providerName=${2:-}
|
||||
[[ -z $providerName ]] && echo "Please specify the provider name (aws,gcp,azure,..etc.)!" && exit 1
|
||||
|
||||
cat <<EOF | kubectl apply -f -
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
labels:
|
||||
app: inlets-server
|
||||
app.kubernetes.io/instance: provider-$providerName
|
||||
app.kubernetes.io/name: gardener-extension-provider-$providerName
|
||||
networking.gardener.cloud/to-dns: allowed
|
||||
networking.gardener.cloud/to-public-networks: allowed
|
||||
name: inlets-server
|
||||
namespace: $namespace
|
||||
spec:
|
||||
containers:
|
||||
- args:
|
||||
- "server"
|
||||
- "-p"
|
||||
- "8080"
|
||||
- "-t"
|
||||
- "21d809ed61915c9177fbceeaa87e307e766be5f2"
|
||||
image: inlets/inlets:2.6.3
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: inlets-server
|
||||
resources:
|
||||
limits:
|
||||
cpu: 50m
|
||||
memory: 128Mi
|
||||
requests:
|
||||
cpu: 20m
|
||||
memory: 64Mi
|
||||
- args:
|
||||
- "server"
|
||||
- "--target"
|
||||
- "127.0.0.1:8080"
|
||||
- "--listen"
|
||||
- "0.0.0.0:9443"
|
||||
- "--cacert"
|
||||
- "/etc/tls/ca.crt"
|
||||
- "--cert"
|
||||
- "/etc/tls/tls.crt"
|
||||
- "--key"
|
||||
- "/etc/tls/tls.key"
|
||||
- "--disable-authentication"
|
||||
image: "squareup/ghostunnel:v1.5.2"
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: ghost-server
|
||||
volumeMounts:
|
||||
- name: inlets-tls
|
||||
mountPath: "/etc/tls"
|
||||
readOnly: true
|
||||
resources:
|
||||
limits:
|
||||
cpu: 50m
|
||||
memory: 128Mi
|
||||
requests:
|
||||
cpu: 20m
|
||||
memory: 64Mi
|
||||
- args:
|
||||
- "sleep"
|
||||
- "8000s"
|
||||
image: busybox
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: debug
|
||||
resources:
|
||||
limits:
|
||||
cpu: 50m
|
||||
memory: 128Mi
|
||||
requests:
|
||||
cpu: 20m
|
||||
memory: 64Mi
|
||||
volumes:
|
||||
- name: inlets-tls
|
||||
secret:
|
||||
secretName: gardener-extension-webhook-cert
|
||||
dnsPolicy: ClusterFirst
|
||||
enableServiceLinks: true
|
||||
restartPolicy: Always
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
waitForInletsPodToBeReady(){
|
||||
namespace=${1:-}
|
||||
[[ -z $namespace ]] && echo "Please specify extension namespace!" && exit 1
|
||||
|
||||
until test "$(kubectl -n $namespace get pods inlets-server --no-headers | awk '{print $2}')" = "3/3"
|
||||
do
|
||||
sleep 2s
|
||||
done
|
||||
}
|
||||
|
||||
cleanUP() {
|
||||
namespace=${1:-}
|
||||
[[ -z $namespace ]] && echo "Please specify the extension namespace!" && exit 1
|
||||
|
||||
echo "cleaning up local-dev setup.."
|
||||
|
||||
echo "Deleting inlets service..."
|
||||
kubectl -n $namespace delete svc/inlets-lb
|
||||
|
||||
echo "Deleting the inlets pod..."
|
||||
kubectl -n $namespace delete pod/inlets-server
|
||||
|
||||
echo "Re-applying old service values..."
|
||||
kubectl apply -f $tmpService
|
||||
|
||||
kill -9 $(pgrep inlets) 2>/dev/null
|
||||
exit 0
|
||||
}
|
||||
|
||||
usage(){
|
||||
echo "==================================================================DISCLAIMER============================================================================"
|
||||
echo "This scripts needs to be run against the KUBECONFIG of a seed cluster, please set your KUBECONFIG accordingly"
|
||||
echo "You also need to set the \`ignoreResources\` variable in your extension chart to \`true\`, generate and apply the corresponding controller-installation"
|
||||
echo "========================================================================================================================================================"
|
||||
|
||||
echo ""
|
||||
|
||||
echo "===================================PRE-REQs========================================="
|
||||
echo "\`host\` commands for DNS"
|
||||
echo "\`inlets\` command. For mac, simply use \`brew install inlets\`, for linux \`curl -sLS https://get.inlets.dev | sudo sh\`"
|
||||
echo "===================================================================================="
|
||||
|
||||
echo ""
|
||||
|
||||
echo "========================================================USAGE======================================================================"
|
||||
echo "> ./hack/hook-me.sh <provider e.g., aws> <extension namespace e.g. extension-provider-aws-fpr6w> <webhookserver port e.g., 8443>"
|
||||
echo "> \`make EXTENSION_NAMESPACE=<extension namespace e.g. extension-provider-aws-fpr6w> WEBHOOK_CONFIG_MODE=service start\`"
|
||||
echo "=================================================================================================================================="
|
||||
|
||||
echo ""
|
||||
|
||||
echo "===================================CLEAN UP COMMANDS========================================="
|
||||
echo "> kubectl -n $namespace delete svc/inlets-lb"
|
||||
echo "> kubectl -n $namespace delete pod/inlets-server"
|
||||
echo "============================================================================================="
|
||||
|
||||
exit 0
|
||||
}
|
||||
if [[ "${BASH_SOURCE[0]}" = "$0" ]]; then
|
||||
|
||||
if [ "$1" == "-h" ] ; then
|
||||
usage
|
||||
fi
|
||||
|
||||
providerName=${1:-}
|
||||
[[ -z $providerName ]] && echo "Please specify the provider name (aws,gcp,azure,..etc.)!" && exit 1
|
||||
|
||||
namespace=${2:-}
|
||||
[[ -z $namespace ]] && echo "Please specify the extension namespace!" && exit 1
|
||||
|
||||
webhookServerPort=${3:-}
|
||||
[[ -z $webhookServerPort ]] && echo "Please specify webhook server port" && exit 1
|
||||
|
||||
|
||||
trap 'cleanUP $namespace' SIGINT SIGTERM
|
||||
|
||||
while true; do
|
||||
read -p "[STEP 0] Have you already set the \`ignoreResources\` chart value to \`true\` for your extension controller-registration?" yn
|
||||
case $yn in
|
||||
[Yy]* )
|
||||
echo "[STEP 1] Checking Pre-reqs!"
|
||||
checkPrereqs
|
||||
|
||||
echo "[STEP 2] Creating Inlets LB Service..!"
|
||||
createInletsLB $namespace && sleep 2s
|
||||
|
||||
echo "[STEP 3] Waiting for Inlets LB Service to be created..!";
|
||||
output=$(waitForInletsLBToBeReady $namespace $providerName)
|
||||
loadbalancerIPOrHostName=$(echo "$output" | tail -n1)
|
||||
echo "[Info] LB IP is $loadbalancerIPOrHostName"
|
||||
|
||||
echo "[STEP 4] Creating the server Pod for TLS Termination and Tunneling connection..!";
|
||||
createServerPod $namespace $providerName
|
||||
|
||||
echo "[STEP 5] Waiting for Inlets Pod to be ready..!";
|
||||
waitForInletsPodToBeReady $namespace
|
||||
|
||||
echo "[STEP 6] Creating WebhookSVC LB..!"
|
||||
createOrUpdateWebhookSVC $namespace $providerName
|
||||
|
||||
echo "[STEP 7] Initializing the inlets client";
|
||||
echo "[Info] Inlets initialized, you are ready to go ahead and run \"make EXTENSION_NAMESPACE=$namespace WEBHOOK_CONFIG_MODE=service start\""
|
||||
echo "[Info] It will take about 5 seconds for the connection to succeeed!"
|
||||
|
||||
inlets client --remote ws://$loadbalancerIPOrHostName:8000 --upstream https://localhost:$webhookServerPort --token=21d809ed61915c9177fbceeaa87e307e766be5f2
|
||||
;;
|
||||
[Nn]* ) echo "You need to set \`ignoreResources\` to true and generate the controller installlation first in your extension chart before proceeding!"; exit;;
|
||||
* ) echo "Please answer yes or no.";;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
#
|
||||
# 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.
|
||||
|
||||
set -e
|
||||
|
||||
echo "> Installing requirements"
|
||||
|
||||
GO111MODULE=off go get golang.org/x/tools/cmd/goimports
|
||||
|
||||
export GO111MODULE=on
|
||||
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.27.0
|
||||
curl -s "https://raw.githubusercontent.com/helm/helm/v2.17.0/scripts/get" | bash -s -- --version 'v2.17.0'
|
||||
|
||||
if [[ "$(uname -s)" == *"Darwin"* ]]; then
|
||||
cat <<EOM
|
||||
You are running in a MAC OS environment!
|
||||
|
||||
Please make sure you have installed the following requirements:
|
||||
|
||||
- GNU Core Utils
|
||||
- GNU Tar
|
||||
- GNU Sed
|
||||
|
||||
Brew command:
|
||||
$ brew install coreutils gnu-tar gnu-sed
|
||||
|
||||
Please allow them to be used without their "g" prefix:
|
||||
$ export PATH=/usr/local/opt/coreutils/libexec/gnubin:\$PATH
|
||||
$ export PATH=/usr/local/opt/gnu-tar/libexec/gnubin:\$PATH
|
||||
$ export PATH=/usr/local/opt/gnu-sed/libexec/gnubin:\$PATH
|
||||
EOM
|
||||
fi
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
#
|
||||
# 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.
|
||||
|
||||
set -e
|
||||
|
||||
echo "> Install"
|
||||
|
||||
LD_FLAGS="${LD_FLAGS:-$($(dirname $0)/get-build-ld-flags.sh)}"
|
||||
|
||||
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on \
|
||||
go install -mod=vendor -ldflags "$LD_FLAGS" \
|
||||
$@
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright 2020 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.
|
||||
#
|
||||
# This file was copied and modified from the kubernetes-sigs/controller-runtime project
|
||||
# https://github.com/kubernetes-sigs/controller-runtime/blob/a9bd9117a77a2f84bbc546e28991136fe0000dc0/hack/setup-envtest.sh
|
||||
#
|
||||
# Modifications copyright (c) 2020 SAP SE or an SAP affiliate company. All rights reserved.
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
# Turn colors in this script off by setting the NO_COLOR variable in your
|
||||
# environment to any value:
|
||||
#
|
||||
# $ NO_COLOR=1 test.sh
|
||||
NO_COLOR=${NO_COLOR:-""}
|
||||
if [ -z "$NO_COLOR" ]; then
|
||||
header=$'\e[1;33m'
|
||||
reset=$'\e[0m'
|
||||
else
|
||||
header=''
|
||||
reset=''
|
||||
fi
|
||||
|
||||
function header_text {
|
||||
echo "$header$*$reset"
|
||||
}
|
||||
|
||||
function setup_envtest_env {
|
||||
header_text "setting up env vars"
|
||||
|
||||
# Setup env vars
|
||||
KUBEBUILDER_ASSETS=${KUBEBUILDER_ASSETS:-""}
|
||||
if [[ -z "${KUBEBUILDER_ASSETS}" ]]; then
|
||||
export KUBEBUILDER_ASSETS="$1/bin"
|
||||
fi
|
||||
}
|
||||
|
||||
# Fetch k8s API gen tools and make it available under KUBEBUILDER_ASSETS.
|
||||
#
|
||||
# Skip fetching and untaring the tools by setting the SKIP_FETCH_TOOLS variable
|
||||
# in your environment to any value:
|
||||
#
|
||||
# $ SKIP_FETCH_TOOLS=1 ./check-everything.sh
|
||||
#
|
||||
# If you skip fetching tools, this script will use the tools already on your
|
||||
# machine.
|
||||
function fetch_envtest_tools {
|
||||
SKIP_FETCH_TOOLS=${SKIP_FETCH_TOOLS:-""}
|
||||
if [ -n "$SKIP_FETCH_TOOLS" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
tmp_root=/tmp
|
||||
envtest_root_dir=$tmp_root/envtest
|
||||
|
||||
k8s_version="${ENVTEST_K8S_VERSION:-1.17.9}"
|
||||
goarch="$(go env GOARCH)"
|
||||
goos="$(go env GOOS)"
|
||||
|
||||
if [[ "$goos" != "linux" && "$goos" != "darwin" ]]; then
|
||||
echo "OS '$goos' not supported. Aborting." >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
local dest_dir="${1}"
|
||||
|
||||
# use the pre-existing version in the temporary folder if it matches our k8s version
|
||||
if [[ -x "${dest_dir}/bin/kube-apiserver" ]]; then
|
||||
version=$("${dest_dir}"/bin/kube-apiserver --version)
|
||||
if [[ $version == *"${k8s_version}"* ]]; then
|
||||
header_text "Using cached envtest tools from ${dest_dir}"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
header_text "fetching envtest tools@${k8s_version} (into '${dest_dir}')"
|
||||
envtest_tools_archive_name="kubebuilder-tools-$k8s_version-$goos-$goarch.tar.gz"
|
||||
envtest_tools_download_url="https://storage.googleapis.com/kubebuilder-tools/$envtest_tools_archive_name"
|
||||
|
||||
envtest_tools_archive_path="$tmp_root/$envtest_tools_archive_name"
|
||||
if [ ! -f $envtest_tools_archive_path ]; then
|
||||
curl -sL ${envtest_tools_download_url} -o "$envtest_tools_archive_path"
|
||||
fi
|
||||
|
||||
mkdir -p "${dest_dir}"
|
||||
tar -C "${dest_dir}" --strip-components=1 -zvxf "$envtest_tools_archive_path"
|
||||
}
|
||||
|
||||
bin_dir="$(git rev-parse --show-toplevel)/bin"
|
||||
kb_root_dir="$bin_dir/kubebuilder"
|
||||
|
||||
mkdir -p "$kb_root_dir"
|
||||
fetch_envtest_tools "$kb_root_dir"
|
||||
setup_envtest_env "$kb_root_dir"
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2020 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
#
|
||||
# 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.
|
||||
set -e
|
||||
|
||||
echo "> Test Cover Clean"
|
||||
|
||||
find . -name "*.coverprofile" -type f -delete
|
||||
rm -f test.coverage.html test.coverprofile
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2020 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
#
|
||||
# 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.
|
||||
set -e
|
||||
|
||||
source "$(dirname $0)/setup-envtest.sh"
|
||||
|
||||
echo "> Test Cover"
|
||||
|
||||
GO111MODULE=on ginkgo -cover -timeout=2m -race -mod=vendor $@
|
||||
|
||||
REPO_ROOT="$(git rev-parse --show-toplevel)"
|
||||
COVERPROFILE="$REPO_ROOT/test.coverprofile"
|
||||
COVERPROFILE_TMP="$REPO_ROOT/test.coverprofile.tmp"
|
||||
COVERPROFILE_HTML="$REPO_ROOT/test.coverage.html"
|
||||
|
||||
echo "mode: set" > "$COVERPROFILE_TMP"
|
||||
find . -name "*.coverprofile" -type f | xargs cat | grep -v mode: | sort -r | awk '{if($1 != last) {print $0;last=$1}}' >> "$COVERPROFILE_TMP"
|
||||
cat "$COVERPROFILE_TMP" | grep -vE "\.pb\.go|zz_generated" > "$COVERPROFILE"
|
||||
rm -rf "$COVERPROFILE_TMP"
|
||||
go tool cover -html="$COVERPROFILE" -o="$COVERPROFILE_HTML"
|
||||
|
||||
go tool cover -func="$COVERPROFILE"
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
#
|
||||
# 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.
|
||||
set -e
|
||||
|
||||
echo "> Test Prometheus"
|
||||
|
||||
echo "Executing Prometheus alert tests"
|
||||
pushd "$(dirname $0)/../charts/seed-monitoring/charts/core/charts/prometheus" > /dev/null
|
||||
promtool test rules rules-tests/*test.yaml
|
||||
popd > /dev/null
|
||||
|
||||
echo "Executing aggregate Prometheus alert tests"
|
||||
pushd "$(dirname $0)/../charts/seed-bootstrap/aggregate-prometheus-rules-tests" > /dev/null
|
||||
promtool test rules *test.yaml
|
||||
popd > /dev/null
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
#
|
||||
# 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.
|
||||
set -e
|
||||
|
||||
source "$(dirname $0)/setup-envtest.sh"
|
||||
|
||||
echo "> Test"
|
||||
|
||||
GO111MODULE=on go test -race -mod=vendor $@ | grep -v 'no test files'
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
// +build tools
|
||||
|
||||
// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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.
|
||||
|
||||
// This package imports things required by build scripts, to force `go mod` to see them as dependencies
|
||||
package tools
|
||||
|
||||
import (
|
||||
_ "github.com/ahmetb/gen-crd-api-reference-docs"
|
||||
_ "github.com/golang/mock/mockgen"
|
||||
_ "github.com/onsi/ginkgo/ginkgo"
|
||||
_ "golang.org/x/lint/golint"
|
||||
_ "k8s.io/code-generator"
|
||||
_ "k8s.io/code-generator/cmd/go-to-protobuf/protoc-gen-gogo"
|
||||
_ "k8s.io/kube-openapi/cmd/openapi-gen"
|
||||
_ "sigs.k8s.io/controller-tools/cmd/controller-gen"
|
||||
)
|
||||
+190
@@ -0,0 +1,190 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2020 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
#
|
||||
# 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.
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
rm -f ${GOPATH}/bin/*-gen
|
||||
|
||||
CURRENT_DIR=$(dirname $0)
|
||||
PROJECT_ROOT="${CURRENT_DIR}"/..
|
||||
|
||||
# core.gardener.cloud APIs
|
||||
|
||||
bash "${PROJECT_ROOT}"/vendor/k8s.io/code-generator/generate-internal-groups.sh \
|
||||
deepcopy,defaulter,client,lister,informer \
|
||||
github.com/gardener/gardener/pkg/client/core \
|
||||
github.com/gardener/gardener/pkg/apis \
|
||||
github.com/gardener/gardener/pkg/apis \
|
||||
"core:v1alpha1,v1beta1" \
|
||||
-h "${PROJECT_ROOT}/hack/LICENSE_BOILERPLATE.txt"
|
||||
|
||||
bash "${PROJECT_ROOT}"/vendor/k8s.io/code-generator/generate-internal-groups.sh \
|
||||
conversion \
|
||||
github.com/gardener/gardener/pkg/client/core \
|
||||
github.com/gardener/gardener/pkg/apis \
|
||||
github.com/gardener/gardener/pkg/apis \
|
||||
"core:v1alpha1,v1beta1" \
|
||||
-h "${PROJECT_ROOT}/hack/LICENSE_BOILERPLATE.txt"
|
||||
|
||||
# extensions.gardener.cloud APIs
|
||||
|
||||
bash "${PROJECT_ROOT}"/vendor/k8s.io/code-generator/generate-groups.sh \
|
||||
"deepcopy,client,informer,lister" \
|
||||
github.com/gardener/gardener/pkg/client/extensions \
|
||||
github.com/gardener/gardener/pkg/apis \
|
||||
"extensions:v1alpha1" \
|
||||
-h "${PROJECT_ROOT}/hack/LICENSE_BOILERPLATE.txt"
|
||||
|
||||
# settings.gardener.cloud APIs
|
||||
|
||||
bash "${PROJECT_ROOT}"/vendor/k8s.io/code-generator/generate-groups.sh \
|
||||
"all" \
|
||||
github.com/gardener/gardener/pkg/client/settings \
|
||||
github.com/gardener/gardener/pkg/apis \
|
||||
"settings:v1alpha1" \
|
||||
-h "${PROJECT_ROOT}/hack/LICENSE_BOILERPLATE.txt"
|
||||
|
||||
bash "${PROJECT_ROOT}"/vendor/k8s.io/code-generator/generate-internal-groups.sh \
|
||||
"deepcopy,defaulter,conversion" \
|
||||
github.com/gardener/gardener/pkg/client/settings \
|
||||
github.com/gardener/gardener/pkg/apis \
|
||||
github.com/gardener/gardener/pkg/apis \
|
||||
"settings:v1alpha1" \
|
||||
-h "${PROJECT_ROOT}/hack/LICENSE_BOILERPLATE.txt"
|
||||
|
||||
# Componentconfig for controller-manager
|
||||
|
||||
bash "${PROJECT_ROOT}"/vendor/k8s.io/code-generator/generate-internal-groups.sh \
|
||||
deepcopy,defaulter \
|
||||
github.com/gardener/gardener/pkg/client/componentconfig \
|
||||
github.com/gardener/gardener/pkg/controllermanager/apis \
|
||||
github.com/gardener/gardener/pkg/controllermanager/apis \
|
||||
"config:v1alpha1" \
|
||||
-h "${PROJECT_ROOT}/hack/LICENSE_BOILERPLATE.txt"
|
||||
|
||||
bash "${PROJECT_ROOT}"/vendor/k8s.io/code-generator/generate-internal-groups.sh \
|
||||
conversion \
|
||||
github.com/gardener/gardener/pkg/client/componentconfig \
|
||||
github.com/gardener/gardener/pkg/controllermanager/apis \
|
||||
github.com/gardener/gardener/pkg/controllermanager/apis \
|
||||
"config:v1alpha1" \
|
||||
--extra-peer-dirs=github.com/gardener/gardener/pkg/controllermanager/apis/config,github.com/gardener/gardener/pkg/controllermanager/apis/config/v1alpha1,k8s.io/apimachinery/pkg/apis/meta/v1,k8s.io/apimachinery/pkg/conversion,k8s.io/apimachinery/pkg/runtime,k8s.io/component-base/config,k8s.io/component-base/config/v1alpha1 \
|
||||
-h "${PROJECT_ROOT}/hack/LICENSE_BOILERPLATE.txt"
|
||||
|
||||
# Componentconfig for admission controller
|
||||
|
||||
bash "${PROJECT_ROOT}"/vendor/k8s.io/code-generator/generate-internal-groups.sh \
|
||||
deepcopy,defaulter \
|
||||
github.com/gardener/gardener/pkg/client/admissioncontrollerconfig \
|
||||
github.com/gardener/gardener/pkg/admissioncontroller/apis \
|
||||
github.com/gardener/gardener/pkg/admissioncontroller/apis \
|
||||
"config:v1alpha1" \
|
||||
-h "${PROJECT_ROOT}/hack/LICENSE_BOILERPLATE.txt"
|
||||
|
||||
bash "${PROJECT_ROOT}"/vendor/k8s.io/code-generator/generate-internal-groups.sh \
|
||||
conversion \
|
||||
github.com/gardener/gardener/pkg/client/admissioncontrollerconfig \
|
||||
github.com/gardener/gardener/pkg/admissioncontroller/apis \
|
||||
github.com/gardener/gardener/pkg/admissioncontroller/apis \
|
||||
"config:v1alpha1" \
|
||||
--extra-peer-dirs=github.com/gardener/gardener/pkg/admissioncontroller/apis/config,github.com/gardener/gardener/pkg/admissioncontroller/apis/config/v1alpha1,k8s.io/apimachinery/pkg/apis/meta/v1,k8s.io/apimachinery/pkg/conversion,k8s.io/apimachinery/pkg/runtime,k8s.io/component-base/config,k8s.io/component-base/config/v1alpha1 \
|
||||
-h "${PROJECT_ROOT}/hack/LICENSE_BOILERPLATE.txt"
|
||||
|
||||
# Configuration for gardener scheduler
|
||||
|
||||
bash "${PROJECT_ROOT}"/vendor/k8s.io/code-generator/generate-internal-groups.sh \
|
||||
deepcopy,defaulter \
|
||||
github.com/gardener/gardener/pkg/scheduler/client \
|
||||
github.com/gardener/gardener/pkg/scheduler/apis \
|
||||
github.com/gardener/gardener/pkg/scheduler/apis \
|
||||
"config:v1alpha1" \
|
||||
-h "${PROJECT_ROOT}/hack/LICENSE_BOILERPLATE.txt"
|
||||
|
||||
bash "${PROJECT_ROOT}"/vendor/k8s.io/code-generator/generate-internal-groups.sh \
|
||||
conversion \
|
||||
github.com/gardener/gardener/pkg/scheduler/client \
|
||||
github.com/gardener/gardener/pkg/scheduler/apis \
|
||||
github.com/gardener/gardener/pkg/scheduler/apis \
|
||||
"config:v1alpha1" \
|
||||
--extra-peer-dirs=github.com/gardener/gardener/pkg/scheduler/apis/config,github.com/gardener/gardener/pkg/scheduler/apis/config/v1alpha1,k8s.io/apimachinery/pkg/apis/meta/v1,k8s.io/apimachinery/pkg/conversion,k8s.io/apimachinery/pkg/runtime,k8s.io/component-base/config,k8s.io/component-base/config/v1alpha1 \
|
||||
-h "${PROJECT_ROOT}/hack/LICENSE_BOILERPLATE.txt"
|
||||
|
||||
# Componentconfig for gardenlet
|
||||
|
||||
bash "${PROJECT_ROOT}"/vendor/k8s.io/code-generator/generate-internal-groups.sh \
|
||||
deepcopy,defaulter \
|
||||
github.com/gardener/gardener/pkg/client/componentconfig \
|
||||
github.com/gardener/gardener/pkg/gardenlet/apis \
|
||||
github.com/gardener/gardener/pkg/gardenlet/apis \
|
||||
"config:v1alpha1" \
|
||||
-h "${PROJECT_ROOT}/hack/LICENSE_BOILERPLATE.txt"
|
||||
|
||||
bash "${PROJECT_ROOT}"/vendor/k8s.io/code-generator/generate-internal-groups.sh \
|
||||
conversion \
|
||||
github.com/gardener/gardener/pkg/client/componentconfig \
|
||||
github.com/gardener/gardener/pkg/gardenlet/apis \
|
||||
github.com/gardener/gardener/pkg/gardenlet/apis \
|
||||
"config:v1alpha1" \
|
||||
--extra-peer-dirs=github.com/gardener/gardener/pkg/gardenlet/apis/config,github.com/gardener/gardener/pkg/gardenlet/apis/config/v1alpha1,k8s.io/apimachinery/pkg/apis/meta/v1,k8s.io/apimachinery/pkg/conversion,k8s.io/apimachinery/pkg/runtime,k8s.io/component-base/config,k8s.io/component-base/config/v1alpha1 \
|
||||
-h "${PROJECT_ROOT}/hack/LICENSE_BOILERPLATE.txt"
|
||||
|
||||
# Componentconfig for admission plugins
|
||||
|
||||
bash "${PROJECT_ROOT}"/vendor/k8s.io/code-generator/generate-internal-groups.sh \
|
||||
deepcopy,defaulter \
|
||||
github.com/gardener/gardener/pkg/client/componentconfig \
|
||||
github.com/gardener/gardener/plugin/pkg/shoot/tolerationrestriction/apis \
|
||||
github.com/gardener/gardener/plugin/pkg/shoot/tolerationrestriction/apis \
|
||||
"shoottolerationrestriction:v1alpha1" \
|
||||
-h "${PROJECT_ROOT}/hack/LICENSE_BOILERPLATE.txt"
|
||||
|
||||
bash "${PROJECT_ROOT}"/vendor/k8s.io/code-generator/generate-internal-groups.sh \
|
||||
conversion \
|
||||
github.com/gardener/gardener/pkg/client/componentconfig \
|
||||
github.com/gardener/gardener/plugin/pkg/shoot/tolerationrestriction/apis \
|
||||
github.com/gardener/gardener/plugin/pkg/shoot/tolerationrestriction/apis \
|
||||
"shoottolerationrestriction:v1alpha1" \
|
||||
--extra-peer-dirs=github.com/gardener/gardener/plugin/pkg/shoot/tolerationrestriction/apis/shoottolerationrestriction,github.com/gardener/gardener/plugin/pkg/shoot/tolerationrestriction/apis/shoottolerationrestriction/v1alpha1,k8s.io/apimachinery/pkg/apis/meta/v1,k8s.io/apimachinery/pkg/conversion,k8s.io/apimachinery/pkg/runtime,k8s.io/component-base/config,k8s.io/component-base/config/v1alpha1 \
|
||||
-h "${PROJECT_ROOT}/hack/LICENSE_BOILERPLATE.txt"
|
||||
|
||||
# OpenAPI definitions
|
||||
|
||||
echo "Generating openapi definitions"
|
||||
rm -Rf ./${PROJECT_ROOT}/openapi/openapi_generated.go
|
||||
go install ./${PROJECT_ROOT}/vendor/k8s.io/kube-openapi/cmd/openapi-gen
|
||||
${GOPATH}/bin/openapi-gen "$@" \
|
||||
--v 1 \
|
||||
--logtostderr \
|
||||
--input-dirs=github.com/gardener/gardener/pkg/apis/core/v1alpha1 \
|
||||
--input-dirs=github.com/gardener/gardener/pkg/apis/core/v1beta1 \
|
||||
--input-dirs=github.com/gardener/gardener/pkg/apis/settings/v1alpha1 \
|
||||
--input-dirs=k8s.io/api/core/v1 \
|
||||
--input-dirs=k8s.io/api/rbac/v1 \
|
||||
--input-dirs=k8s.io/api/autoscaling/v1 \
|
||||
--input-dirs=k8s.io/apimachinery/pkg/apis/meta/v1 \
|
||||
--input-dirs=k8s.io/apimachinery/pkg/api/resource \
|
||||
--input-dirs=k8s.io/apimachinery/pkg/types \
|
||||
--input-dirs=k8s.io/apimachinery/pkg/version \
|
||||
--input-dirs=k8s.io/apimachinery/pkg/runtime \
|
||||
--input-dirs=k8s.io/apimachinery/pkg/util/intstr \
|
||||
--report-filename=${PROJECT_ROOT}/pkg/openapi/api_violations.report \
|
||||
--output-package=github.com/gardener/gardener/pkg/openapi \
|
||||
-h "${PROJECT_ROOT}/hack/LICENSE_BOILERPLATE.txt"
|
||||
|
||||
echo
|
||||
echo "NOTE: If you changed the API then consider updating the example manifests."
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2020 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
#
|
||||
# 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.
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
CURRENT_DIR="$(dirname $0)"
|
||||
PROJECT_ROOT="${CURRENT_DIR}"/..
|
||||
if [ "${PROJECT_ROOT#/}" == "${PROJECT_ROOT}" ]; then
|
||||
PROJECT_ROOT="./$PROJECT_ROOT"
|
||||
fi
|
||||
|
||||
pushd "$PROJECT_ROOT" > /dev/null
|
||||
APIROOTS=${APIROOTS:-$(git grep --files-with-matches -e '// +k8s:protobuf-gen=package' cmd pkg | \
|
||||
xargs -n 1 dirname | \
|
||||
sed 's,^,github.com/gardener/gardener/,;' | \
|
||||
sort | uniq
|
||||
)}
|
||||
popd > /dev/null
|
||||
|
||||
rm -f ${GOPATH}/bin/go-to-protobuf
|
||||
rm -f ${GOPATH}/bin/protoc-gen-gogo
|
||||
|
||||
GOFLAGS="" go build -o ${GOPATH}/bin "$PROJECT_ROOT/vendor/k8s.io/code-generator/cmd/go-to-protobuf"
|
||||
GOFLAGS="" go build -o ${GOPATH}/bin "$PROJECT_ROOT/vendor/k8s.io/code-generator/cmd/go-to-protobuf/protoc-gen-gogo"
|
||||
|
||||
if [[ -z "$(which protoc)" || "$(protoc --version)" != "libprotoc 3."* ]]; then
|
||||
if [[ "$(uname -s)" == *"Darwin"* ]]; then
|
||||
brew install protobuf
|
||||
else
|
||||
PROTOC_ZIP=protoc-3.7.1-linux-x86_64.zip
|
||||
curl -OL https://github.com/protocolbuffers/protobuf/releases/download/v3.7.1/$PROTOC_ZIP
|
||||
unzip -o $PROTOC_ZIP -d /usr/local bin/protoc
|
||||
unzip -o $PROTOC_ZIP -d /usr/local 'include/*'
|
||||
rm -f $PROTOC_ZIP
|
||||
fi
|
||||
|
||||
echo "WARNING: Protobuf changes are not being validated"
|
||||
fi
|
||||
|
||||
read -ra PACKAGES <<< $(echo ${APIROOTS})
|
||||
|
||||
# requires the 'proto' tag to build (will remove when ready)
|
||||
# searches for the protoc-gen-gogo extension in the output directory
|
||||
# satisfies import of github.com/gogo/protobuf/gogoproto/gogo.proto and the
|
||||
# core Google protobuf types
|
||||
go-to-protobuf \
|
||||
--packages="$(IFS=, ; echo "${PACKAGES[*]}")" \
|
||||
--apimachinery-packages='-k8s.io/apimachinery/pkg/util/intstr,-k8s.io/apimachinery/pkg/api/resource,-k8s.io/apimachinery/pkg/runtime/schema,-k8s.io/apimachinery/pkg/runtime,-k8s.io/apimachinery/pkg/apis/meta/v1,-k8s.io/apimachinery/pkg/apis/meta/v1beta1,-k8s.io/api/core/v1,-k8s.io/api/rbac/v1,-k8s.io/api/autoscaling/v1' \
|
||||
--go-header-file=${PROJECT_ROOT}/hack/LICENSE_BOILERPLATE.txt \
|
||||
--proto-import=${PROJECT_ROOT}/vendor
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
// Copyright (c) 2020 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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 core
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
gardencore "github.com/gardener/gardener/pkg/apis/core"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// Accessor tries to create a `gardencore.Object` from the given runtime.Object.
|
||||
//
|
||||
// If the given object already implements Object, it is returned as-is.
|
||||
// Otherwise, an error with the type of the object is returned.
|
||||
func Accessor(obj runtime.Object) (gardencore.Object, error) {
|
||||
switch v := obj.(type) {
|
||||
case gardencore.Object:
|
||||
return v, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("value of type %T does not implement Object", obj)
|
||||
}
|
||||
}
|
||||
+263
@@ -0,0 +1,263 @@
|
||||
// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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 extensions
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
gardencorev1beta1 "github.com/gardener/gardener/pkg/apis/core/v1beta1"
|
||||
extensionsv1alpha1 "github.com/gardener/gardener/pkg/apis/extensions/v1alpha1"
|
||||
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// Accessor tries to create an extensionsv1alpha1.Object from the given runtime.Object.
|
||||
//
|
||||
// If the given object already implements object, it is returned as-is.
|
||||
// If the object is unstructured, an unstructured accessor is returned that retrieves values
|
||||
// on a best-effort basis.
|
||||
// Otherwise, an error with the type of the object is returned.
|
||||
func Accessor(obj runtime.Object) (extensionsv1alpha1.Object, error) {
|
||||
switch v := obj.(type) {
|
||||
case extensionsv1alpha1.Object:
|
||||
return v, nil
|
||||
case *unstructured.Unstructured:
|
||||
return UnstructuredAccessor(v), nil
|
||||
default:
|
||||
return nil, fmt.Errorf("value of type %T does not implement Object", obj)
|
||||
}
|
||||
}
|
||||
|
||||
// UnstructuredAccessor is an Object that retrieves values on a best-effort basis.
|
||||
// If values don't exist, it usually returns the zero value of them.
|
||||
func UnstructuredAccessor(u *unstructured.Unstructured) extensionsv1alpha1.Object {
|
||||
return unstructuredAccessor{u}
|
||||
}
|
||||
|
||||
type unstructuredAccessor struct {
|
||||
*unstructured.Unstructured
|
||||
}
|
||||
|
||||
type unstructuredSpecAccessor struct {
|
||||
*unstructured.Unstructured
|
||||
}
|
||||
|
||||
type unstructuredStatusAccessor struct {
|
||||
*unstructured.Unstructured
|
||||
}
|
||||
|
||||
func nestedString(obj map[string]interface{}, fields ...string) string {
|
||||
v, ok, err := unstructured.NestedString(obj, fields...)
|
||||
if err != nil || !ok {
|
||||
return ""
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func nestedInt64(obj map[string]interface{}, fields ...string) int64 {
|
||||
v, ok, err := unstructured.NestedInt64(obj, fields...)
|
||||
if err != nil || !ok {
|
||||
return 0
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func nestedStringReference(obj map[string]interface{}, fields ...string) *string {
|
||||
v, ok, err := unstructured.NestedString(obj, fields...)
|
||||
if err != nil || !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &v
|
||||
}
|
||||
|
||||
func nestedRawExtension(obj map[string]interface{}, fields ...string) *runtime.RawExtension {
|
||||
val, ok, err := unstructured.NestedFieldNoCopy(obj, fields...)
|
||||
if err != nil || !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
data, ok := val.(map[string]interface{})
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
rawExtension := &runtime.RawExtension{}
|
||||
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(data, rawExtension); err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return rawExtension
|
||||
}
|
||||
|
||||
// GetExtensionSpec implements Object.
|
||||
func (u unstructuredAccessor) GetExtensionSpec() extensionsv1alpha1.Spec {
|
||||
return unstructuredSpecAccessor(u)
|
||||
}
|
||||
|
||||
// GetExtensionType implements Spec.
|
||||
func (u unstructuredSpecAccessor) GetExtensionType() string {
|
||||
return nestedString(u.UnstructuredContent(), "spec", "type")
|
||||
}
|
||||
|
||||
// GetExtensionPurpose implements Spec.
|
||||
func (u unstructuredSpecAccessor) GetExtensionPurpose() *string {
|
||||
return nestedStringReference(u.UnstructuredContent(), "spec", "purpose")
|
||||
}
|
||||
|
||||
// GetProviderConfig implements Spec.
|
||||
func (u unstructuredSpecAccessor) GetProviderConfig() *runtime.RawExtension {
|
||||
return nestedRawExtension(u.UnstructuredContent(), "spec", "providerConfig")
|
||||
}
|
||||
|
||||
// GetExtensionStatus implements Object.
|
||||
func (u unstructuredAccessor) GetExtensionStatus() extensionsv1alpha1.Status {
|
||||
return unstructuredStatusAccessor(u)
|
||||
}
|
||||
|
||||
// GetProviderStatus implements Status.
|
||||
func (u unstructuredStatusAccessor) GetProviderStatus() *runtime.RawExtension {
|
||||
return nestedRawExtension(u.UnstructuredContent(), "status", "providerStatus")
|
||||
}
|
||||
|
||||
// GetLastOperation implements Status.
|
||||
func (u unstructuredStatusAccessor) GetLastOperation() *gardencorev1beta1.LastOperation {
|
||||
val, ok, err := unstructured.NestedFieldNoCopy(u.UnstructuredContent(), "status", "lastOperation")
|
||||
if err != nil || !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
lastOperation := &gardencorev1beta1.LastOperation{}
|
||||
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(val.(map[string]interface{}), lastOperation); err != nil {
|
||||
return nil
|
||||
}
|
||||
return lastOperation
|
||||
}
|
||||
|
||||
// GetLastError implements Status.
|
||||
func (u unstructuredStatusAccessor) GetLastError() *gardencorev1beta1.LastError {
|
||||
val, ok, err := unstructured.NestedFieldNoCopy(u.UnstructuredContent(), "status", "lastError")
|
||||
if err != nil || !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
lastError := &gardencorev1beta1.LastError{}
|
||||
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(val.(map[string]interface{}), lastError); err != nil {
|
||||
return nil
|
||||
}
|
||||
return lastError
|
||||
}
|
||||
|
||||
// GetObservedGeneration implements Status.
|
||||
func (u unstructuredStatusAccessor) GetObservedGeneration() int64 {
|
||||
return nestedInt64(u.Object, "status", "observedGeneration")
|
||||
}
|
||||
|
||||
// GetState implements Status.
|
||||
func (u unstructuredStatusAccessor) GetState() *runtime.RawExtension {
|
||||
val, ok, err := unstructured.NestedFieldNoCopy(u.UnstructuredContent(), "status", "state")
|
||||
if err != nil || !ok {
|
||||
return nil
|
||||
}
|
||||
raw := &runtime.RawExtension{}
|
||||
err = runtime.DefaultUnstructuredConverter.FromUnstructured(val.(map[string]interface{}), raw)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return raw
|
||||
}
|
||||
|
||||
// SetState implements Status.
|
||||
func (u unstructuredStatusAccessor) SetState(state *runtime.RawExtension) {
|
||||
unstrc, err := runtime.DefaultUnstructuredConverter.ToUnstructured(state)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err := unstructured.SetNestedField(u.UnstructuredContent(), unstrc, "status", "state"); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// GetConditions implements Status.
|
||||
func (u unstructuredStatusAccessor) GetConditions() []gardencorev1beta1.Condition {
|
||||
val, ok, err := unstructured.NestedFieldNoCopy(u.UnstructuredContent(), "status", "conditions")
|
||||
if err != nil || !ok {
|
||||
return nil
|
||||
}
|
||||
var conditions []gardencorev1beta1.Condition
|
||||
interfaceConditionSlice := val.([]interface{})
|
||||
for _, interfaceCondition := range interfaceConditionSlice {
|
||||
new := interfaceCondition.(map[string]interface{})
|
||||
condition := &gardencorev1beta1.Condition{}
|
||||
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(new, condition); err != nil {
|
||||
return nil
|
||||
}
|
||||
conditions = append(conditions, *condition)
|
||||
}
|
||||
return conditions
|
||||
}
|
||||
|
||||
// SetConditions implements Status.
|
||||
func (u unstructuredStatusAccessor) SetConditions(conditions []gardencorev1beta1.Condition) {
|
||||
var interfaceSlice = make([]interface{}, len(conditions))
|
||||
for i, d := range conditions {
|
||||
unstrc, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&d)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
interfaceSlice[i] = unstrc
|
||||
}
|
||||
err := unstructured.SetNestedSlice(u.UnstructuredContent(), interfaceSlice, "status", "conditions")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// GetResources implements Status.
|
||||
func (u unstructuredStatusAccessor) GetResources() []gardencorev1beta1.NamedResourceReference {
|
||||
val, ok, err := unstructured.NestedFieldNoCopy(u.UnstructuredContent(), "status", "resources")
|
||||
if err != nil || !ok {
|
||||
return nil
|
||||
}
|
||||
var resources []gardencorev1beta1.NamedResourceReference
|
||||
interfaceResourceSlice := val.([]interface{})
|
||||
for _, interfaceResource := range interfaceResourceSlice {
|
||||
new := interfaceResource.(map[string]interface{})
|
||||
resource := &gardencorev1beta1.NamedResourceReference{}
|
||||
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(new, resource); err != nil {
|
||||
return nil
|
||||
}
|
||||
resources = append(resources, *resource)
|
||||
}
|
||||
return resources
|
||||
}
|
||||
|
||||
// SetResources implements Status.
|
||||
func (u unstructuredStatusAccessor) SetResources(namedResourceReference []gardencorev1beta1.NamedResourceReference) {
|
||||
var interfaceSlice = make([]interface{}, len(namedResourceReference))
|
||||
for i, d := range namedResourceReference {
|
||||
unstrc, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&d)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
interfaceSlice[i] = unstrc
|
||||
}
|
||||
err := unstructured.SetNestedSlice(u.UnstructuredContent(), interfaceSlice, "status", "resources")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
// Copyright (c) 2020 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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 extensions
|
||||
|
||||
import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
extensionsv1alpha1 "github.com/gardener/gardener/pkg/apis/extensions/v1alpha1"
|
||||
)
|
||||
|
||||
// GetShootNamespacedCRsLists returns an empty CR list struct, for each CR used for Shoot management
|
||||
func GetShootNamespacedCRsLists() []client.ObjectList {
|
||||
return []client.ObjectList{
|
||||
// The ControlPlane CR is now handled as a shoot component
|
||||
// &extensionsv1alpha1.ControlPlaneList{},
|
||||
// The Extension CR is now handled as a shoot component
|
||||
// &extensionsv1alpha1.ExtensionList{},
|
||||
// The Infrastructure CR is now handled as a shoot component
|
||||
// &extensionsv1alpha1.InfrastructureList{},
|
||||
// The Network CR is now handled as a shoot component
|
||||
// &extensionsv1alpha1.NetworkList{},
|
||||
&extensionsv1alpha1.OperatingSystemConfigList{},
|
||||
// The Worker CR is now handled as a shoot component
|
||||
// &extensionsv1alpha1.WorkerList{},
|
||||
// The ContainerRuntime CR is now handled as a shoot component
|
||||
// &extensionsv1alpha1.ContainerRuntimeList{},
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
// Copyright (c) 2018 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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.
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
|
||||
// Package core is the internal version of the API.
|
||||
// +groupName=core.gardener.cloud
|
||||
package core
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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 core
|
||||
|
||||
// Field path constants that are specific to the internal API
|
||||
// representation.
|
||||
const (
|
||||
// BackupBucketSeedName is the field selector path for finding
|
||||
// the Seed cluster of a core.gardener.cloud/v1beta1 BackupBucket.
|
||||
BackupBucketSeedName = "spec.seedName"
|
||||
// BackupEntrySeedName is the field selector path for finding
|
||||
// the Seed cluster of a core.gardener.cloud/v1beta1 BackupEntry.
|
||||
BackupEntrySeedName = "spec.seedName"
|
||||
|
||||
// RegistrationRefName is the field selector path for finding
|
||||
// the ControllerRegistration name of a core.gardener.cloud/{v1beta1,v1beta1} ControllerInstallation.
|
||||
RegistrationRefName = "spec.registrationRef.name"
|
||||
// SeedRefName is the field selector path for finding
|
||||
// the Seed name of a core.gardener.cloud/{v1beta1,v1beta1} ControllerInstallation.
|
||||
SeedRefName = "spec.seedRef.name"
|
||||
|
||||
// ShootCloudProfileName is the field selector path for finding
|
||||
// the CloudProfile name of a core.gardener.cloud/{v1alpha1,v1beta1} Shoot.
|
||||
ShootCloudProfileName = "spec.cloudProfileName"
|
||||
// ShootSeedName is the field selector path for finding
|
||||
// the Seed cluster of a core.gardener.cloud/{v1alpha1,v1beta1} Shoot.
|
||||
ShootSeedName = "spec.seedName"
|
||||
// ShootStatusSeedName is the field selector path for finding
|
||||
// the Seed cluster of a core.gardener.cloud/{v1alpha1,v1beta1} Shoot
|
||||
// referred in the status.
|
||||
ShootStatusSeedName = "status.seedName"
|
||||
)
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
// Copyright (c) 2018 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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 install
|
||||
|
||||
import (
|
||||
"github.com/gardener/gardener/pkg/apis/core"
|
||||
"github.com/gardener/gardener/pkg/apis/core/v1alpha1"
|
||||
"github.com/gardener/gardener/pkg/apis/core/v1beta1"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
)
|
||||
|
||||
// Install registers the API group and adds types to a scheme.
|
||||
func Install(scheme *runtime.Scheme) {
|
||||
utilruntime.Must(core.AddToScheme(scheme))
|
||||
utilruntime.Must(v1alpha1.AddToScheme(scheme))
|
||||
utilruntime.Must(v1beta1.AddToScheme(scheme))
|
||||
|
||||
utilruntime.Must(scheme.SetVersionPriority(v1beta1.SchemeGroupVersion, v1alpha1.SchemeGroupVersion))
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
// Copyright (c) 2018 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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 core
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
// GroupName is the name of the core API group.
|
||||
const GroupName = "core.gardener.cloud"
|
||||
|
||||
// SchemeGroupVersion is group version used to register these objects.
|
||||
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal}
|
||||
|
||||
// Kind takes an unqualified kind and returns back a Group qualified GroupKind.
|
||||
func Kind(kind string) schema.GroupKind {
|
||||
return SchemeGroupVersion.WithKind(kind).GroupKind()
|
||||
}
|
||||
|
||||
// Resource takes an unqualified resource and returns back a Group qualified GroupResource.
|
||||
func Resource(resource string) schema.GroupResource {
|
||||
return SchemeGroupVersion.WithResource(resource).GroupResource()
|
||||
}
|
||||
|
||||
var (
|
||||
// SchemeBuilder is a new Scheme Builder which registers our API.
|
||||
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
|
||||
// AddToScheme is a reference to the Scheme Builder's AddToScheme function.
|
||||
AddToScheme = SchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
// Adds the list of known types to the given scheme.
|
||||
func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&BackupBucket{},
|
||||
&BackupBucketList{},
|
||||
&BackupEntry{},
|
||||
&BackupEntryList{},
|
||||
&CloudProfile{},
|
||||
&CloudProfileList{},
|
||||
&ControllerRegistration{},
|
||||
&ControllerRegistrationList{},
|
||||
&ControllerInstallation{},
|
||||
&ControllerInstallationList{},
|
||||
&Plant{},
|
||||
&PlantList{},
|
||||
&Project{},
|
||||
&ProjectList{},
|
||||
&Quota{},
|
||||
&QuotaList{},
|
||||
&SecretBinding{},
|
||||
&SecretBindingList{},
|
||||
&Seed{},
|
||||
&SeedList{},
|
||||
&ShootState{},
|
||||
&ShootStateList{},
|
||||
&Shoot{},
|
||||
&ShootList{},
|
||||
)
|
||||
return nil
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
// Copyright (c) 2020 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
|
||||
//
|
||||
// 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 core
|
||||
|
||||
import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
const (
|
||||
// GardenerSeedLeaseNamespace is the namespace in which Gardenlet will report Seeds'
|
||||
// status using Lease resources for each Seed
|
||||
GardenerSeedLeaseNamespace = "gardener-system-seed-lease"
|
||||
)
|
||||
|
||||
// Object is an core object resource.
|
||||
type Object interface {
|
||||
metav1.Object
|
||||
// GetProviderType gets the type of the provider.
|
||||
GetProviderType() string
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user