-
Notifications
You must be signed in to change notification settings - Fork 326
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #353 from hashicorp/crd-controller-base
CRD Controller
- Loading branch information
Showing
134 changed files
with
15,240 additions
and
295 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# this is a generated file used for operator sdk during code generation of CRDs, Controllers and webhooks | ||
domain: hashicorp.com | ||
layout: go.kubebuilder.io/v2 | ||
repo: github.com/hashicorp/consul-k8s | ||
version: 3-alpha | ||
plugins: | ||
go.operator-sdk.io/v2-alpha: {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
// Package common holds code that isn't tied to a particular CRD version or type. | ||
package common | ||
|
||
const ( | ||
ServiceDefaults string = "servicedefaults" | ||
ProxyDefaults string = "proxydefaults" | ||
ServiceResolver string = "serviceresolver" | ||
ServiceRouter string = "servicerouter" | ||
ServiceSplitter string = "servicesplitter" | ||
ServiceIntentions string = "serviceintentions" | ||
|
||
Global string = "global" | ||
DefaultConsulNamespace string = "default" | ||
WildcardNamespace string = "*" | ||
|
||
SourceKey string = "external-source" | ||
DatacenterKey string = "consul.hashicorp.com/source-datacenter" | ||
SourceValue string = "kubernetes" | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package common | ||
|
||
import ( | ||
"github.com/hashicorp/consul/api" | ||
corev1 "k8s.io/api/core/v1" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
"k8s.io/apimachinery/pkg/runtime" | ||
"k8s.io/apimachinery/pkg/runtime/schema" | ||
) | ||
|
||
// ConfigEntryResource is a generic config entry custom resource. It is implemented | ||
// by each config entry type so that they can be acted upon generically. | ||
// It is not tied to a specific CRD version. | ||
type ConfigEntryResource interface { | ||
// GetObjectMeta returns object meta. | ||
GetObjectMeta() metav1.ObjectMeta | ||
// AddFinalizer adds a finalizer to the list of finalizers. | ||
AddFinalizer(name string) | ||
// RemoveFinalizer removes this finalizer from the list. | ||
RemoveFinalizer(name string) | ||
// Finalizers returns the list of finalizers for this object. | ||
Finalizers() []string | ||
// ConsulKind returns the Consul config entry kind, i.e. service-defaults, not | ||
// servicedefaults. | ||
ConsulKind() string | ||
// ConsulGlobalResource returns if the resource exists in the default | ||
// Consul namespace only. | ||
ConsulGlobalResource() bool | ||
// ConsulMirroringNS returns the Consul namespace that the config entry should | ||
// be created in if namespaces and mirroring are enabled. | ||
ConsulMirroringNS() string | ||
// KubeKind returns the Kube config entry kind, i.e. servicedefaults, not | ||
// service-defaults. | ||
KubeKind() string | ||
// ConsulName returns the name of the config entry as saved in Consul. | ||
// This may be different than KubernetesName() in the case of a ServiceIntentions | ||
// config entry. | ||
ConsulName() string | ||
// KubernetesName returns the name of the Kubernetes resource. | ||
KubernetesName() string | ||
// SetSyncedCondition updates the synced condition. | ||
SetSyncedCondition(status corev1.ConditionStatus, reason, message string) | ||
// SyncedCondition gets the synced condition. | ||
SyncedCondition() (status corev1.ConditionStatus, reason, message string) | ||
// SyncedConditionStatus returns the status of the synced condition. | ||
SyncedConditionStatus() corev1.ConditionStatus | ||
// ToConsul converts the resource to the corresponding Consul API definition. | ||
// Its return type is the generic ConfigEntry but a specific config entry | ||
// type should be constructed e.g. ServiceConfigEntry. | ||
ToConsul(datacenter string) api.ConfigEntry | ||
// MatchesConsul returns true if the resource has the same fields as the Consul | ||
// config entry. | ||
MatchesConsul(candidate api.ConfigEntry) bool | ||
// GetObjectKind should be implemented by the generated code. | ||
GetObjectKind() schema.ObjectKind | ||
// DeepCopyObject should be implemented by the generated code. | ||
DeepCopyObject() runtime.Object | ||
// Validate returns an error if the resource is invalid. | ||
Validate() error | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package common | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"net/http" | ||
|
||
"github.com/go-logr/logr" | ||
"k8s.io/api/admission/v1beta1" | ||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission" | ||
) | ||
|
||
// ConfigEntryLister is implemented by CRD-specific webhooks. | ||
type ConfigEntryLister interface { | ||
// List returns all resources of this type across all namespaces in a | ||
// Kubernetes cluster. | ||
List(ctx context.Context) ([]ConfigEntryResource, error) | ||
} | ||
|
||
// ValidateConfigEntry validates cfgEntry. It is a generic method that | ||
// can be used by all CRD-specific validators. | ||
// Callers should pass themselves as validator and kind should be the custom | ||
// resource name, e.g. "ServiceDefaults". | ||
func ValidateConfigEntry( | ||
ctx context.Context, | ||
req admission.Request, | ||
logger logr.Logger, | ||
configEntryLister ConfigEntryLister, | ||
cfgEntry ConfigEntryResource, | ||
enableConsulNamespaces bool, | ||
nsMirroring bool) admission.Response { | ||
|
||
// On create we need to validate that there isn't already a resource with | ||
// the same name in a different namespace if we're need to mapping all Kube | ||
// resources to a single Consul namespace. The only case where we're not | ||
// mapping all kube resources to a single Consul namespace is when we | ||
// are running Consul enterprise with namespace mirroring. | ||
singleConsulDestNS := !(enableConsulNamespaces && nsMirroring) | ||
if req.Operation == v1beta1.Create && singleConsulDestNS { | ||
logger.Info("validate create", "name", cfgEntry.KubernetesName()) | ||
|
||
list, err := configEntryLister.List(ctx) | ||
if err != nil { | ||
return admission.Errored(http.StatusInternalServerError, err) | ||
} | ||
for _, item := range list { | ||
if item.KubernetesName() == cfgEntry.KubernetesName() { | ||
return admission.Errored(http.StatusBadRequest, | ||
fmt.Errorf("%s resource with name %q is already defined – all %s resources must have unique names across namespaces", | ||
cfgEntry.KubeKind(), | ||
cfgEntry.KubernetesName(), | ||
cfgEntry.KubeKind())) | ||
} | ||
} | ||
} | ||
if err := cfgEntry.Validate(); err != nil { | ||
return admission.Errored(http.StatusBadRequest, err) | ||
} | ||
return admission.Allowed(fmt.Sprintf("valid %s request", cfgEntry.KubeKind())) | ||
} |
Oops, something went wrong.