mirror of
https://github.com/kubevela/kubevela.git
synced 2026-05-02 15:36:58 +00:00
* Feat: ref component Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: support topology and override Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: add support for external policy and workflow Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: add admission control Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: disable cross namespace ref object Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Chore: refactor Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: support labelSelector in ref-objects Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: add pre approve for deploy step Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Chore: refactor Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: test Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: support comp/trait type in override policy even not used by prototype Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: support regex match for patch component name Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: labelSelector not work for cluster Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: ref workflow contains external policy Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: revision test Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: parallel apply components Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: add test for oam provider Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: service ref-comp & indirect trait ns Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: align namespace setting for chart Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add strict unmarshal and reformat Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: merge with cluster rework Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: patch trait-def Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: apply components + load dynamic component Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add test for loadPoliciesInOrder Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: add test for open merge Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: reformat & add test for step generator Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add test for parse override policy related defs Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add test for multicluster provider (expandTopology and overrideConfiguration) Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add admission test Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: revert trait status pass in component status Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add test for dependency in workflowstep & standalone multicluster test Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add check for ref and steps in WorkflowStep & enhance ref-objects scheme check Signed-off-by: Somefive <yd219913@alibaba-inc.com>
112 lines
3.7 KiB
Go
112 lines
3.7 KiB
Go
/*
|
|
Copyright 2021 The KubeVela Authors.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package resourcekeeper
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/pkg/errors"
|
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
|
|
|
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
|
|
)
|
|
|
|
var (
|
|
// AllowCrossNamespaceResource indicates whether application can apply resources into other namespaces
|
|
AllowCrossNamespaceResource = true
|
|
// AllowResourceTypes if not empty, application can only apply resources with specified types
|
|
AllowResourceTypes = ""
|
|
)
|
|
|
|
// AdmissionCheck check whether resources dispatch/deletion is admitted
|
|
func (h *resourceKeeper) AdmissionCheck(ctx context.Context, manifests []*unstructured.Unstructured) error {
|
|
for _, handler := range []ResourceAdmissionHandler{
|
|
&NamespaceAdmissionHandler{app: h.app},
|
|
&ResourceTypeAdmissionHandler{},
|
|
} {
|
|
if err := handler.Validate(ctx, manifests); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// ResourceAdmissionHandler defines the handler to validate the admission of resource operation
|
|
type ResourceAdmissionHandler interface {
|
|
Validate(ctx context.Context, manifests []*unstructured.Unstructured) error
|
|
}
|
|
|
|
// NamespaceAdmissionHandler defines the handler to validate if the resource namespace is valid to be dispatch/delete
|
|
type NamespaceAdmissionHandler struct {
|
|
app *v1beta1.Application
|
|
}
|
|
|
|
// Validate check if cross namespace is available
|
|
func (h *NamespaceAdmissionHandler) Validate(ctx context.Context, manifests []*unstructured.Unstructured) error {
|
|
if !AllowCrossNamespaceResource {
|
|
for _, manifest := range manifests {
|
|
if manifest.GetNamespace() != h.app.GetNamespace() {
|
|
return errors.Errorf("forbidden resource: %s %s/%s is outside the namespace of application", manifest.GetKind(), manifest.GetNamespace(), manifest.GetName())
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// ResourceTypeAdmissionHandler defines the handler to validate if the resource type is valid to be dispatch/delete
|
|
type ResourceTypeAdmissionHandler struct {
|
|
initialized bool
|
|
isWhiteList bool
|
|
resourceTypeMap map[string]struct{}
|
|
}
|
|
|
|
// Validate check if resource type is valid
|
|
func (h *ResourceTypeAdmissionHandler) Validate(ctx context.Context, manifests []*unstructured.Unstructured) error {
|
|
if AllowResourceTypes != "" {
|
|
if !h.initialized {
|
|
h.initialized = true
|
|
h.resourceTypeMap = make(map[string]struct{})
|
|
if strings.HasPrefix(AllowResourceTypes, "whitelist:") {
|
|
for _, t := range strings.Split(strings.TrimPrefix(AllowResourceTypes, "whitelist:"), ",") {
|
|
h.isWhiteList = true
|
|
h.resourceTypeMap[t] = struct{}{}
|
|
}
|
|
}
|
|
if strings.HasPrefix(AllowResourceTypes, "blacklist:") {
|
|
for _, t := range strings.Split(strings.TrimPrefix(AllowResourceTypes, "blacklist:"), ",") {
|
|
h.isWhiteList = false
|
|
h.resourceTypeMap[t] = struct{}{}
|
|
}
|
|
}
|
|
}
|
|
for _, manifest := range manifests {
|
|
gvk := manifest.GetObjectKind().GroupVersionKind()
|
|
resourceType := fmt.Sprintf("%s.%s", manifest.GetKind(), gvk.Version)
|
|
if gvk.Group != "" {
|
|
resourceType += "." + gvk.Group
|
|
}
|
|
_, found := h.resourceTypeMap[resourceType]
|
|
if h.isWhiteList != found {
|
|
return errors.Errorf("forbidden resource: type (%s) of resource %s/%s is not allowed", manifest.GetKind(), manifest.GetNamespace(), manifest.GetName())
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|