mirror of
https://github.com/kubevela/kubevela.git
synced 2026-05-19 15:56:54 +00:00
This commit implements Part 1 of the policy refactor plan, establishing
a clean and secure context structure for Application-scoped policies.
Key Changes:
1. Security: Metadata Filtering
- Added filterUserMetadata() to filter internal annotations/labels
- Prevents policies from accessing system annotations (app.oam.dev/*,
kubernetes.io/*, kubectl.kubernetes.io/*, etc.)
- O(1) map-based filtering for performance
2. Explicit Context Fields
- Added context.appName (instead of context.application.metadata.name)
- Added context.namespace, context.appRevision, context.appRevisionNum
- Added filtered context.appLabels and context.appAnnotations
- All exposed via process.Context infrastructure
3. Controlled Application Spec Access
- Added context.appComponents (components array only)
- Added context.appWorkflow (workflow object only)
- Added context.appPolicies (policies array only)
- Prevents unintended access to full Application CR
4. Removed context.application
- Completely removed to enforce explicit field access
- Deleted cleanApplicationForPolicyContext() helper function
- Forces security best practices
5. Removed context.prior
- Simplified incremental policy feature (can be added back later)
- Deleted associated test coverage
Test Changes:
- Deleted 3 test blocks relying on removed features
- Fixed TTL test expectation (CRD default is -1, not 0)
- Fixed WorkflowStep struct initialization
- All tests passing
Benefits:
- ✅ Clean API with explicit fields
- ✅ Security: No bypass to unfiltered metadata
- ✅ Forces best practices
- ✅ Simpler for policy authors
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
126 lines
4.1 KiB
Go
126 lines
4.1 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 process
|
|
|
|
import (
|
|
"context"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/kubevela/workflow/pkg/cue/process"
|
|
|
|
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
|
|
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
|
|
"github.com/oam-dev/kubevela/apis/types"
|
|
"github.com/oam-dev/kubevela/pkg/oam/util"
|
|
)
|
|
|
|
// ContextData is the core data of process context
|
|
type ContextData struct {
|
|
Namespace string
|
|
Cluster string
|
|
AppName string
|
|
CompName string
|
|
StepName string
|
|
CompRevision string
|
|
AppRevisionName string
|
|
WorkflowName string
|
|
PublishVersion string
|
|
ReplicaKey string
|
|
|
|
Ctx context.Context
|
|
BaseHooks []process.BaseHook
|
|
AuxiliaryHooks []process.AuxiliaryHook
|
|
Components []common.ApplicationComponent
|
|
|
|
AppLabels map[string]string
|
|
AppAnnotations map[string]string
|
|
AppComponents []common.ApplicationComponent
|
|
AppWorkflow *v1beta1.Workflow
|
|
AppPolicies []v1beta1.AppPolicy
|
|
|
|
ClusterVersion types.ClusterVersion
|
|
Output interface{}
|
|
}
|
|
|
|
// policyAdditionalContextKeyString is the string key for policy additionalContext in Go context
|
|
// We use a string key to avoid type mismatches across packages
|
|
const policyAdditionalContextKeyString = "kubevela.oam.dev/policy-additional-context"
|
|
|
|
// NewContext creates a new process context
|
|
func NewContext(data ContextData) process.Context {
|
|
// Extract policy additionalContext from Go context if it exists
|
|
// This allows Application-scoped policies to inject data into component/trait rendering
|
|
var customData map[string]interface{}
|
|
if data.Ctx != nil {
|
|
if val := data.Ctx.Value(policyAdditionalContextKeyString); val != nil {
|
|
if contextMap, ok := val.(map[string]interface{}); ok {
|
|
// Wrap additionalContext under "custom" key so it's accessible as context.custom
|
|
customData = map[string]interface{}{
|
|
"custom": contextMap,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
ctx := process.NewContext(process.ContextData{
|
|
Namespace: data.Namespace,
|
|
Name: data.CompName,
|
|
StepName: data.StepName,
|
|
WorkflowName: data.WorkflowName,
|
|
PublishVersion: data.PublishVersion,
|
|
Ctx: data.Ctx,
|
|
BaseHooks: data.BaseHooks,
|
|
AuxiliaryHooks: data.AuxiliaryHooks,
|
|
CustomData: customData,
|
|
})
|
|
ctx.PushData(ContextAppName, data.AppName)
|
|
ctx.PushData(ContextAppRevision, data.AppRevisionName)
|
|
ctx.PushData(ContextCompRevisionName, data.CompRevision)
|
|
ctx.PushData(ContextComponents, data.Components)
|
|
ctx.PushData(ContextAppLabels, data.AppLabels)
|
|
ctx.PushData(ContextAppAnnotations, data.AppAnnotations)
|
|
ctx.PushData(ContextAppComponents, data.AppComponents)
|
|
ctx.PushData(ContextAppWorkflow, data.AppWorkflow)
|
|
ctx.PushData(ContextAppPolicies, data.AppPolicies)
|
|
ctx.PushData(ContextReplicaKey, data.ReplicaKey)
|
|
revNum, _ := util.ExtractRevisionNum(data.AppRevisionName, "-")
|
|
ctx.PushData(ContextAppRevisionNum, revNum)
|
|
ctx.PushData(ContextCluster, data.Cluster)
|
|
ctx.PushData(ContextClusterVersion, parseClusterVersion(data.ClusterVersion))
|
|
if data.Output != nil {
|
|
ctx.PushData(OutputFieldName, data.Output)
|
|
}
|
|
return ctx
|
|
}
|
|
|
|
func parseClusterVersion(cv types.ClusterVersion) map[string]interface{} {
|
|
// no minor found, use control plane cluster version instead.
|
|
if cv.Minor == "" {
|
|
cv = types.ControlPlaneClusterVersion
|
|
}
|
|
minorS := strings.TrimSpace(cv.Minor)
|
|
minorS = strings.TrimRight(minorS, ".+-/?!")
|
|
minor, _ := strconv.ParseInt(minorS, 10, 64)
|
|
return map[string]interface{}{
|
|
"major": cv.Major,
|
|
"gitVersion": cv.GitVersion,
|
|
"platform": cv.Platform,
|
|
"minor": minor,
|
|
}
|
|
}
|