mirror of
https://github.com/kubevela/kubevela.git
synced 2026-03-02 09:40:51 +00:00
Compare commits
20 Commits
v1.4.0-alp
...
v1.3.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
825f1aaa22 | ||
|
|
82075427e6 | ||
|
|
f89cf673c0 | ||
|
|
ce53f6922f | ||
|
|
b6f70d9a3c | ||
|
|
64d063ccfe | ||
|
|
a98278fb7a | ||
|
|
0553d603e6 | ||
|
|
a36e99308f | ||
|
|
947bac2d35 | ||
|
|
7644cc59cb | ||
|
|
89a441b8ce | ||
|
|
780572c68f | ||
|
|
a13cab65b2 | ||
|
|
e26104adcc | ||
|
|
26ac584655 | ||
|
|
482976990d | ||
|
|
bc4812a12e | ||
|
|
58c2208e2a | ||
|
|
f83d88cfb0 |
38
.github/workflows/apiserver-test.yaml
vendored
38
.github/workflows/apiserver-test.yaml
vendored
@@ -6,9 +6,7 @@ on:
|
||||
- master
|
||||
- release-*
|
||||
- apiserver
|
||||
tags:
|
||||
- v*
|
||||
workflow_dispatch: { }
|
||||
workflow_dispatch: {}
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
@@ -20,8 +18,6 @@ env:
|
||||
GO_VERSION: '1.17'
|
||||
GOLANGCI_VERSION: 'v1.38'
|
||||
KIND_VERSION: 'v0.7.0'
|
||||
KIND_IMAGE_VERSION: '[\"v1.20.7\"]'
|
||||
KIND_IMAGE_VERSIONS: '[\"v1.18.20\",\"v1.20.7\",\"v1.22.7\"]'
|
||||
|
||||
jobs:
|
||||
|
||||
@@ -39,36 +35,10 @@ jobs:
|
||||
do_not_skip: '["workflow_dispatch", "schedule", "push"]'
|
||||
concurrent_skipping: false
|
||||
|
||||
set-k8s-matrix:
|
||||
runs-on: ubuntu-20.04
|
||||
outputs:
|
||||
matrix: ${{ steps.set-k8s-matrix.outputs.matrix }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: mukunku/tag-exists-action@v1.0.0
|
||||
id: checkTag
|
||||
with:
|
||||
tag: 'v1'
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- id: set-k8s-matrix
|
||||
run: |
|
||||
echo ${{ steps.checkTag.outputs.exists }}
|
||||
if [ "${{ steps.checkTag.outputs.exists }}" = "true" ]; then
|
||||
echo "::set-output name=matrix::${{ env.KIND_IMAGE_VERSIONS }}"
|
||||
else
|
||||
echo "::set-output name=matrix::${{ env.KIND_IMAGE_VERSION }}"
|
||||
fi
|
||||
|
||||
|
||||
apiserver-unit-tests:
|
||||
runs-on: aliyun
|
||||
needs: [ detect-noop,set-k8s-matrix ]
|
||||
needs: detect-noop
|
||||
if: needs.detect-noop.outputs.noop != 'true'
|
||||
strategy:
|
||||
matrix:
|
||||
k8s-version: ${{ fromJson(needs.set-k8s-matrix.outputs.matrix) }}
|
||||
|
||||
steps:
|
||||
- name: Set up Go
|
||||
@@ -95,7 +65,7 @@ jobs:
|
||||
- name: Setup Kind Cluster (Worker)
|
||||
run: |
|
||||
kind delete cluster --name worker
|
||||
kind create cluster --image kindest/node:${{ matrix.k8s-version }} --name worker
|
||||
kind create cluster --image kindest/node:v1.20.7@sha256:688fba5ce6b825be62a7c7fe1415b35da2bdfbb5a69227c499ea4cc0008661ca --name worker
|
||||
kubectl version
|
||||
kubectl cluster-info
|
||||
kind get kubeconfig --name worker --internal > /tmp/worker.kubeconfig
|
||||
@@ -104,7 +74,7 @@ jobs:
|
||||
- name: Setup Kind Cluster (Hub)
|
||||
run: |
|
||||
kind delete cluster
|
||||
kind create cluster --image kindest/node:${{ matrix.k8s-version }}
|
||||
kind create cluster --image kindest/node:v1.20.7@sha256:688fba5ce6b825be62a7c7fe1415b35da2bdfbb5a69227c499ea4cc0008661ca
|
||||
kubectl version
|
||||
kubectl cluster-info
|
||||
|
||||
|
||||
37
.github/workflows/e2e-multicluster-test.yml
vendored
37
.github/workflows/e2e-multicluster-test.yml
vendored
@@ -5,8 +5,6 @@ on:
|
||||
branches:
|
||||
- master
|
||||
- release-*
|
||||
tags:
|
||||
- v*
|
||||
workflow_dispatch: {}
|
||||
pull_request:
|
||||
branches:
|
||||
@@ -18,8 +16,6 @@ env:
|
||||
GO_VERSION: '1.17'
|
||||
GOLANGCI_VERSION: 'v1.38'
|
||||
KIND_VERSION: 'v0.7.0'
|
||||
KIND_IMAGE_VERSION: '[\"v1.20.7\"]'
|
||||
KIND_IMAGE_VERSIONS: '[\"v1.18.20\",\"v1.20.7\",\"v1.22.7\"]'
|
||||
|
||||
jobs:
|
||||
|
||||
@@ -37,37 +33,10 @@ jobs:
|
||||
do_not_skip: '["workflow_dispatch", "schedule", "push"]'
|
||||
concurrent_skipping: false
|
||||
|
||||
set-k8s-matrix:
|
||||
runs-on: ubuntu-20.04
|
||||
outputs:
|
||||
matrix: ${{ steps.set-k8s-matrix.outputs.matrix }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: mukunku/tag-exists-action@v1.0.0
|
||||
id: checkTag
|
||||
with:
|
||||
tag: 'v1'
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- id: set-k8s-matrix
|
||||
run: |
|
||||
echo ${{ steps.checkTag.outputs.exists }}
|
||||
if [ "${{ steps.checkTag.outputs.exists }}" = "true" ]; then
|
||||
echo "::set-output name=matrix::${{ env.KIND_IMAGE_VERSIONS }}"
|
||||
else
|
||||
echo "::set-output name=matrix::${{ env.KIND_IMAGE_VERSION }}"
|
||||
fi
|
||||
|
||||
|
||||
e2e-multi-cluster-tests:
|
||||
runs-on: aliyun
|
||||
needs: [ detect-noop,set-k8s-matrix ]
|
||||
needs: detect-noop
|
||||
if: needs.detect-noop.outputs.noop != 'true'
|
||||
strategy:
|
||||
matrix:
|
||||
k8s-version: ${{ fromJson(needs.set-k8s-matrix.outputs.matrix) }}
|
||||
|
||||
|
||||
steps:
|
||||
- name: Check out code into the Go module directory
|
||||
@@ -91,7 +60,7 @@ jobs:
|
||||
- name: Setup Kind Cluster (Worker)
|
||||
run: |
|
||||
kind delete cluster --name worker
|
||||
kind create cluster --image kindest/node:${{ matrix.k8s-version }} --name worker
|
||||
kind create cluster --image kindest/node:v1.20.7@sha256:688fba5ce6b825be62a7c7fe1415b35da2bdfbb5a69227c499ea4cc0008661ca --name worker
|
||||
kubectl version
|
||||
kubectl cluster-info
|
||||
kind get kubeconfig --name worker --internal > /tmp/worker.kubeconfig
|
||||
@@ -100,7 +69,7 @@ jobs:
|
||||
- name: Setup Kind Cluster (Hub)
|
||||
run: |
|
||||
kind delete cluster
|
||||
kind create cluster --image kindest/node:${{ matrix.k8s-version }}
|
||||
kind create cluster --image kindest/node:v1.20.7@sha256:688fba5ce6b825be62a7c7fe1415b35da2bdfbb5a69227c499ea4cc0008661ca
|
||||
kubectl version
|
||||
kubectl cluster-info
|
||||
|
||||
|
||||
33
.github/workflows/e2e-rollout-test.yml
vendored
33
.github/workflows/e2e-rollout-test.yml
vendored
@@ -5,8 +5,6 @@ on:
|
||||
branches:
|
||||
- master
|
||||
- release-*
|
||||
tags:
|
||||
- v*
|
||||
workflow_dispatch: {}
|
||||
pull_request:
|
||||
branches:
|
||||
@@ -18,8 +16,6 @@ env:
|
||||
GO_VERSION: '1.17'
|
||||
GOLANGCI_VERSION: 'v1.38'
|
||||
KIND_VERSION: 'v0.7.0'
|
||||
KIND_IMAGE_VERSION: '[\"v1.20.7\"]'
|
||||
KIND_IMAGE_VERSIONS: '[\"v1.18.20\",\"v1.20.7\",\"v1.22.7\"]'
|
||||
|
||||
jobs:
|
||||
|
||||
@@ -37,35 +33,10 @@ jobs:
|
||||
do_not_skip: '["workflow_dispatch", "schedule", "push"]'
|
||||
concurrent_skipping: false
|
||||
|
||||
set-k8s-matrix:
|
||||
runs-on: ubuntu-20.04
|
||||
outputs:
|
||||
matrix: ${{ steps.set-k8s-matrix.outputs.matrix }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: mukunku/tag-exists-action@v1.0.0
|
||||
id: checkTag
|
||||
with:
|
||||
tag: 'v1'
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- id: set-k8s-matrix
|
||||
run: |
|
||||
echo ${{ steps.checkTag.outputs.exists }}
|
||||
if [ "${{ steps.checkTag.outputs.exists }}" = "true" ]; then
|
||||
echo "::set-output name=matrix::${{ env.KIND_IMAGE_VERSIONS }}"
|
||||
else
|
||||
echo "::set-output name=matrix::${{ env.KIND_IMAGE_VERSION }}"
|
||||
fi
|
||||
|
||||
e2e-rollout-tests:
|
||||
runs-on: aliyun
|
||||
needs: [ detect-noop,set-k8s-matrix ]
|
||||
needs: detect-noop
|
||||
if: needs.detect-noop.outputs.noop != 'true'
|
||||
strategy:
|
||||
matrix:
|
||||
k8s-version: ${{ fromJson(needs.set-k8s-matrix.outputs.matrix) }}
|
||||
|
||||
steps:
|
||||
- name: Check out code into the Go module directory
|
||||
@@ -89,7 +60,7 @@ jobs:
|
||||
- name: Setup Kind Cluster
|
||||
run: |
|
||||
kind delete cluster
|
||||
kind create cluster --image kindest/node:${{ matrix.k8s-version }}
|
||||
kind create cluster --image kindest/node:v1.20.7@sha256:688fba5ce6b825be62a7c7fe1415b35da2bdfbb5a69227c499ea4cc0008661ca
|
||||
kubectl version
|
||||
kubectl cluster-info
|
||||
|
||||
|
||||
33
.github/workflows/e2e-test.yml
vendored
33
.github/workflows/e2e-test.yml
vendored
@@ -5,8 +5,6 @@ on:
|
||||
branches:
|
||||
- master
|
||||
- release-*
|
||||
tags:
|
||||
- v*
|
||||
workflow_dispatch: {}
|
||||
pull_request:
|
||||
branches:
|
||||
@@ -18,8 +16,6 @@ env:
|
||||
GO_VERSION: '1.17'
|
||||
GOLANGCI_VERSION: 'v1.38'
|
||||
KIND_VERSION: 'v0.7.0'
|
||||
KIND_IMAGE_VERSION: '[\"v1.20.7\"]'
|
||||
KIND_IMAGE_VERSIONS: '[\"v1.18.20\",\"v1.20.7\",\"v1.22.7\"]'
|
||||
|
||||
jobs:
|
||||
|
||||
@@ -37,35 +33,10 @@ jobs:
|
||||
do_not_skip: '["workflow_dispatch", "schedule", "push"]'
|
||||
concurrent_skipping: false
|
||||
|
||||
set-k8s-matrix:
|
||||
runs-on: ubuntu-20.04
|
||||
outputs:
|
||||
matrix: ${{ steps.set-k8s-matrix.outputs.matrix }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: mukunku/tag-exists-action@v1.0.0
|
||||
id: checkTag
|
||||
with:
|
||||
tag: 'v1'
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- id: set-k8s-matrix
|
||||
run: |
|
||||
echo ${{ steps.checkTag.outputs.exists }}
|
||||
if [ "${{ steps.checkTag.outputs.exists }}" = "true" ]; then
|
||||
echo "::set-output name=matrix::${{ env.KIND_IMAGE_VERSIONS }}"
|
||||
else
|
||||
echo "::set-output name=matrix::${{ env.KIND_IMAGE_VERSION }}"
|
||||
fi
|
||||
|
||||
e2e-tests:
|
||||
runs-on: aliyun
|
||||
needs: [ detect-noop,set-k8s-matrix ]
|
||||
needs: detect-noop
|
||||
if: needs.detect-noop.outputs.noop != 'true'
|
||||
strategy:
|
||||
matrix:
|
||||
k8s-version: ${{ fromJson(needs.set-k8s-matrix.outputs.matrix) }}
|
||||
|
||||
steps:
|
||||
- name: Check out code into the Go module directory
|
||||
@@ -89,7 +60,7 @@ jobs:
|
||||
- name: Setup Kind Cluster
|
||||
run: |
|
||||
kind delete cluster
|
||||
kind create cluster --image kindest/node:${{ matrix.k8s-version }}
|
||||
kind create cluster --image kindest/node:v1.20.7@sha256:688fba5ce6b825be62a7c7fe1415b35da2bdfbb5a69227c499ea4cc0008661ca
|
||||
kubectl version
|
||||
kubectl cluster-info
|
||||
|
||||
|
||||
2
.github/workflows/go.yml
vendored
2
.github/workflows/go.yml
vendored
@@ -57,7 +57,7 @@ jobs:
|
||||
restore-keys: ${{ runner.os }}-pkg-
|
||||
|
||||
- name: Install StaticCheck
|
||||
run: GO111MODULE=on go get honnef.co/go/tools/cmd/staticcheck@v0.3.0
|
||||
run: GO111MODULE=off go get honnef.co/go/tools/cmd/staticcheck
|
||||
|
||||
- name: Static Check
|
||||
run: staticcheck ./...
|
||||
|
||||
4
.github/workflows/unit-test.yml
vendored
4
.github/workflows/unit-test.yml
vendored
@@ -58,7 +58,7 @@ jobs:
|
||||
restore-keys: ${{ runner.os }}-pkg-
|
||||
|
||||
- name: Install ginkgo
|
||||
run: |
|
||||
run: |
|
||||
sudo apt-get install -y golang-ginkgo-dev
|
||||
|
||||
- name: Setup Kind Cluster
|
||||
@@ -72,7 +72,7 @@ jobs:
|
||||
version: 3.1.0
|
||||
kubebuilderOnly: false
|
||||
kubernetesVersion: v1.21.2
|
||||
|
||||
|
||||
- name: Run Make test
|
||||
run: make test
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ Reviewers:
|
||||
- devholic
|
||||
- fourierr
|
||||
- JooKS-me
|
||||
- s4rd1nh4
|
||||
|
||||
Approvers:
|
||||
- Somefive (Multi-Cluster)
|
||||
|
||||
@@ -45,7 +45,7 @@ Full documentation is available on the [KubeVela website](https://kubevela.io/).
|
||||
|
||||
## Community
|
||||
|
||||
- Slack: [CNCF Slack kubevela channel](https://cloud-native.slack.com/archives/C01BLQ3HTJA) (*English*)
|
||||
- Slack: [CNCF Slack](https://slack.cncf.io/) #kubevela channel (*English*)
|
||||
- Gitter: [oam-dev](https://gitter.im/oam-dev/community) (*English*)
|
||||
- [DingTalk Group](https://page.dingtalk.com/wow/dingtalk/act/en-home): `23310022` (*Chinese*)
|
||||
- Wechat Group (*Chinese*): Broker wechat to add you into the user group.
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
/*
|
||||
Copyright 2022 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 common
|
||||
|
||||
const (
|
||||
// Group api group name
|
||||
Group = "core.oam.dev"
|
||||
)
|
||||
@@ -345,8 +345,6 @@ type WorkflowStatus struct {
|
||||
Mode WorkflowMode `json:"mode"`
|
||||
Message string `json:"message,omitempty"`
|
||||
|
||||
SuspendState string `json:"suspendState,omitempty"`
|
||||
|
||||
Suspend bool `json:"suspend"`
|
||||
Terminated bool `json:"terminated"`
|
||||
Finished bool `json:"finished"`
|
||||
@@ -498,8 +496,6 @@ const (
|
||||
PolicyResourceCreator ResourceCreatorRole = "policy"
|
||||
// WorkflowResourceCreator create the resource in workflow.
|
||||
WorkflowResourceCreator ResourceCreatorRole = "workflow"
|
||||
// DebugResourceCreator create the debug resource.
|
||||
DebugResourceCreator ResourceCreatorRole = "debug"
|
||||
)
|
||||
|
||||
// OAMObjectReference defines the object reference for an oam resource
|
||||
|
||||
@@ -33,22 +33,11 @@ type GarbageCollectPolicySpec struct {
|
||||
// outdated resources will be kept until resourcetracker be deleted manually
|
||||
KeepLegacyResource bool `json:"keepLegacyResource,omitempty"`
|
||||
|
||||
// Order defines the order of garbage collect
|
||||
Order GarbageCollectOrder `json:"order,omitempty"`
|
||||
|
||||
// Rules defines list of rules to control gc strategy at resource level
|
||||
// if one resource is controlled by multiple rules, first rule will be used
|
||||
Rules []GarbageCollectPolicyRule `json:"rules,omitempty"`
|
||||
}
|
||||
|
||||
// GarbageCollectOrder is the order of garbage collect
|
||||
type GarbageCollectOrder string
|
||||
|
||||
const (
|
||||
// OrderDependency is the order of dependency
|
||||
OrderDependency GarbageCollectOrder = "dependency"
|
||||
)
|
||||
|
||||
// GarbageCollectPolicyRule defines a single garbage-collect policy rule
|
||||
type GarbageCollectPolicyRule struct {
|
||||
Selector GarbageCollectPolicyRuleSelector `json:"selector"`
|
||||
@@ -56,13 +45,12 @@ type GarbageCollectPolicyRule struct {
|
||||
}
|
||||
|
||||
// GarbageCollectPolicyRuleSelector select the targets of the rule
|
||||
// if both traitTypes, oamTypes and componentTypes are specified, combination logic is OR
|
||||
// if both traitTypes and componentTypes are specified, combination logic is OR
|
||||
// if one resource is specified with conflict strategies, strategy as component go first.
|
||||
type GarbageCollectPolicyRuleSelector struct {
|
||||
CompNames []string `json:"componentNames"`
|
||||
CompTypes []string `json:"componentTypes"`
|
||||
OAMResourceTypes []string `json:"oamTypes"`
|
||||
TraitTypes []string `json:"traitTypes"`
|
||||
CompNames []string `json:"componentNames"`
|
||||
CompTypes []string `json:"componentTypes"`
|
||||
TraitTypes []string `json:"traitTypes"`
|
||||
}
|
||||
|
||||
// GarbageCollectStrategy the strategy for target resource to recycle
|
||||
@@ -81,11 +69,10 @@ const (
|
||||
// FindStrategy find gc strategy for target resource
|
||||
func (in GarbageCollectPolicySpec) FindStrategy(manifest *unstructured.Unstructured) *GarbageCollectStrategy {
|
||||
for _, rule := range in.Rules {
|
||||
var compName, compType, oamType, traitType string
|
||||
var compName, compType, traitType string
|
||||
if labels := manifest.GetLabels(); labels != nil {
|
||||
compName = labels[oam.LabelAppComponent]
|
||||
compType = labels[oam.WorkloadTypeLabel]
|
||||
oamType = labels[oam.LabelOAMResourceType]
|
||||
traitType = labels[oam.TraitTypeLabel]
|
||||
}
|
||||
match := func(src []string, val string) (found bool) {
|
||||
@@ -96,7 +83,6 @@ func (in GarbageCollectPolicySpec) FindStrategy(manifest *unstructured.Unstructu
|
||||
}
|
||||
if match(rule.Selector.CompNames, compName) ||
|
||||
match(rule.Selector.CompTypes, compType) ||
|
||||
match(rule.Selector.OAMResourceTypes, oamType) ||
|
||||
match(rule.Selector.TraitTypes, traitType) {
|
||||
return &rule.Strategy
|
||||
}
|
||||
|
||||
@@ -109,18 +109,6 @@ func TestGarbageCollectPolicySpec_FindStrategy(t *testing.T) {
|
||||
}},
|
||||
expectStrategy: GarbageCollectStrategyNever,
|
||||
},
|
||||
"resource type rule match": {
|
||||
rules: []GarbageCollectPolicyRule{{
|
||||
Selector: GarbageCollectPolicyRuleSelector{OAMResourceTypes: []string{"TRAIT"}},
|
||||
Strategy: GarbageCollectStrategyNever,
|
||||
}},
|
||||
input: &unstructured.Unstructured{Object: map[string]interface{}{
|
||||
"metadata": map[string]interface{}{
|
||||
"labels": map[string]interface{}{oam.LabelOAMResourceType: "TRAIT"},
|
||||
},
|
||||
}},
|
||||
expectStrategy: GarbageCollectStrategyNever,
|
||||
},
|
||||
}
|
||||
for name, tc := range testCases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
|
||||
@@ -21,8 +21,6 @@ const (
|
||||
TopologyPolicyType = "topology"
|
||||
// OverridePolicyType refers to the type of override policy
|
||||
OverridePolicyType = "override"
|
||||
// DebugPolicyType refers to the type of debug policy
|
||||
DebugPolicyType = "debug"
|
||||
)
|
||||
|
||||
// TopologyPolicySpec defines the spec of topology policy
|
||||
|
||||
@@ -19,13 +19,11 @@ package v1alpha1
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"sigs.k8s.io/controller-runtime/pkg/scheme"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
|
||||
)
|
||||
|
||||
// Package type metadata.
|
||||
const (
|
||||
Group = common.Group
|
||||
Group = "core.oam.dev"
|
||||
Version = "v1alpha1"
|
||||
)
|
||||
|
||||
|
||||
@@ -291,11 +291,6 @@ func (in *GarbageCollectPolicyRuleSelector) DeepCopyInto(out *GarbageCollectPoli
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.OAMResourceTypes != nil {
|
||||
in, out := &in.OAMResourceTypes, &out.OAMResourceTypes
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.TraitTypes != nil {
|
||||
in, out := &in.TraitTypes, &out.TraitTypes
|
||||
*out = make([]string, len(*in))
|
||||
|
||||
@@ -21,13 +21,11 @@ import (
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"sigs.k8s.io/controller-runtime/pkg/scheme"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
|
||||
)
|
||||
|
||||
// Package type metadata.
|
||||
const (
|
||||
Group = common.Group
|
||||
Group = "core.oam.dev"
|
||||
Version = "v1alpha2"
|
||||
)
|
||||
|
||||
|
||||
@@ -43,9 +43,6 @@ type PolicyDefinitionStatus struct {
|
||||
// ConditionedStatus reflects the observed status of a resource
|
||||
condition.ConditionedStatus `json:",inline"`
|
||||
|
||||
// ConfigMapRef refer to a ConfigMap which contains OpenAPI V3 JSON schema of Component parameters.
|
||||
ConfigMapRef string `json:"configMapRef,omitempty"`
|
||||
|
||||
// LatestRevision of the component definition
|
||||
// +optional
|
||||
LatestRevision *common.Revision `json:"latestRevision,omitempty"`
|
||||
|
||||
@@ -21,13 +21,11 @@ import (
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"sigs.k8s.io/controller-runtime/pkg/scheme"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
|
||||
)
|
||||
|
||||
// Package type metadata.
|
||||
const (
|
||||
Group = common.Group
|
||||
Group = "core.oam.dev"
|
||||
Version = "v1beta1"
|
||||
)
|
||||
|
||||
|
||||
@@ -31,7 +31,6 @@ import (
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
|
||||
"github.com/oam-dev/kubevela/apis/interfaces"
|
||||
velatypes "github.com/oam-dev/kubevela/apis/types"
|
||||
"github.com/oam-dev/kubevela/pkg/oam"
|
||||
"github.com/oam-dev/kubevela/pkg/utils/errors"
|
||||
)
|
||||
@@ -122,11 +121,7 @@ func (in ManagedResource) NamespacedName() types.NamespacedName {
|
||||
// ResourceKey computes the key for managed resource, resources with the same key points to the same resource
|
||||
func (in ManagedResource) ResourceKey() string {
|
||||
gv, kind := in.GroupVersionKind().ToAPIVersionAndKind()
|
||||
cluster := in.Cluster
|
||||
if cluster == "" {
|
||||
cluster = velatypes.ClusterLocalName
|
||||
}
|
||||
return strings.Join([]string{gv, kind, cluster, in.Namespace, in.Name}, "/")
|
||||
return strings.Join([]string{gv, kind, in.Cluster, in.Namespace, in.Name}, "/")
|
||||
}
|
||||
|
||||
// ComponentKey computes the key for the component which managed resource belongs to
|
||||
@@ -192,7 +187,7 @@ func (in *ResourceTracker) findMangedResourceIndex(mr ManagedResource) int {
|
||||
}
|
||||
|
||||
// AddManagedResource add object to managed resources, if exists, update
|
||||
func (in *ResourceTracker) AddManagedResource(rsc client.Object, metaOnly bool, creator common.ResourceCreatorRole) (updated bool) {
|
||||
func (in *ResourceTracker) AddManagedResource(rsc client.Object, metaOnly bool) (updated bool) {
|
||||
gvk := rsc.GetObjectKind().GroupVersionKind()
|
||||
mr := ManagedResource{
|
||||
ClusterObjectReference: common.ClusterObjectReference{
|
||||
@@ -210,9 +205,6 @@ func (in *ResourceTracker) AddManagedResource(rsc client.Object, metaOnly bool,
|
||||
if !metaOnly {
|
||||
mr.Data = &runtime.RawExtension{Object: rsc}
|
||||
}
|
||||
if creator != "" {
|
||||
mr.ClusterObjectReference.Creator = creator
|
||||
}
|
||||
if idx := in.findMangedResourceIndex(mr); idx >= 0 {
|
||||
if reflect.DeepEqual(in.Spec.ManagedResources[idx], mr) {
|
||||
return false
|
||||
|
||||
@@ -156,16 +156,16 @@ func TestResourceTracker_ManagedResource(t *testing.T) {
|
||||
r := require.New(t)
|
||||
input := &ResourceTracker{}
|
||||
deploy1 := v12.Deployment{ObjectMeta: v13.ObjectMeta{Name: "deploy1"}}
|
||||
input.AddManagedResource(&deploy1, true, "")
|
||||
input.AddManagedResource(&deploy1, true)
|
||||
r.Equal(1, len(input.Spec.ManagedResources))
|
||||
cm2 := v1.ConfigMap{ObjectMeta: v13.ObjectMeta{Name: "cm2"}}
|
||||
input.AddManagedResource(&cm2, false, "")
|
||||
input.AddManagedResource(&cm2, false)
|
||||
r.Equal(2, len(input.Spec.ManagedResources))
|
||||
pod3 := v1.Pod{ObjectMeta: v13.ObjectMeta{Name: "pod3"}}
|
||||
input.AddManagedResource(&pod3, false, "")
|
||||
input.AddManagedResource(&pod3, false)
|
||||
r.Equal(3, len(input.Spec.ManagedResources))
|
||||
deploy1.Spec.Replicas = pointer.Int32(5)
|
||||
input.AddManagedResource(&deploy1, false, "")
|
||||
input.AddManagedResource(&deploy1, false)
|
||||
r.Equal(3, len(input.Spec.ManagedResources))
|
||||
input.DeleteManagedResource(&cm2, false)
|
||||
r.Equal(3, len(input.Spec.ManagedResources))
|
||||
|
||||
@@ -22,9 +22,6 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
// ClusterLocalName the name for the hub cluster
|
||||
ClusterLocalName = "local"
|
||||
|
||||
// CredentialTypeInternal identifies the virtual cluster from internal kubevela system
|
||||
CredentialTypeInternal v1alpha1.CredentialType = "Internal"
|
||||
// CredentialTypeOCMManagedCluster identifies the virtual cluster from ocm
|
||||
|
||||
@@ -18,13 +18,6 @@ package types
|
||||
|
||||
import "github.com/oam-dev/kubevela/pkg/oam"
|
||||
|
||||
const (
|
||||
// KubeVelaName name of kubevela
|
||||
KubeVelaName = "kubevela"
|
||||
// VelaCoreName name of vela-core
|
||||
VelaCoreName = "vela-core"
|
||||
)
|
||||
|
||||
const (
|
||||
// DefaultKubeVelaReleaseName defines the default name of KubeVela Release
|
||||
DefaultKubeVelaReleaseName = "kubevela"
|
||||
@@ -80,8 +73,8 @@ const (
|
||||
LabelConfigSyncToMultiCluster = "config.oam.dev/multi-cluster"
|
||||
// LabelConfigIdentifier is the label for config identifier
|
||||
LabelConfigIdentifier = "config.oam.dev/identifier"
|
||||
// AnnotationConfigDescription is the annotation for config description
|
||||
AnnotationConfigDescription = "config.oam.dev/description"
|
||||
// LabelConfigDescription is the label for config description
|
||||
LabelConfigDescription = "config.oam.dev/description"
|
||||
// AnnotationConfigAlias is the annotation for config alias
|
||||
AnnotationConfigAlias = "config.oam.dev/alias"
|
||||
)
|
||||
@@ -155,13 +148,3 @@ const (
|
||||
// HelmRepository is the config type for Helm chart repository
|
||||
HelmRepository = "config-helm-repository"
|
||||
)
|
||||
|
||||
const (
|
||||
// TerrfaormComponentPrefix is the prefix of component type of terraform-xxx
|
||||
TerrfaormComponentPrefix = "terraform-"
|
||||
)
|
||||
|
||||
const (
|
||||
// ClusterGatewayAccessorGroup the group to impersonate which allows the access to the cluster-gateway
|
||||
ClusterGatewayAccessorGroup = "cluster-gateway-accessor"
|
||||
)
|
||||
|
||||
@@ -78,22 +78,6 @@ helm install --create-namespace -n vela-system kubevela kubevela/vela-core --wai
|
||||
| `healthCheck.port` | KubeVela health check port | `9440` |
|
||||
|
||||
|
||||
### KubeVela controller optimization parameters
|
||||
|
||||
| Name | Description | Value |
|
||||
| ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
|
||||
| `optimize.optimizeCachedGvks` | Optimize types of resources to be cached. | `nil` |
|
||||
| `optimize.resourceTrackerListOp` | Optimize ResourceTracker List Op by adding index. | `true` |
|
||||
| `optimize.controllerReconcileLoopReduction` | Optimize ApplicationController reconcile by reducing the number of loops to reconcile application. | `false` |
|
||||
| `optimize.markWithProb` | Optimize ResourceTracker GC by only run mark with probability. Side effect: outdated ResourceTracker might not be able to be removed immediately. | `0.1` |
|
||||
| `optimize.disableComponentRevision` | Optimize componentRevision by disabling the creation and gc | `false` |
|
||||
| `optimize.disableApplicationRevision` | Optimize ApplicationRevision by disabling the creation and gc. | `false` |
|
||||
| `optimize.disableWorkflowRecorder` | Optimize workflow recorder by disabling the creation and gc. | `false` |
|
||||
| `optimize.enableInMemoryWorkflowContext` | Optimize workflow by use in-memory context. | `false` |
|
||||
| `optimize.disableResourceApplyDoubleCheck` | Optimize workflow by ignoring resource double check after apply. | `false` |
|
||||
| `optimize.enableResourceTrackerDeleteOnlyTrigger` | Optimize resourcetracker by only trigger reconcile when resourcetracker is deleted. | `true` |
|
||||
|
||||
|
||||
### MultiCluster parameters
|
||||
|
||||
| Name | Description | Value |
|
||||
@@ -122,27 +106,23 @@ helm install --create-namespace -n vela-system kubevela kubevela/vela-core --wai
|
||||
|
||||
### Common parameters
|
||||
|
||||
| Name | Description | Value |
|
||||
| ----------------------------- | -------------------------------------------------------------------------------------------------------------------------- | -------------------- |
|
||||
| `imagePullSecrets` | Image pull secrets | `[]` |
|
||||
| `nameOverride` | Override name | `""` |
|
||||
| `fullnameOverride` | Fullname override | `""` |
|
||||
| `serviceAccount.create` | Specifies whether a service account should be created | `true` |
|
||||
| `serviceAccount.annotations` | Annotations to add to the service account | `{}` |
|
||||
| `serviceAccount.name` | The name of the service account to use. If not set and create is true, a name is generated using the fullname template | `nil` |
|
||||
| `nodeSelector` | Node selector | `{}` |
|
||||
| `tolerations` | Tolerations | `[]` |
|
||||
| `affinity` | Affinity | `{}` |
|
||||
| `rbac.create` | Specifies whether a RBAC role should be created | `true` |
|
||||
| `logDebug` | Enable debug logs for development purpose | `false` |
|
||||
| `logFilePath` | If non-empty, write log files in this path | `""` |
|
||||
| `logFileMaxSize` | Defines the maximum size a log file can grow to. Unit is megabytes. If the value is 0, the maximum file size is unlimited. | `1024` |
|
||||
| `kubeClient.qps` | The qps for reconcile clients, default is 50 | `50` |
|
||||
| `kubeClient.burst` | The burst for reconcile clients, default is 100 | `100` |
|
||||
| `authentication.enabled` | Enable authentication for application | `false` |
|
||||
| `authentication.withUser` | Application authentication will impersonate as the request User | `false` |
|
||||
| `authentication.defaultUser` | Application authentication will impersonate as the User if no user provided in Application | `kubevela:vela-core` |
|
||||
| `authentication.groupPattern` | Application authentication will impersonate as the request Group that matches the pattern | `kubevela:*` |
|
||||
| Name | Description | Value |
|
||||
| ---------------------------- | -------------------------------------------------------------------------------------------------------------------------- | ------- |
|
||||
| `imagePullSecrets` | Image pull secrets | `[]` |
|
||||
| `nameOverride` | Override name | `""` |
|
||||
| `fullnameOverride` | Fullname override | `""` |
|
||||
| `serviceAccount.create` | Specifies whether a service account should be created | `true` |
|
||||
| `serviceAccount.annotations` | Annotations to add to the service account | `{}` |
|
||||
| `serviceAccount.name` | The name of the service account to use. If not set and create is true, a name is generated using the fullname template | `nil` |
|
||||
| `nodeSelector` | Node selector | `{}` |
|
||||
| `tolerations` | Tolerations | `[]` |
|
||||
| `affinity` | Affinity | `{}` |
|
||||
| `rbac.create` | Specifies whether a RBAC role should be created | `true` |
|
||||
| `logDebug` | Enable debug logs for development purpose | `false` |
|
||||
| `logFilePath` | If non-empty, write log files in this path | `""` |
|
||||
| `logFileMaxSize` | Defines the maximum size a log file can grow to. Unit is megabytes. If the value is 0, the maximum file size is unlimited. | `1024` |
|
||||
| `kubeClient.qps` | The qps for reconcile clients, default is 50 | `50` |
|
||||
| `kubeClient.burst` | The burst for reconcile clients, default is 100 | `100` |
|
||||
|
||||
|
||||
## Uninstallation
|
||||
@@ -184,4 +164,10 @@ To uninstall the KubeVela helm release:
|
||||
$ helm uninstall -n vela-system kubevela
|
||||
```
|
||||
|
||||
Finally, this command will remove all the Kubernetes resources associated with KubeVela and remove this chart release.
|
||||
Finally, this command will remove all the Kubernetes resources associated with KubeVela and remove this chart release.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -934,8 +934,6 @@ spec:
|
||||
type: array
|
||||
suspend:
|
||||
type: boolean
|
||||
suspendState:
|
||||
type: string
|
||||
terminated:
|
||||
type: boolean
|
||||
required:
|
||||
@@ -2745,8 +2743,6 @@ spec:
|
||||
type: array
|
||||
suspend:
|
||||
type: boolean
|
||||
suspendState:
|
||||
type: string
|
||||
terminated:
|
||||
type: boolean
|
||||
required:
|
||||
@@ -3390,10 +3386,6 @@ spec:
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
configMapRef:
|
||||
description: ConfigMapRef refer to a ConfigMap which contains
|
||||
OpenAPI V3 JSON schema of Component parameters.
|
||||
type: string
|
||||
latestRevision:
|
||||
description: LatestRevision of the component definition
|
||||
properties:
|
||||
@@ -4690,8 +4682,6 @@ spec:
|
||||
type: array
|
||||
suspend:
|
||||
type: boolean
|
||||
suspendState:
|
||||
type: string
|
||||
terminated:
|
||||
type: boolean
|
||||
required:
|
||||
|
||||
@@ -643,8 +643,6 @@ spec:
|
||||
type: array
|
||||
suspend:
|
||||
type: boolean
|
||||
suspendState:
|
||||
type: string
|
||||
terminated:
|
||||
type: boolean
|
||||
required:
|
||||
@@ -1148,8 +1146,6 @@ spec:
|
||||
type: array
|
||||
suspend:
|
||||
type: boolean
|
||||
suspendState:
|
||||
type: string
|
||||
terminated:
|
||||
type: boolean
|
||||
required:
|
||||
|
||||
@@ -636,10 +636,6 @@ spec:
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
configMapRef:
|
||||
description: ConfigMapRef refer to a ConfigMap which contains
|
||||
OpenAPI V3 JSON schema of Component parameters.
|
||||
type: string
|
||||
latestRevision:
|
||||
description: LatestRevision of the component definition
|
||||
properties:
|
||||
|
||||
@@ -244,10 +244,6 @@ spec:
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
configMapRef:
|
||||
description: ConfigMapRef refer to a ConfigMap which contains OpenAPI
|
||||
V3 JSON schema of Component parameters.
|
||||
type: string
|
||||
latestRevision:
|
||||
description: LatestRevision of the component definition
|
||||
properties:
|
||||
|
||||
@@ -120,32 +120,6 @@ webhooks:
|
||||
- UPDATE
|
||||
resources:
|
||||
- podspecworkloads
|
||||
- clientConfig:
|
||||
caBundle: Cg==
|
||||
service:
|
||||
name: {{ template "kubevela.name" . }}-webhook
|
||||
namespace: {{ .Release.Namespace }}
|
||||
path: /mutating-core-oam-dev-v1beta1-applications
|
||||
{{- if .Values.admissionWebhooks.patch.enabled }}
|
||||
failurePolicy: Ignore
|
||||
{{- else }}
|
||||
failurePolicy: Fail
|
||||
{{- end }}
|
||||
name: mutating.core.oam.dev.v1beta1.applications
|
||||
admissionReviewVersions:
|
||||
- v1beta1
|
||||
- v1
|
||||
sideEffects: None
|
||||
rules:
|
||||
- apiGroups:
|
||||
- core.oam.dev
|
||||
apiVersions:
|
||||
- v1beta1
|
||||
operations:
|
||||
- CREATE
|
||||
- UPDATE
|
||||
resources:
|
||||
- applications
|
||||
- clientConfig:
|
||||
caBundle: Cg==
|
||||
service:
|
||||
|
||||
@@ -274,30 +274,4 @@ spec:
|
||||
runAsGroup: 2000
|
||||
runAsNonRoot: true
|
||||
runAsUser: 2000
|
||||
{{ end }}
|
||||
---
|
||||
{{ if and .Values.multicluster.enabled }}
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: {{ include "kubevela.fullname" . }}:cluster-gateway-access-role
|
||||
rules:
|
||||
- apiGroups: [ "cluster.core.oam.dev" ]
|
||||
resources: [ "clustergateways/proxy" ]
|
||||
verbs: [ "get", "list", "watch", "create", "update", "patch", "delete" ]
|
||||
{{ end }}
|
||||
---
|
||||
{{ if and .Values.multicluster.enabled }}
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: {{ include "kubevela.fullname" . }}:cluster-gateway-access-rolebinding
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: {{ include "kubevela.fullname" . }}:cluster-gateway-access-role
|
||||
subjects:
|
||||
- kind: Group
|
||||
name: cluster-gateway-accessor
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
{{ end }}
|
||||
@@ -10,7 +10,6 @@ metadata:
|
||||
custom.definition.oam.dev/catalog.config.oam.dev: velacore-config
|
||||
custom.definition.oam.dev/multi-cluster.config.oam.dev: "true"
|
||||
custom.definition.oam.dev/type.config.oam.dev: image-registry
|
||||
custom.definition.oam.dev/ui-hidden: "true"
|
||||
name: config-image-registry
|
||||
namespace: {{ include "systemDefinitionNamespace" . }}
|
||||
spec:
|
||||
|
||||
@@ -35,9 +35,6 @@ spec:
|
||||
if parameter.args != _|_ {
|
||||
args: parameter.args
|
||||
}
|
||||
if parameter["env"] != _|_ {
|
||||
env: parameter.env
|
||||
}
|
||||
|
||||
// +patchKey=name
|
||||
volumeMounts: [{
|
||||
@@ -64,31 +61,6 @@ spec:
|
||||
// +usage=Specify the args run in the init container
|
||||
args?: [...string]
|
||||
|
||||
// +usage=Specify the env run in the init container
|
||||
env?: [...{
|
||||
// +usage=Environment variable name
|
||||
name: string
|
||||
// +usage=The value of the environment variable
|
||||
value?: string
|
||||
// +usage=Specifies a source the value of this var should come from
|
||||
valueFrom?: {
|
||||
// +usage=Selects a key of a secret in the pod's namespace
|
||||
secretKeyRef?: {
|
||||
// +usage=The name of the secret in the pod's namespace to select from
|
||||
name: string
|
||||
// +usage=The key of the secret to select from. Must be a valid secret key
|
||||
key: string
|
||||
}
|
||||
// +usage=Selects a key of a config map in the pod's namespace
|
||||
configMapKeyRef?: {
|
||||
// +usage=The name of the config map in the pod's namespace to select from
|
||||
name: string
|
||||
// +usage=The key of the config map to select from. Must be a valid secret key
|
||||
key: string
|
||||
}
|
||||
}
|
||||
}]
|
||||
|
||||
// +usage=Specify the mount name of shared volume
|
||||
mountName: *"workdir" | string
|
||||
|
||||
|
||||
@@ -27,9 +27,6 @@ spec:
|
||||
if parameter.args != _|_ {
|
||||
args: parameter.args
|
||||
}
|
||||
if parameter["env"] != _|_ {
|
||||
env: parameter.env
|
||||
}
|
||||
if parameter["volumes"] != _|_ {
|
||||
volumeMounts: [ for v in parameter.volumes {
|
||||
{
|
||||
@@ -38,13 +35,6 @@ spec:
|
||||
}
|
||||
}]
|
||||
}
|
||||
if parameter["livenessProbe"] != _|_ {
|
||||
livenessProbe: parameter.livenessProbe
|
||||
}
|
||||
|
||||
if parameter["readinessProbe"] != _|_ {
|
||||
readinessProbe: parameter.readinessProbe
|
||||
}
|
||||
}]
|
||||
}
|
||||
parameter: {
|
||||
@@ -60,82 +50,10 @@ spec:
|
||||
// +usage=Specify the args in the sidecar
|
||||
args?: [...string]
|
||||
|
||||
// +usage=Specify the env in the sidecar
|
||||
env?: [...{
|
||||
// +usage=Environment variable name
|
||||
name: string
|
||||
// +usage=The value of the environment variable
|
||||
value?: string
|
||||
// +usage=Specifies a source the value of this var should come from
|
||||
valueFrom?: {
|
||||
// +usage=Selects a key of a secret in the pod's namespace
|
||||
secretKeyRef?: {
|
||||
// +usage=The name of the secret in the pod's namespace to select from
|
||||
name: string
|
||||
// +usage=The key of the secret to select from. Must be a valid secret key
|
||||
key: string
|
||||
}
|
||||
// +usage=Selects a key of a config map in the pod's namespace
|
||||
configMapKeyRef?: {
|
||||
// +usage=The name of the config map in the pod's namespace to select from
|
||||
name: string
|
||||
// +usage=The key of the config map to select from. Must be a valid secret key
|
||||
key: string
|
||||
}
|
||||
}
|
||||
}]
|
||||
|
||||
// +usage=Specify the shared volume path
|
||||
volumes?: [...{
|
||||
name: string
|
||||
path: string
|
||||
}]
|
||||
|
||||
// +usage=Instructions for assessing whether the container is alive.
|
||||
livenessProbe?: #HealthProbe
|
||||
|
||||
// +usage=Instructions for assessing whether the container is in a suitable state to serve traffic.
|
||||
readinessProbe?: #HealthProbe
|
||||
}
|
||||
#HealthProbe: {
|
||||
|
||||
// +usage=Instructions for assessing container health by executing a command. Either this attribute or the httpGet attribute or the tcpSocket attribute MUST be specified. This attribute is mutually exclusive with both the httpGet attribute and the tcpSocket attribute.
|
||||
exec?: {
|
||||
// +usage=A command to be executed inside the container to assess its health. Each space delimited token of the command is a separate array element. Commands exiting 0 are considered to be successful probes, whilst all other exit codes are considered failures.
|
||||
command: [...string]
|
||||
}
|
||||
|
||||
// +usage=Instructions for assessing container health by executing an HTTP GET request. Either this attribute or the exec attribute or the tcpSocket attribute MUST be specified. This attribute is mutually exclusive with both the exec attribute and the tcpSocket attribute.
|
||||
httpGet?: {
|
||||
// +usage=The endpoint, relative to the port, to which the HTTP GET request should be directed.
|
||||
path: string
|
||||
// +usage=The TCP socket within the container to which the HTTP GET request should be directed.
|
||||
port: int
|
||||
httpHeaders?: [...{
|
||||
name: string
|
||||
value: string
|
||||
}]
|
||||
}
|
||||
|
||||
// +usage=Instructions for assessing container health by probing a TCP socket. Either this attribute or the exec attribute or the httpGet attribute MUST be specified. This attribute is mutually exclusive with both the exec attribute and the httpGet attribute.
|
||||
tcpSocket?: {
|
||||
// +usage=The TCP socket within the container that should be probed to assess container health.
|
||||
port: int
|
||||
}
|
||||
|
||||
// +usage=Number of seconds after the container is started before the first probe is initiated.
|
||||
initialDelaySeconds: *0 | int
|
||||
|
||||
// +usage=How often, in seconds, to execute the probe.
|
||||
periodSeconds: *10 | int
|
||||
|
||||
// +usage=Number of seconds after which the probe times out.
|
||||
timeoutSeconds: *1 | int
|
||||
|
||||
// +usage=Minimum consecutive successes for the probe to be considered successful after having failed.
|
||||
successThreshold: *1 | int
|
||||
|
||||
// +usage=Number of consecutive failures required to determine the container is not alive (liveness probe) or not ready (readiness probe).
|
||||
failureThreshold: *3 | int
|
||||
}
|
||||
|
||||
|
||||
@@ -87,17 +87,6 @@ spec:
|
||||
}
|
||||
},
|
||||
] | []
|
||||
configMountToEnvsList: *[
|
||||
for v in parameter.configMap if v.mountToEnvs != _|_ for k in v.mountToEnvs {
|
||||
{
|
||||
name: k.envName
|
||||
valueFrom: configMapKeyRef: {
|
||||
name: v.name
|
||||
key: k.configMapKey
|
||||
}
|
||||
}
|
||||
},
|
||||
] | []
|
||||
secretVolumeMountsList: *[
|
||||
for v in parameter.secret if v.mountPath != _|_ {
|
||||
{
|
||||
@@ -117,17 +106,6 @@ spec:
|
||||
}
|
||||
},
|
||||
] | []
|
||||
secretMountToEnvsList: *[
|
||||
for v in parameter.secret if v.mountToEnvs != _|_ for k in v.mountToEnvs {
|
||||
{
|
||||
name: k.envName
|
||||
valueFrom: secretKeyRef: {
|
||||
name: v.name
|
||||
key: k.secretKey
|
||||
}
|
||||
}
|
||||
},
|
||||
] | []
|
||||
emptyDirVolumeMountsList: *[
|
||||
for v in parameter.emptyDir {
|
||||
{
|
||||
@@ -150,7 +128,7 @@ spec:
|
||||
|
||||
containers: [{
|
||||
// +patchKey=name
|
||||
env: configMapEnvMountsList + secretEnvMountsList + configMountToEnvsList + secretMountToEnvsList
|
||||
env: configMapEnvMountsList + secretEnvMountsList
|
||||
// +patchKey=name
|
||||
volumeDevices: volumeDevicesList
|
||||
// +patchKey=name
|
||||
@@ -270,10 +248,6 @@ spec:
|
||||
envName: string
|
||||
configMapKey: string
|
||||
}
|
||||
mountToEnvs?: [...{
|
||||
envName: string
|
||||
configMapKey: string
|
||||
}]
|
||||
mountPath?: string
|
||||
defaultMode: *420 | int
|
||||
readOnly: *false | bool
|
||||
@@ -293,10 +267,6 @@ spec:
|
||||
envName: string
|
||||
secretKey: string
|
||||
}
|
||||
mountToEnvs?: [...{
|
||||
envName: string
|
||||
secretKey: string
|
||||
}]
|
||||
mountPath?: string
|
||||
defaultMode: *420 | int
|
||||
readOnly: *false | bool
|
||||
|
||||
@@ -11,8 +11,6 @@ spec:
|
||||
schematic:
|
||||
cue:
|
||||
template: |
|
||||
parameter: {
|
||||
// +usage=Specify the wait duration time to resume workflow such as "30s", "1min" or "2m15s"
|
||||
duration?: string
|
||||
}
|
||||
// no parameters
|
||||
parameter: {}
|
||||
|
||||
|
||||
@@ -455,7 +455,7 @@ spec:
|
||||
readinessProbe?: #HealthProbe
|
||||
|
||||
// +usage=Specify the hostAliases to add
|
||||
hostAliases?: [...{
|
||||
hostAliases: [...{
|
||||
ip: string
|
||||
hostnames: [...string]
|
||||
}]
|
||||
|
||||
@@ -25,9 +25,6 @@ subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ include "kubevela.serviceAccountName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
- kind: Group
|
||||
name: core.oam.dev
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
|
||||
---
|
||||
# permissions to do leader election.
|
||||
@@ -124,36 +121,6 @@ spec:
|
||||
- "--webhook-port={{ .Values.webhookService.port }}"
|
||||
- "--webhook-cert-dir={{ .Values.admissionWebhooks.certificate.mountPath }}"
|
||||
{{ end }}
|
||||
{{ if ne .Values.optimize.cachedGvks "" }}
|
||||
- "--optimize-cached-gvks={{ .Values.optimize.cachedGvks }}"
|
||||
{{ end }}
|
||||
{{ if not .Values.optimize.resourceTrackerListOp }}
|
||||
- "--optimize-resource-tracker-list-op=false"
|
||||
{{ end }}
|
||||
{{ if .Values.optimize.controllerReconcileLoopReduction }}
|
||||
- "--optimize-controller-reconcile-loop-reduction"
|
||||
{{ end }}
|
||||
{{ if .Values.optimize.markWithProb }}
|
||||
- "--optimize-mark-with-prob={{ .Values.optimize.markWithProb }}"
|
||||
{{ end }}
|
||||
{{ if .Values.optimize.disableComponentRevision }}
|
||||
- "--optimize-disable-component-revision"
|
||||
{{ end }}
|
||||
{{ if .Values.optimize.disableApplicationRevision }}
|
||||
- "--optimize-disable-application-revision"
|
||||
{{ end }}
|
||||
{{ if .Values.optimize.disableWorkflowRecorder }}
|
||||
- "--optimize-disable-workflow-recorder"
|
||||
{{ end }}
|
||||
{{ if .Values.optimize.enableInMemoryWorkflowContext }}
|
||||
- "--optimize-enable-in-memory-workflow-context"
|
||||
{{ end }}
|
||||
{{ if .Values.optimize.disableResourceApplyDoubleCheck }}
|
||||
- "--optimize-disable-resource-apply-double-check"
|
||||
{{ end }}
|
||||
{{ if not .Values.optimize.enableResourceTrackerDeleteOnlyTrigger }}
|
||||
- "--optimize-enable-resource-tracker-delete-only-trigger=false"
|
||||
{{ end }}
|
||||
- "--health-addr=:{{ .Values.healthCheck.port }}"
|
||||
{{ if ne .Values.disableCaps "" }}
|
||||
- "--disable-caps={{ .Values.disableCaps }}"
|
||||
@@ -172,14 +139,6 @@ spec:
|
||||
- "--max-workflow-wait-backoff-time={{ .Values.workflow.backoff.maxTime.waitState }}"
|
||||
- "--max-workflow-failed-backoff-time={{ .Values.workflow.backoff.maxTime.failedState }}"
|
||||
- "--max-workflow-step-error-retry-times={{ .Values.workflow.step.errorRetryTimes }}"
|
||||
- "--feature-gates=AuthenticateApplication={{- .Values.authentication.enabled | toString -}}"
|
||||
{{ if .Values.authentication.enabled }}
|
||||
{{ if .Values.authentication.withUser }}
|
||||
- "--authentication-with-user"
|
||||
{{ end }}
|
||||
- "--authentication-default-user={{ .Values.authentication.defaultUser }}"
|
||||
- "--authentication-group-pattern={{ .Values.authentication.groupPattern }}"
|
||||
{{ end }}
|
||||
image: {{ .Values.imageRegistry }}{{ .Values.image.repository }}:{{ .Values.image.tag }}
|
||||
imagePullPolicy: {{ quote .Values.image.pullPolicy }}
|
||||
resources:
|
||||
@@ -227,4 +186,4 @@ spec:
|
||||
{{- with .Values.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -84,28 +84,6 @@ webhookService:
|
||||
healthCheck:
|
||||
port: 9440
|
||||
|
||||
## @section KubeVela controller optimization parameters
|
||||
##@param optimize.optimizeCachedGvks Optimize types of resources to be cached.
|
||||
##@param optimize.resourceTrackerListOp Optimize ResourceTracker List Op by adding index.
|
||||
##@param optimize.controllerReconcileLoopReduction Optimize ApplicationController reconcile by reducing the number of loops to reconcile application.
|
||||
##@param optimize.markWithProb Optimize ResourceTracker GC by only run mark with probability. Side effect: outdated ResourceTracker might not be able to be removed immediately.
|
||||
##@param optimize.disableComponentRevision Optimize componentRevision by disabling the creation and gc
|
||||
##@param optimize.disableApplicationRevision Optimize ApplicationRevision by disabling the creation and gc.
|
||||
##@param optimize.disableWorkflowRecorder Optimize workflow recorder by disabling the creation and gc.
|
||||
##@param optimize.enableInMemoryWorkflowContext Optimize workflow by use in-memory context.
|
||||
##@param optimize.disableResourceApplyDoubleCheck Optimize workflow by ignoring resource double check after apply.
|
||||
##@param optimize.enableResourceTrackerDeleteOnlyTrigger Optimize resourcetracker by only trigger reconcile when resourcetracker is deleted.
|
||||
optimize:
|
||||
optimizeCachedGvks:
|
||||
resourceTrackerListOp: true
|
||||
controllerReconcileLoopReduction: false
|
||||
markWithProb: 0.1
|
||||
disableComponentRevision: false
|
||||
disableApplicationRevision: false
|
||||
disableWorkflowRecorder: false
|
||||
enableInMemoryWorkflowContext: false
|
||||
disableResourceApplyDoubleCheck: false
|
||||
enableResourceTrackerDeleteOnlyTrigger: true
|
||||
|
||||
## @section MultiCluster parameters
|
||||
|
||||
@@ -232,13 +210,3 @@ admissionWebhooks:
|
||||
kubeClient:
|
||||
qps: 50
|
||||
burst: 100
|
||||
|
||||
## @param authentication.enabled Enable authentication for application
|
||||
## @param authentication.withUser Application authentication will impersonate as the request User
|
||||
## @param authentication.defaultUser Application authentication will impersonate as the User if no user provided in Application
|
||||
## @param authentication.groupPattern Application authentication will impersonate as the request Group that matches the pattern
|
||||
authentication:
|
||||
enabled: false
|
||||
withUser: false
|
||||
defaultUser: kubevela:vela-core
|
||||
groupPattern: kubevela:*
|
||||
|
||||
@@ -125,26 +125,22 @@ helm install --create-namespace -n vela-system kubevela kubevela/vela-minimal --
|
||||
|
||||
### Common parameters
|
||||
|
||||
| Name | Description | Value |
|
||||
| ----------------------------- | -------------------------------------------------------------------------------------------------------------------------- | -------------------- |
|
||||
| `imagePullSecrets` | Image pull secrets | `[]` |
|
||||
| `nameOverride` | Override name | `""` |
|
||||
| `fullnameOverride` | Fullname override | `""` |
|
||||
| `serviceAccount.create` | Specifies whether a service account should be created | `true` |
|
||||
| `serviceAccount.annotations` | Annotations to add to the service account | `{}` |
|
||||
| `serviceAccount.name` | The name of the service account to use. If not set and create is true, a name is generated using the fullname template | `nil` |
|
||||
| `nodeSelector` | Node selector | `{}` |
|
||||
| `tolerations` | Tolerations | `[]` |
|
||||
| `affinity` | Affinity | `{}` |
|
||||
| `rbac.create` | Specifies whether a RBAC role should be created | `true` |
|
||||
| `logDebug` | Enable debug logs for development purpose | `false` |
|
||||
| `logFilePath` | If non-empty, write log files in this path | `""` |
|
||||
| `logFileMaxSize` | Defines the maximum size a log file can grow to. Unit is megabytes. If the value is 0, the maximum file size is unlimited. | `1024` |
|
||||
| `kubeClient.qps` | The qps for reconcile clients, default is 50 | `50` |
|
||||
| `kubeClient.burst` | The burst for reconcile clients, default is 100 | `100` |
|
||||
| `authentication.enabled` | Enable authentication for application | `false` |
|
||||
| `authentication.withUser` | Application authentication will impersonate as the request User | `false` |
|
||||
| `authentication.defaultUser` | Application authentication will impersonate as the User if no user provided in Application | `kubevela:vela-core` |
|
||||
| `authentication.groupPattern` | Application authentication will impersonate as the request Group that matches the pattern | `kubevela:*` |
|
||||
| Name | Description | Value |
|
||||
| ---------------------------- | -------------------------------------------------------------------------------------------------------------------------- | ------- |
|
||||
| `imagePullSecrets` | Image pull secrets | `[]` |
|
||||
| `nameOverride` | Override name | `""` |
|
||||
| `fullnameOverride` | Fullname override | `""` |
|
||||
| `serviceAccount.create` | Specifies whether a service account should be created | `true` |
|
||||
| `serviceAccount.annotations` | Annotations to add to the service account | `{}` |
|
||||
| `serviceAccount.name` | The name of the service account to use. If not set and create is true, a name is generated using the fullname template | `nil` |
|
||||
| `nodeSelector` | Node selector | `{}` |
|
||||
| `tolerations` | Tolerations | `[]` |
|
||||
| `affinity` | Affinity | `{}` |
|
||||
| `rbac.create` | Specifies whether a RBAC role should be created | `true` |
|
||||
| `logDebug` | Enable debug logs for development purpose | `false` |
|
||||
| `logFilePath` | If non-empty, write log files in this path | `""` |
|
||||
| `logFileMaxSize` | Defines the maximum size a log file can grow to. Unit is megabytes. If the value is 0, the maximum file size is unlimited. | `1024` |
|
||||
| `kubeClient.qps` | The qps for reconcile clients, default is 50 | `50` |
|
||||
| `kubeClient.burst` | The burst for reconcile clients, default is 100 | `100` |
|
||||
|
||||
|
||||
|
||||
@@ -934,8 +934,6 @@ spec:
|
||||
type: array
|
||||
suspend:
|
||||
type: boolean
|
||||
suspendState:
|
||||
type: string
|
||||
terminated:
|
||||
type: boolean
|
||||
required:
|
||||
@@ -2745,8 +2743,6 @@ spec:
|
||||
type: array
|
||||
suspend:
|
||||
type: boolean
|
||||
suspendState:
|
||||
type: string
|
||||
terminated:
|
||||
type: boolean
|
||||
required:
|
||||
@@ -3390,10 +3386,6 @@ spec:
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
configMapRef:
|
||||
description: ConfigMapRef refer to a ConfigMap which contains
|
||||
OpenAPI V3 JSON schema of Component parameters.
|
||||
type: string
|
||||
latestRevision:
|
||||
description: LatestRevision of the component definition
|
||||
properties:
|
||||
@@ -4690,8 +4682,6 @@ spec:
|
||||
type: array
|
||||
suspend:
|
||||
type: boolean
|
||||
suspendState:
|
||||
type: string
|
||||
terminated:
|
||||
type: boolean
|
||||
required:
|
||||
|
||||
@@ -643,8 +643,6 @@ spec:
|
||||
type: array
|
||||
suspend:
|
||||
type: boolean
|
||||
suspendState:
|
||||
type: string
|
||||
terminated:
|
||||
type: boolean
|
||||
required:
|
||||
@@ -1148,8 +1146,6 @@ spec:
|
||||
type: array
|
||||
suspend:
|
||||
type: boolean
|
||||
suspendState:
|
||||
type: string
|
||||
terminated:
|
||||
type: boolean
|
||||
required:
|
||||
|
||||
@@ -636,10 +636,6 @@ spec:
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
configMapRef:
|
||||
description: ConfigMapRef refer to a ConfigMap which contains
|
||||
OpenAPI V3 JSON schema of Component parameters.
|
||||
type: string
|
||||
latestRevision:
|
||||
description: LatestRevision of the component definition
|
||||
properties:
|
||||
|
||||
@@ -244,10 +244,6 @@ spec:
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
configMapRef:
|
||||
description: ConfigMapRef refer to a ConfigMap which contains OpenAPI
|
||||
V3 JSON schema of Component parameters.
|
||||
type: string
|
||||
latestRevision:
|
||||
description: LatestRevision of the component definition
|
||||
properties:
|
||||
|
||||
@@ -92,32 +92,6 @@ webhooks:
|
||||
- UPDATE
|
||||
resources:
|
||||
- podspecworkloads
|
||||
- clientConfig:
|
||||
caBundle: Cg==
|
||||
service:
|
||||
name: {{ template "kubevela.name" . }}-webhook
|
||||
namespace: {{ .Release.Namespace }}
|
||||
path: /mutating-core-oam-dev-v1beta1-applications
|
||||
{{- if .Values.admissionWebhooks.patch.enabled }}
|
||||
failurePolicy: Ignore
|
||||
{{- else }}
|
||||
failurePolicy: Fail
|
||||
{{- end }}
|
||||
name: mutating.core.oam.dev.v1beta1.applications
|
||||
admissionReviewVersions:
|
||||
- v1beta1
|
||||
- v1
|
||||
sideEffects: None
|
||||
rules:
|
||||
- apiGroups:
|
||||
- core.oam.dev
|
||||
apiVersions:
|
||||
- v1beta1
|
||||
operations:
|
||||
- CREATE
|
||||
- UPDATE
|
||||
resources:
|
||||
- applications
|
||||
- clientConfig:
|
||||
caBundle: Cg==
|
||||
service:
|
||||
|
||||
@@ -188,30 +188,4 @@ spec:
|
||||
runAsGroup: 2000
|
||||
runAsNonRoot: true
|
||||
runAsUser: 2000
|
||||
{{ end }}
|
||||
---
|
||||
{{ if and .Values.multicluster.enabled }}
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: {{ include "kubevela.fullname" . }}:cluster-gateway-access-role
|
||||
rules:
|
||||
- apiGroups: [ "cluster.core.oam.dev" ]
|
||||
resources: [ "clustergateways/proxy" ]
|
||||
verbs: [ "get", "list", "watch", "create", "update", "patch", "delete" ]
|
||||
{{ end }}
|
||||
---
|
||||
{{ if and .Values.multicluster.enabled }}
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: {{ include "kubevela.fullname" . }}:cluster-gateway-access-rolebinding
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: {{ include "kubevela.fullname" . }}:cluster-gateway-access-role
|
||||
subjects:
|
||||
- kind: Group
|
||||
name: cluster-gateway-accessor
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
@@ -10,7 +10,6 @@ metadata:
|
||||
custom.definition.oam.dev/catalog.config.oam.dev: velacore-config
|
||||
custom.definition.oam.dev/multi-cluster.config.oam.dev: "true"
|
||||
custom.definition.oam.dev/type.config.oam.dev: image-registry
|
||||
custom.definition.oam.dev/ui-hidden: "true"
|
||||
name: config-image-registry
|
||||
namespace: {{ include "systemDefinitionNamespace" . }}
|
||||
spec:
|
||||
|
||||
@@ -35,9 +35,6 @@ spec:
|
||||
if parameter.args != _|_ {
|
||||
args: parameter.args
|
||||
}
|
||||
if parameter["env"] != _|_ {
|
||||
env: parameter.env
|
||||
}
|
||||
|
||||
// +patchKey=name
|
||||
volumeMounts: [{
|
||||
@@ -64,31 +61,6 @@ spec:
|
||||
// +usage=Specify the args run in the init container
|
||||
args?: [...string]
|
||||
|
||||
// +usage=Specify the env run in the init container
|
||||
env?: [...{
|
||||
// +usage=Environment variable name
|
||||
name: string
|
||||
// +usage=The value of the environment variable
|
||||
value?: string
|
||||
// +usage=Specifies a source the value of this var should come from
|
||||
valueFrom?: {
|
||||
// +usage=Selects a key of a secret in the pod's namespace
|
||||
secretKeyRef?: {
|
||||
// +usage=The name of the secret in the pod's namespace to select from
|
||||
name: string
|
||||
// +usage=The key of the secret to select from. Must be a valid secret key
|
||||
key: string
|
||||
}
|
||||
// +usage=Selects a key of a config map in the pod's namespace
|
||||
configMapKeyRef?: {
|
||||
// +usage=The name of the config map in the pod's namespace to select from
|
||||
name: string
|
||||
// +usage=The key of the config map to select from. Must be a valid secret key
|
||||
key: string
|
||||
}
|
||||
}
|
||||
}]
|
||||
|
||||
// +usage=Specify the mount name of shared volume
|
||||
mountName: *"workdir" | string
|
||||
|
||||
|
||||
@@ -27,9 +27,6 @@ spec:
|
||||
if parameter.args != _|_ {
|
||||
args: parameter.args
|
||||
}
|
||||
if parameter["env"] != _|_ {
|
||||
env: parameter.env
|
||||
}
|
||||
if parameter["volumes"] != _|_ {
|
||||
volumeMounts: [ for v in parameter.volumes {
|
||||
{
|
||||
@@ -38,13 +35,6 @@ spec:
|
||||
}
|
||||
}]
|
||||
}
|
||||
if parameter["livenessProbe"] != _|_ {
|
||||
livenessProbe: parameter.livenessProbe
|
||||
}
|
||||
|
||||
if parameter["readinessProbe"] != _|_ {
|
||||
readinessProbe: parameter.readinessProbe
|
||||
}
|
||||
}]
|
||||
}
|
||||
parameter: {
|
||||
@@ -60,82 +50,10 @@ spec:
|
||||
// +usage=Specify the args in the sidecar
|
||||
args?: [...string]
|
||||
|
||||
// +usage=Specify the env in the sidecar
|
||||
env?: [...{
|
||||
// +usage=Environment variable name
|
||||
name: string
|
||||
// +usage=The value of the environment variable
|
||||
value?: string
|
||||
// +usage=Specifies a source the value of this var should come from
|
||||
valueFrom?: {
|
||||
// +usage=Selects a key of a secret in the pod's namespace
|
||||
secretKeyRef?: {
|
||||
// +usage=The name of the secret in the pod's namespace to select from
|
||||
name: string
|
||||
// +usage=The key of the secret to select from. Must be a valid secret key
|
||||
key: string
|
||||
}
|
||||
// +usage=Selects a key of a config map in the pod's namespace
|
||||
configMapKeyRef?: {
|
||||
// +usage=The name of the config map in the pod's namespace to select from
|
||||
name: string
|
||||
// +usage=The key of the config map to select from. Must be a valid secret key
|
||||
key: string
|
||||
}
|
||||
}
|
||||
}]
|
||||
|
||||
// +usage=Specify the shared volume path
|
||||
volumes?: [...{
|
||||
name: string
|
||||
path: string
|
||||
}]
|
||||
|
||||
// +usage=Instructions for assessing whether the container is alive.
|
||||
livenessProbe?: #HealthProbe
|
||||
|
||||
// +usage=Instructions for assessing whether the container is in a suitable state to serve traffic.
|
||||
readinessProbe?: #HealthProbe
|
||||
}
|
||||
#HealthProbe: {
|
||||
|
||||
// +usage=Instructions for assessing container health by executing a command. Either this attribute or the httpGet attribute or the tcpSocket attribute MUST be specified. This attribute is mutually exclusive with both the httpGet attribute and the tcpSocket attribute.
|
||||
exec?: {
|
||||
// +usage=A command to be executed inside the container to assess its health. Each space delimited token of the command is a separate array element. Commands exiting 0 are considered to be successful probes, whilst all other exit codes are considered failures.
|
||||
command: [...string]
|
||||
}
|
||||
|
||||
// +usage=Instructions for assessing container health by executing an HTTP GET request. Either this attribute or the exec attribute or the tcpSocket attribute MUST be specified. This attribute is mutually exclusive with both the exec attribute and the tcpSocket attribute.
|
||||
httpGet?: {
|
||||
// +usage=The endpoint, relative to the port, to which the HTTP GET request should be directed.
|
||||
path: string
|
||||
// +usage=The TCP socket within the container to which the HTTP GET request should be directed.
|
||||
port: int
|
||||
httpHeaders?: [...{
|
||||
name: string
|
||||
value: string
|
||||
}]
|
||||
}
|
||||
|
||||
// +usage=Instructions for assessing container health by probing a TCP socket. Either this attribute or the exec attribute or the httpGet attribute MUST be specified. This attribute is mutually exclusive with both the exec attribute and the httpGet attribute.
|
||||
tcpSocket?: {
|
||||
// +usage=The TCP socket within the container that should be probed to assess container health.
|
||||
port: int
|
||||
}
|
||||
|
||||
// +usage=Number of seconds after the container is started before the first probe is initiated.
|
||||
initialDelaySeconds: *0 | int
|
||||
|
||||
// +usage=How often, in seconds, to execute the probe.
|
||||
periodSeconds: *10 | int
|
||||
|
||||
// +usage=Number of seconds after which the probe times out.
|
||||
timeoutSeconds: *1 | int
|
||||
|
||||
// +usage=Minimum consecutive successes for the probe to be considered successful after having failed.
|
||||
successThreshold: *1 | int
|
||||
|
||||
// +usage=Number of consecutive failures required to determine the container is not alive (liveness probe) or not ready (readiness probe).
|
||||
failureThreshold: *3 | int
|
||||
}
|
||||
|
||||
|
||||
@@ -87,17 +87,6 @@ spec:
|
||||
}
|
||||
},
|
||||
] | []
|
||||
configMountToEnvsList: *[
|
||||
for v in parameter.configMap if v.mountToEnvs != _|_ for k in v.mountToEnvs {
|
||||
{
|
||||
name: k.envName
|
||||
valueFrom: configMapKeyRef: {
|
||||
name: v.name
|
||||
key: k.configMapKey
|
||||
}
|
||||
}
|
||||
},
|
||||
] | []
|
||||
secretVolumeMountsList: *[
|
||||
for v in parameter.secret if v.mountPath != _|_ {
|
||||
{
|
||||
@@ -117,17 +106,6 @@ spec:
|
||||
}
|
||||
},
|
||||
] | []
|
||||
secretMountToEnvsList: *[
|
||||
for v in parameter.secret if v.mountToEnvs != _|_ for k in v.mountToEnvs {
|
||||
{
|
||||
name: k.envName
|
||||
valueFrom: secretKeyRef: {
|
||||
name: v.name
|
||||
key: k.secretKey
|
||||
}
|
||||
}
|
||||
},
|
||||
] | []
|
||||
emptyDirVolumeMountsList: *[
|
||||
for v in parameter.emptyDir {
|
||||
{
|
||||
@@ -150,7 +128,7 @@ spec:
|
||||
|
||||
containers: [{
|
||||
// +patchKey=name
|
||||
env: configMapEnvMountsList + secretEnvMountsList + configMountToEnvsList + secretMountToEnvsList
|
||||
env: configMapEnvMountsList + secretEnvMountsList
|
||||
// +patchKey=name
|
||||
volumeDevices: volumeDevicesList
|
||||
// +patchKey=name
|
||||
@@ -270,10 +248,6 @@ spec:
|
||||
envName: string
|
||||
configMapKey: string
|
||||
}
|
||||
mountToEnvs?: [...{
|
||||
envName: string
|
||||
configMapKey: string
|
||||
}]
|
||||
mountPath?: string
|
||||
defaultMode: *420 | int
|
||||
readOnly: *false | bool
|
||||
@@ -293,10 +267,6 @@ spec:
|
||||
envName: string
|
||||
secretKey: string
|
||||
}
|
||||
mountToEnvs?: [...{
|
||||
envName: string
|
||||
secretKey: string
|
||||
}]
|
||||
mountPath?: string
|
||||
defaultMode: *420 | int
|
||||
readOnly: *false | bool
|
||||
|
||||
@@ -11,8 +11,6 @@ spec:
|
||||
schematic:
|
||||
cue:
|
||||
template: |
|
||||
parameter: {
|
||||
// +usage=Specify the wait duration time to resume workflow such as "30s", "1min" or "2m15s"
|
||||
duration?: string
|
||||
}
|
||||
// no parameters
|
||||
parameter: {}
|
||||
|
||||
|
||||
@@ -455,7 +455,7 @@ spec:
|
||||
readinessProbe?: #HealthProbe
|
||||
|
||||
// +usage=Specify the hostAliases to add
|
||||
hostAliases?: [...{
|
||||
hostAliases: [...{
|
||||
ip: string
|
||||
hostnames: [...string]
|
||||
}]
|
||||
|
||||
@@ -27,9 +27,6 @@ subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ include "kubevela.serviceAccountName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
- kind: Group
|
||||
name: core.oam.dev
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
|
||||
---
|
||||
# permissions to do leader election.
|
||||
@@ -145,14 +142,6 @@ spec:
|
||||
- "--max-workflow-wait-backoff-time={{ .Values.workflow.backoff.maxTime.waitState }}"
|
||||
- "--max-workflow-failed-backoff-time={{ .Values.workflow.backoff.maxTime.failedState }}"
|
||||
- "--max-workflow-step-error-retry-times={{ .Values.workflow.step.errorRetryTimes }}"
|
||||
- "--feature-gates=AuthenticateApplication={{- .Values.authentication.enabled | toString -}}"
|
||||
{{ if .Values.authentication.enabled }}
|
||||
{{ if .Values.authentication.withUser }}
|
||||
- "--authentication-with-user"
|
||||
{{ end }}
|
||||
- "--authentication-default-user={{ .Values.authentication.defaultUser }}"
|
||||
- "--authentication-group-pattern={{ .Values.authentication.groupPattern }}"
|
||||
{{ end }}
|
||||
image: {{ .Values.imageRegistry }}{{ .Values.image.repository }}:{{ .Values.image.tag }}
|
||||
imagePullPolicy: {{ quote .Values.image.pullPolicy }}
|
||||
resources:
|
||||
|
||||
@@ -215,13 +215,3 @@ admissionWebhooks:
|
||||
kubeClient:
|
||||
qps: 50
|
||||
burst: 100
|
||||
|
||||
## @param authentication.enabled Enable authentication for application
|
||||
## @param authentication.withUser Application authentication will impersonate as the request User
|
||||
## @param authentication.defaultUser Application authentication will impersonate as the User if no user provided in Application
|
||||
## @param authentication.groupPattern Application authentication will impersonate as the request Group that matches the pattern
|
||||
authentication:
|
||||
enabled: false
|
||||
withUser: false
|
||||
defaultUser: kubevela:vela-core
|
||||
groupPattern: kubevela:*
|
||||
|
||||
@@ -46,7 +46,6 @@ func main() {
|
||||
flag.StringVar(&s.restCfg.LeaderConfig.LockName, "lock-name", "apiserver-lock", "the lease lock resource name")
|
||||
flag.DurationVar(&s.restCfg.LeaderConfig.Duration, "duration", time.Second*5, "the lease lock resource name")
|
||||
flag.DurationVar(&s.restCfg.AddonCacheTime, "addon-cache-duration", time.Minute*10, "how long between two addon cache operation")
|
||||
flag.BoolVar(&s.restCfg.DisableStatisticCronJob, "disable-statistic-cronJob", false, "close the system statistic info calculating cronJob")
|
||||
flag.Parse()
|
||||
|
||||
if len(os.Args) > 2 && os.Args[1] == "build-swagger" {
|
||||
|
||||
@@ -36,8 +36,6 @@ import (
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/healthz"
|
||||
|
||||
apicommon "github.com/oam-dev/kubevela/apis/core.oam.dev/common"
|
||||
"github.com/oam-dev/kubevela/apis/types"
|
||||
"github.com/oam-dev/kubevela/pkg/auth"
|
||||
ctrlClient "github.com/oam-dev/kubevela/pkg/client"
|
||||
standardcontroller "github.com/oam-dev/kubevela/pkg/controller"
|
||||
@@ -52,7 +50,6 @@ import (
|
||||
"github.com/oam-dev/kubevela/pkg/oam"
|
||||
"github.com/oam-dev/kubevela/pkg/oam/discoverymapper"
|
||||
"github.com/oam-dev/kubevela/pkg/resourcekeeper"
|
||||
pkgutils "github.com/oam-dev/kubevela/pkg/utils"
|
||||
"github.com/oam-dev/kubevela/pkg/utils/common"
|
||||
"github.com/oam-dev/kubevela/pkg/utils/system"
|
||||
"github.com/oam-dev/kubevela/pkg/utils/util"
|
||||
@@ -62,6 +59,10 @@ import (
|
||||
"github.com/oam-dev/kubevela/version"
|
||||
)
|
||||
|
||||
const (
|
||||
kubevelaName = "kubevela"
|
||||
)
|
||||
|
||||
var (
|
||||
scheme = common.Scheme
|
||||
waitSecretTimeout = 90 * time.Second
|
||||
@@ -201,22 +202,10 @@ func main() {
|
||||
klog.InfoS("Vela-Core init", "definition namespace", oam.SystemDefinitonNamespace)
|
||||
|
||||
restConfig := ctrl.GetConfigOrDie()
|
||||
restConfig.UserAgent = types.KubeVelaName + "/" + version.GitRevision
|
||||
restConfig.UserAgent = kubevelaName + "/" + version.GitRevision
|
||||
restConfig.QPS = float32(qps)
|
||||
restConfig.Burst = burst
|
||||
restConfig.Wrap(auth.NewImpersonatingRoundTripper)
|
||||
restConfig.Impersonate.UserName = types.VelaCoreName
|
||||
if sub := pkgutils.GetServiceAccountSubjectFromConfig(restConfig); sub != "" {
|
||||
restConfig.Impersonate.UserName = sub
|
||||
}
|
||||
restConfig.Impersonate.Groups = []string{apicommon.Group}
|
||||
klog.InfoS("Kubernetes Config Loaded",
|
||||
"UserAgent", restConfig.UserAgent,
|
||||
"QPS", restConfig.QPS,
|
||||
"Burst", restConfig.Burst,
|
||||
"Impersonate-User", restConfig.Impersonate.UserName,
|
||||
"Impersonate-Group", strings.Join(restConfig.Impersonate.Groups, ","),
|
||||
)
|
||||
|
||||
// wrapper the round tripper by multi cluster rewriter
|
||||
if enableClusterGateway {
|
||||
@@ -236,7 +225,7 @@ func main() {
|
||||
}
|
||||
ctrl.SetLogger(klogr.New())
|
||||
|
||||
leaderElectionID := util.GenerateLeaderElectionID(types.KubeVelaName, controllerArgs.IgnoreAppWithoutControllerRequirement)
|
||||
leaderElectionID := util.GenerateLeaderElectionID(kubevelaName, controllerArgs.IgnoreAppWithoutControllerRequirement)
|
||||
mgr, err := ctrl.NewManager(restConfig, ctrl.Options{
|
||||
Scheme: scheme,
|
||||
MetricsBindAddress: metricsAddr,
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
By leveraging the garbage-collect policy, users can persist some resources, which skip the normal garbage-collect process when application is updated.
|
||||
|
||||
### traitTypes
|
||||
|
||||
Take the following app as an example, in the garbage-collect policy, a rule is added which marks all the resources created by the `expose` trait to use the `onAppDelete` strategy. This will keep those services until application is deleted.
|
||||
```shell
|
||||
$ cat <<EOF | kubectl apply -f -
|
||||
@@ -80,8 +78,6 @@ hello-world ClusterIP 10.96.160.208 <none> 8000/TCP 5m56s
|
||||
hello-world-new ClusterIP 10.96.20.4 <none> 8000/TCP 13s
|
||||
```
|
||||
|
||||
### componentTypes
|
||||
|
||||
Users can also keep component if they are deploying job-like components. Resources dispatched by `job-like-component` type component will be kept after application is deleted.
|
||||
|
||||
```yaml
|
||||
@@ -104,8 +100,6 @@ spec:
|
||||
strategy: never
|
||||
```
|
||||
|
||||
### componentNames
|
||||
|
||||
A more straightforward way is to specify `compNames` to match specified components.
|
||||
```yaml
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
@@ -130,74 +124,3 @@ spec:
|
||||
- example-addon-namespace
|
||||
strategy: never
|
||||
```
|
||||
|
||||
### oamTypes
|
||||
|
||||
Users can also persist resources using `oamTypes`, where the values of `oamTypes` can be `TRAIT` and `WORKLOAD`.
|
||||
|
||||
```shell
|
||||
$ cat <<EOF | kubectl apply -f -
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: garbage-collect-app
|
||||
spec:
|
||||
components:
|
||||
- name: hello-world
|
||||
type: webservice
|
||||
properties:
|
||||
image: crccheck/hello-world
|
||||
traits:
|
||||
- type: expose
|
||||
properties:
|
||||
port: [8000]
|
||||
policies:
|
||||
- name: garbage-collect
|
||||
type: garbage-collect
|
||||
properties:
|
||||
rules:
|
||||
- selector:
|
||||
oamTypes:
|
||||
- TRAIT
|
||||
strategy: onAppDelete
|
||||
EOF
|
||||
```
|
||||
|
||||
And then, let's modify the component name.
|
||||
|
||||
```shell
|
||||
$ cat <<EOF | kubectl apply -f -
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: garbage-collect-app
|
||||
spec:
|
||||
components:
|
||||
- name: hello-world-new
|
||||
type: webservice
|
||||
properties:
|
||||
image: crccheck/hello-world
|
||||
traits:
|
||||
- type: expose
|
||||
properties:
|
||||
port: [8000]
|
||||
policies:
|
||||
- name: garbage-collect
|
||||
type: garbage-collect
|
||||
properties:
|
||||
rules:
|
||||
- selector:
|
||||
oamTypes:
|
||||
- TRAIT
|
||||
strategy: onAppDelete
|
||||
EOF
|
||||
```
|
||||
|
||||
List the service in cluster, you will find:
|
||||
|
||||
```shell
|
||||
$ kubectl get service
|
||||
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
hello-world ClusterIP 10.96.31.209 <none> 8000/TCP 31s
|
||||
hello-world-new ClusterIP 10.96.17.103 <none> 8000/TCP 5s
|
||||
```
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
# How to garbage collect resources in the order of dependency
|
||||
|
||||
If you want to garbage collect resources in the order of dependency, you can add `order: dependency` in the `garbage-collect` policy.
|
||||
|
||||
> Notice that this order policy is only valid for the resources that are created in the components.
|
||||
|
||||
In the following example, component `test1` depends on `test2`, and `test2` need the output from `test3`.
|
||||
|
||||
So the order of deployment is: `test3 -> test2 -> test1`.
|
||||
|
||||
When we add `order: dependency` in `garbage-collect` policy and delete the application, the order of garbage collect is: `test3 -> test2 -> test1`.
|
||||
|
||||
```yaml
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: gc-dependency
|
||||
namespace: default
|
||||
spec:
|
||||
components:
|
||||
- name: test1
|
||||
type: webservice
|
||||
properties:
|
||||
image: crccheck/hello-world
|
||||
port: 8000
|
||||
dependsOn:
|
||||
- "test2"
|
||||
- name: test2
|
||||
type: webservice
|
||||
properties:
|
||||
image: crccheck/hello-world
|
||||
port: 8000
|
||||
inputs:
|
||||
- from: test3-output
|
||||
parameterKey: test
|
||||
- name: test3
|
||||
type: webservice
|
||||
properties:
|
||||
image: crccheck/hello-world
|
||||
port: 8000
|
||||
outputs:
|
||||
- name: test3-output
|
||||
valueFrom: output.metadata.name
|
||||
|
||||
policies:
|
||||
- name: gc-dependency
|
||||
type: garbage-collect
|
||||
properties:
|
||||
order: dependency
|
||||
```
|
||||
@@ -32,9 +32,6 @@ spec:
|
||||
mountToEnv:
|
||||
envName: TEST_ENV
|
||||
configMapKey: key1
|
||||
mountToEnvs:
|
||||
- envName: TEST_CM_ENV
|
||||
configMapKey: key2
|
||||
data:
|
||||
key1: value1
|
||||
key2: value2
|
||||
@@ -52,15 +49,9 @@ spec:
|
||||
mountToEnv:
|
||||
envName: TEST_SECRET
|
||||
secretKey: key1
|
||||
mountToEnvs:
|
||||
- envName: TEST_SECRET_ENV_2
|
||||
secretKey: key2
|
||||
- envName: TEST_SECRET_ENV_3
|
||||
secretKey: key3
|
||||
data:
|
||||
key1: dmFsdWUx
|
||||
key2: dmFsdWUy
|
||||
key3: dmFsdWUz
|
||||
emptyDir:
|
||||
- name: test1
|
||||
mountPath: /test/mount/emptydir
|
||||
|
||||
23
e2e/addon/mock/testdata/mock-addon/metadata.yaml
vendored
23
e2e/addon/mock/testdata/mock-addon/metadata.yaml
vendored
@@ -1,23 +0,0 @@
|
||||
name: mock-addon
|
||||
version: 1.0.0
|
||||
description: Extended workload to do continuous and progressive delivery
|
||||
icon: https://raw.githubusercontent.com/fluxcd/flux/master/docs/_files/weave-flux.png
|
||||
url: https://fluxcd.io
|
||||
|
||||
tags:
|
||||
- extended_workload
|
||||
- gitops
|
||||
- only_example
|
||||
|
||||
deployTo:
|
||||
control_plane: true
|
||||
runtime_cluster: false
|
||||
|
||||
dependencies: []
|
||||
#- name: addon_name
|
||||
|
||||
# set invisible means this won't be list and will be enabled when depended on
|
||||
# for example, terraform-alibaba depends on terraform which is invisible,
|
||||
# when terraform-alibaba is enabled, terraform will be enabled automatically
|
||||
# default: false
|
||||
invisible: false
|
||||
14
e2e/addon/mock/testdata/mock-addon/template.yaml
vendored
14
e2e/addon/mock/testdata/mock-addon/template.yaml
vendored
@@ -1,14 +0,0 @@
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: mock-addon
|
||||
namespace: vela-system
|
||||
spec:
|
||||
components:
|
||||
- name: ns-example-system
|
||||
type: raw
|
||||
properties:
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: mock-system
|
||||
@@ -129,7 +129,7 @@ var _ = Describe("Test Kubectl Plugin", func() {
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(output).Should(ContainSubstring(showTdResult))
|
||||
})
|
||||
It("Test show componentDefinition use Helm Charts as Workload", func() {
|
||||
PIt("Test show componentDefinition use Helm Charts as Workload", func() {
|
||||
Eventually(func() string {
|
||||
cdName := "test-webapp-chart"
|
||||
output, _ := e2e.Exec(fmt.Sprintf("kubectl-vela show %s -n default", cdName))
|
||||
|
||||
34
go.mod
34
go.mod
@@ -5,7 +5,6 @@ go 1.17
|
||||
require (
|
||||
cuelang.org/go v0.2.2
|
||||
github.com/AlecAivazis/survey/v2 v2.1.1
|
||||
github.com/FogDong/uitable v0.0.5
|
||||
github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8
|
||||
github.com/agiledragon/gomonkey/v2 v2.4.0
|
||||
github.com/alibabacloud-go/cs-20151215/v2 v2.4.5
|
||||
@@ -65,9 +64,10 @@ require (
|
||||
go.mongodb.org/mongo-driver v1.5.1
|
||||
go.uber.org/zap v1.18.1
|
||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97
|
||||
golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a
|
||||
golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211
|
||||
golang.org/x/tools v0.1.7 // indirect
|
||||
golang.org/x/tools v0.1.6 // indirect
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
|
||||
gopkg.in/src-d/go-git.v4 v4.13.1
|
||||
@@ -97,18 +97,6 @@ require (
|
||||
sigs.k8s.io/yaml v1.2.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/docker/distribution v2.8.1+incompatible // indirect
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||
github.com/hashicorp/go-retryablehttp v0.7.0 // indirect
|
||||
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 // indirect
|
||||
github.com/xanzy/go-gitlab v0.60.0
|
||||
github.com/xanzy/ssh-agent v0.3.0 // indirect
|
||||
golang.org/x/net v0.0.0-20220325170049-de3da57026de // indirect
|
||||
golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 // indirect
|
||||
google.golang.org/protobuf v1.28.0 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.81.0 // indirect
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
|
||||
@@ -152,7 +140,8 @@ require (
|
||||
github.com/cyphar/filepath-securejoin v0.2.2 // indirect
|
||||
github.com/deislabs/oras v0.11.1 // indirect
|
||||
github.com/docker/cli v20.10.5+incompatible // indirect
|
||||
github.com/docker/docker v20.10.14+incompatible // indirect
|
||||
github.com/docker/distribution v2.8.0-beta.1+incompatible // indirect
|
||||
github.com/docker/docker v17.12.0-ce-rc1.0.20200618181300-9dc6525e6118+incompatible // indirect
|
||||
github.com/docker/docker-credential-helpers v0.6.3 // indirect
|
||||
github.com/docker/go-connections v0.4.0 // indirect
|
||||
github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916 // indirect
|
||||
@@ -163,7 +152,7 @@ require (
|
||||
github.com/emirpasic/gods v1.12.0 // indirect
|
||||
github.com/evanphx/json-patch/v5 v5.1.0 // indirect
|
||||
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect
|
||||
github.com/fatih/camelcase v1.0.0
|
||||
github.com/fatih/camelcase v1.0.0 // indirect
|
||||
github.com/ghodss/yaml v1.0.0 // indirect
|
||||
github.com/go-errors/errors v1.0.1 // indirect
|
||||
github.com/go-logr/zapr v0.4.0 // indirect
|
||||
@@ -180,7 +169,7 @@ require (
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/golang/snappy v0.0.1 // indirect
|
||||
github.com/google/btree v1.0.1 // indirect
|
||||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
github.com/google/go-querystring v1.0.0 // indirect
|
||||
github.com/google/gofuzz v1.1.0 // indirect
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
|
||||
github.com/googleapis/gnostic v0.5.5 // indirect
|
||||
@@ -195,6 +184,7 @@ require (
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.11 // indirect
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 // indirect
|
||||
github.com/klauspost/compress v1.11.0 // indirect
|
||||
github.com/kr/pretty v0.3.0 // indirect
|
||||
github.com/kr/pty v1.1.8 // indirect
|
||||
@@ -232,7 +222,6 @@ require (
|
||||
github.com/prometheus/client_model v0.2.0 // indirect
|
||||
github.com/prometheus/common v0.26.0 // indirect
|
||||
github.com/prometheus/procfs v0.6.0 // indirect
|
||||
github.com/robfig/cron/v3 v3.0.1
|
||||
github.com/rogpeppe/go-internal v1.8.0 // indirect
|
||||
github.com/rubenv/sql-migrate v0.0.0-20200616145509-8d140a17f351 // indirect
|
||||
github.com/russross/blackfriday v1.5.2 // indirect
|
||||
@@ -246,6 +235,7 @@ require (
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.0 // indirect
|
||||
github.com/tjfoc/gmsm v1.3.2 // indirect
|
||||
github.com/xanzy/ssh-agent v0.3.0 // indirect
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
|
||||
github.com/xdg-go/scram v1.0.2 // indirect
|
||||
github.com/xdg-go/stringprep v1.0.2 // indirect
|
||||
@@ -260,14 +250,16 @@ require (
|
||||
go.uber.org/atomic v1.7.0 // indirect
|
||||
go.uber.org/multierr v1.6.0 // indirect
|
||||
golang.org/x/mod v0.4.2 // indirect
|
||||
golang.org/x/net v0.0.0-20211029224645-99673261e6eb // indirect
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||
gomodules.xyz/jsonpatch/v2 v2.2.0
|
||||
gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c // indirect
|
||||
google.golang.org/grpc v1.38.0 // indirect
|
||||
google.golang.org/protobuf v1.26.0 // indirect
|
||||
gopkg.in/gorp.v1 v1.7.2 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/ini.v1 v1.62.0 // indirect
|
||||
|
||||
39
go.sum
39
go.sum
@@ -118,8 +118,6 @@ github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20O
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
||||
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
|
||||
github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs=
|
||||
github.com/FogDong/uitable v0.0.5 h1:1bJo/uvhGUC6i8JPHZCr8XKMHiDExE7mQkOCmDl0ryQ=
|
||||
github.com/FogDong/uitable v0.0.5/go.mod h1:1yEaP13SkkBUj3HvqKIUWnsb42XigyZbNle84mc5kLM=
|
||||
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
||||
github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd h1:sjQovDkwrZp8u+gxLtPgKGjk5hCxuy2hrRejBTA9xFU=
|
||||
github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E=
|
||||
@@ -411,8 +409,8 @@ github.com/docker/cli v20.10.9+incompatible h1:OJ7YkwQA+k2Oi51lmCojpjiygKpi76P7b
|
||||
github.com/docker/cli v20.10.9+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/distribution v0.0.0-20191216044856-a8371794149d/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY=
|
||||
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68=
|
||||
github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/distribution v2.8.0-beta.1+incompatible h1:9MjVa+OTMHm4C0kKZB68jPlDM9Cg75ta4i46Gxxxn8o=
|
||||
github.com/docker/distribution v2.8.0-beta.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/docker-credential-helpers v0.6.3 h1:zI2p9+1NQYdnG6sMU26EX4aVGlqbInSQxQXLvzJ4RPQ=
|
||||
github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y=
|
||||
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
||||
@@ -783,9 +781,8 @@ github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-github/v32 v32.1.0 h1:GWkQOdXqviCPx7Q7Fj+KyPoGm4SwHRh8rheoPhd27II=
|
||||
github.com/google/go-github/v32 v32.1.0/go.mod h1:rIEpZD9CTDQwDK9GDrtMTycQNA4JU3qBsCizh3q2WCI=
|
||||
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
||||
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
||||
github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
|
||||
github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
@@ -898,12 +895,8 @@ github.com/hashicorp/consul/sdk v0.4.0/go.mod h1:fY08Y9z5SvJqevyZNy6WWPXiG3KwBPA
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
|
||||
github.com/hashicorp/go-getter v1.4.0/go.mod h1:7qxyCd8rBfcShwsvxgIguu4KbS3l8bUCwg2Umn7RjeY=
|
||||
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
|
||||
github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
|
||||
github.com/hashicorp/go-hclog v0.12.2 h1:F1fdYblUEsxKiailtkhCCG2g4bipEgaHiDc8vffNpD4=
|
||||
github.com/hashicorp/go-hclog v0.12.2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
|
||||
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
github.com/hashicorp/go-immutable-radix v1.1.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
@@ -913,9 +906,6 @@ github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iP
|
||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
||||
github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
|
||||
github.com/hashicorp/go-retryablehttp v0.6.8/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
|
||||
github.com/hashicorp/go-retryablehttp v0.7.0 h1:eu1EI/mbirUgP5C8hVsTNaGZreBDlYiwC1FZWkvQPQ4=
|
||||
github.com/hashicorp/go-retryablehttp v0.7.0/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
|
||||
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
|
||||
github.com/hashicorp/go-rootcerts v1.0.1/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
|
||||
github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
|
||||
@@ -1447,8 +1437,6 @@ github.com/rancher/wrangler v0.4.0/go.mod h1:1cR91WLhZgkZ+U4fV9nVuXqKurWbgXcIReU
|
||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M=
|
||||
github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc=
|
||||
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
||||
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
@@ -1630,8 +1618,6 @@ github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgq
|
||||
github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
|
||||
github.com/wonderflow/cert-manager-api v1.0.3 h1:xQQMkJNQ12oYyy00jOQUlSKgdraApaURxv3PHFdVTfA=
|
||||
github.com/wonderflow/cert-manager-api v1.0.3/go.mod h1:1Se7MSg11/eNYlo4fWv6vOM55/jTBMOzg2DN1kVFiSc=
|
||||
github.com/xanzy/go-gitlab v0.60.0 h1:HaIlc14k4t9eJjAhY0Gmq2fBHgKd1MthBn3+vzDtsbA=
|
||||
github.com/xanzy/go-gitlab v0.60.0/go.mod h1:F0QEXwmqiBUxCgJm8fE9S+1veX4XC9Z4cfaAbqwk4YM=
|
||||
github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
|
||||
github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI=
|
||||
github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0=
|
||||
@@ -1922,12 +1908,9 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b
|
||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
||||
golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211029224645-99673261e6eb h1:pirldcYWx7rx7kE5r+9WsOXPXK0+WH5+uZ7uPmJ44uM=
|
||||
golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220325170049-de3da57026de h1:pZB1TWnKi+o4bENlbzAgLrEbY4RMYmUIRobMcSmfeYc=
|
||||
golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@@ -1939,9 +1922,8 @@ golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ
|
||||
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602 h1:0Ja1LBD+yisY6RWM/BH7TJVXWsSjs2VwBSmvSX4HdBc=
|
||||
golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a h1:qfl7ob3DIEs3Ml9oLuPwY2N04gymzAW04WsUQHIClgM=
|
||||
golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -2095,9 +2077,8 @@ golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxb
|
||||
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20210611083556-38a9dc6acbc6/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs=
|
||||
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 h1:M73Iuj3xbbb9Uk1DYhzydthsj6oOd6l9bpuFcNoUvTs=
|
||||
golang.org/x/time v0.0.0-20220224211638-0e9765cccd65/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
@@ -2221,8 +2202,8 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.7 h1:6j8CgantCy3yc8JGBqkDLMKWqZ0RDU2g1HVgacojGWQ=
|
||||
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
|
||||
golang.org/x/tools v0.1.6 h1:SIasE1FVIQOWz2GEAHFOmoW7xchJcqlucjSULTL0Ag4=
|
||||
golang.org/x/tools v0.1.6/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@@ -2267,7 +2248,6 @@ google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk
|
||||
google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
@@ -2376,9 +2356,8 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
|
||||
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
|
||||
|
||||
@@ -934,8 +934,6 @@ spec:
|
||||
type: array
|
||||
suspend:
|
||||
type: boolean
|
||||
suspendState:
|
||||
type: string
|
||||
terminated:
|
||||
type: boolean
|
||||
required:
|
||||
@@ -2745,8 +2743,6 @@ spec:
|
||||
type: array
|
||||
suspend:
|
||||
type: boolean
|
||||
suspendState:
|
||||
type: string
|
||||
terminated:
|
||||
type: boolean
|
||||
required:
|
||||
@@ -3390,10 +3386,6 @@ spec:
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
configMapRef:
|
||||
description: ConfigMapRef refer to a ConfigMap which contains
|
||||
OpenAPI V3 JSON schema of Component parameters.
|
||||
type: string
|
||||
latestRevision:
|
||||
description: LatestRevision of the component definition
|
||||
properties:
|
||||
@@ -4690,8 +4682,6 @@ spec:
|
||||
type: array
|
||||
suspend:
|
||||
type: boolean
|
||||
suspendState:
|
||||
type: string
|
||||
terminated:
|
||||
type: boolean
|
||||
required:
|
||||
|
||||
@@ -854,8 +854,6 @@ spec:
|
||||
type: array
|
||||
suspend:
|
||||
type: boolean
|
||||
suspendState:
|
||||
type: string
|
||||
terminated:
|
||||
type: boolean
|
||||
required:
|
||||
@@ -1521,8 +1519,6 @@ spec:
|
||||
type: array
|
||||
suspend:
|
||||
type: boolean
|
||||
suspendState:
|
||||
type: string
|
||||
terminated:
|
||||
type: boolean
|
||||
required:
|
||||
|
||||
@@ -636,10 +636,6 @@ spec:
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
configMapRef:
|
||||
description: ConfigMapRef refer to a ConfigMap which contains
|
||||
OpenAPI V3 JSON schema of Component parameters.
|
||||
type: string
|
||||
latestRevision:
|
||||
description: LatestRevision of the component definition
|
||||
properties:
|
||||
|
||||
@@ -244,10 +244,6 @@ spec:
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
configMapRef:
|
||||
description: ConfigMapRef refer to a ConfigMap which contains OpenAPI
|
||||
V3 JSON schema of Component parameters.
|
||||
type: string
|
||||
latestRevision:
|
||||
description: LatestRevision of the component definition
|
||||
properties:
|
||||
|
||||
@@ -47,5 +47,5 @@ VELA_CORE_TEST_IMAGE ?= vela-core-test:$(GIT_COMMIT)
|
||||
VELA_APISERVER_IMAGE ?= apiserver:latest
|
||||
VELA_RUNTIME_ROLLOUT_IMAGE ?= vela-runtime-rollout:latest
|
||||
VELA_RUNTIME_ROLLOUT_TEST_IMAGE ?= vela-runtime-rollout-test:$(GIT_COMMIT)
|
||||
RUNTIME_CLUSTER_CONFIG ?= /tmp/worker.client.kubeconfig
|
||||
RUNTIME_CLUSTER_CONFIG ?= /tmp/worker.kubeconfig
|
||||
RUNTIME_CLUSTER_NAME ?= worker
|
||||
@@ -25,7 +25,7 @@ ifeq (, $(shell which staticcheck))
|
||||
@{ \
|
||||
set -e ;\
|
||||
echo 'installing honnef.co/go/tools/cmd/staticcheck ' ;\
|
||||
GO111MODULE=on go get honnef.co/go/tools/cmd/staticcheck@v0.3.0 ;\
|
||||
GO111MODULE=off go get honnef.co/go/tools/cmd/staticcheck ;\
|
||||
}
|
||||
STATICCHECK=$(GOBIN)/staticcheck
|
||||
else
|
||||
|
||||
@@ -15,7 +15,7 @@ setup-runtime-e2e-cluster:
|
||||
|
||||
.PHONY: e2e-setup
|
||||
e2e-setup:
|
||||
helm install kruise https://github.com/openkruise/charts/releases/download/kruise-1.1.0/kruise-1.1.0.tgz --set featureGates="PreDownloadImageForInPlaceUpdate=true"
|
||||
helm install kruise https://github.com/openkruise/kruise/releases/download/v0.9.0/kruise-chart.tgz --set featureGates="PreDownloadImageForInPlaceUpdate=true"
|
||||
sh ./hack/e2e/modify_charts.sh
|
||||
helm upgrade --install --create-namespace --namespace vela-system --set image.pullPolicy=IfNotPresent --set image.repository=vela-core-test --set applicationRevisionLimit=5 --set dependCheckWait=10s --set image.tag=$(GIT_COMMIT) --wait kubevela ./charts/vela-core
|
||||
helm upgrade --install --create-namespace --namespace oam-runtime-system --set image.pullPolicy=IfNotPresent --set image.repository=vela-core-test --set dependCheckWait=10s --set image.tag=$(GIT_COMMIT) --wait oam-runtime ./charts/oam-runtime
|
||||
@@ -48,7 +48,6 @@ ADDONSERVER = $(shell pgrep vela_addon_mock_server)
|
||||
e2e-apiserver-test:
|
||||
pkill vela_addon_mock_server || true
|
||||
go run ./e2e/addon/mock/vela_addon_mock_server.go &
|
||||
sleep 15
|
||||
go test -v -coverpkg=./... -coverprofile=/tmp/e2e_apiserver_test.out ./test/e2e-apiserver-test
|
||||
@$(OK) tests pass
|
||||
|
||||
|
||||
@@ -36,7 +36,6 @@ import (
|
||||
"github.com/google/go-github/v32/github"
|
||||
"github.com/hashicorp/go-version"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/xanzy/go-gitlab"
|
||||
"golang.org/x/oauth2"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
@@ -448,15 +447,6 @@ func createGiteeHelper(content *utils.Content, token string) *giteeHelper {
|
||||
}
|
||||
}
|
||||
|
||||
func createGitlabHelper(content *utils.Content, token string) (*gitlabHelper, error) {
|
||||
newClient, err := gitlab.NewClient(token, gitlab.WithBaseURL(content.GitlabContent.Host))
|
||||
|
||||
return &gitlabHelper{
|
||||
Client: newClient,
|
||||
Meta: content,
|
||||
}, err
|
||||
}
|
||||
|
||||
// readRepo will read relative path (relative to Meta.Path)
|
||||
func (h *gitHelper) readRepo(relativePath string) (*github.RepositoryContent, []*github.RepositoryContent, error) {
|
||||
file, items, _, err := h.Client.Repositories.GetContents(context.Background(), h.Meta.GithubContent.Owner, h.Meta.GithubContent.Repo, path.Join(h.Meta.GithubContent.Path, relativePath), nil)
|
||||
|
||||
@@ -147,7 +147,7 @@ func TestGetAddonData(t *testing.T) {
|
||||
server := httptest.NewServer(ossHandler)
|
||||
defer server.Close()
|
||||
|
||||
reader, err := NewAsyncReader(server.URL, "", "", "", "", ossType)
|
||||
reader, err := NewAsyncReader(server.URL, "", "", "", ossType)
|
||||
assert.NoError(t, err)
|
||||
testReaderFunc(t, reader)
|
||||
}
|
||||
@@ -617,9 +617,9 @@ func TestRenderApp4ObservabilityWithK8sData(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetPatternFromItem(t *testing.T) {
|
||||
ossR, err := NewAsyncReader("http://ep.beijing", "some-bucket", "", "some-sub-path", "", ossType)
|
||||
ossR, err := NewAsyncReader("http://ep.beijing", "some-bucket", "some-sub-path", "", ossType)
|
||||
assert.NoError(t, err)
|
||||
gitR, err := NewAsyncReader("https://github.com/oam-dev/catalog", "", "", "addons", "", gitType)
|
||||
gitR, err := NewAsyncReader("https://github.com/oam-dev/catalog", "", "addons", "", gitType)
|
||||
assert.NoError(t, err)
|
||||
gitItemName := "parameter.cue"
|
||||
gitItemType := FileType
|
||||
@@ -657,7 +657,7 @@ func TestGetPatternFromItem(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGitLabReaderNotPanic(t *testing.T) {
|
||||
_, err := NewAsyncReader("https://gitlab.com/test/catalog", "", "", "addons", "", gitType)
|
||||
_, err := NewAsyncReader("https://gitlab.com/test/catalog", "", "addons", "", gitType)
|
||||
assert.EqualError(t, err, "git type repository only support github for now")
|
||||
}
|
||||
|
||||
|
||||
@@ -1,150 +0,0 @@
|
||||
/*
|
||||
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 addon
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
|
||||
"github.com/xanzy/go-gitlab"
|
||||
|
||||
"github.com/oam-dev/kubevela/pkg/utils"
|
||||
)
|
||||
|
||||
var _ AsyncReader = &gitlabReader{}
|
||||
|
||||
// gitlabReader helps get addon's file by git
|
||||
type gitlabReader struct {
|
||||
h *gitlabHelper
|
||||
}
|
||||
|
||||
// gitlabHelper helps get addon's file by git
|
||||
type gitlabHelper struct {
|
||||
Client *gitlab.Client
|
||||
Meta *utils.Content
|
||||
}
|
||||
|
||||
// GitLabItem addon's sub item
|
||||
type GitLabItem struct {
|
||||
basePath string
|
||||
tp string
|
||||
path string
|
||||
name string
|
||||
}
|
||||
|
||||
// GetType get addon's sub item type
|
||||
func (g GitLabItem) GetType() string {
|
||||
return g.tp
|
||||
}
|
||||
|
||||
// GetPath get addon's sub item path
|
||||
func (g GitLabItem) GetPath() string {
|
||||
return g.path[len(g.basePath)+1:]
|
||||
}
|
||||
|
||||
// GetName get addon's sub item name
|
||||
func (g GitLabItem) GetName() string {
|
||||
return g.name
|
||||
}
|
||||
|
||||
// GetRef ref is empty , use default branch master
|
||||
func (g *gitlabReader) GetRef() string {
|
||||
var ref = "master"
|
||||
if g.h.Meta.GitlabContent.Ref != "" {
|
||||
return g.h.Meta.GitlabContent.Ref
|
||||
}
|
||||
return ref
|
||||
}
|
||||
|
||||
// GetProjectID get gitlab project id
|
||||
func (g *gitlabReader) GetProjectID() int {
|
||||
return g.h.Meta.GitlabContent.PId
|
||||
}
|
||||
|
||||
// GetProjectPath get gitlab project path
|
||||
func (g *gitlabReader) GetProjectPath() string {
|
||||
return g.h.Meta.GitlabContent.Path
|
||||
}
|
||||
|
||||
// ListAddonMeta relative path to repoURL/basePath
|
||||
func (g *gitlabReader) ListAddonMeta() (addonCandidates map[string]SourceMeta, err error) {
|
||||
addonCandidates = make(map[string]SourceMeta)
|
||||
path := g.GetProjectPath()
|
||||
ref := g.GetRef()
|
||||
tree, _, err := g.h.Client.Repositories.ListTree(g.GetProjectID(), &gitlab.ListTreeOptions{Path: &path, Ref: &ref})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, node := range tree {
|
||||
if node.Type == TreeType {
|
||||
items, err := g.listAddonItem(make([]Item, 0), node.Path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
addonCandidates[node.Name] = SourceMeta{
|
||||
Name: node.Name,
|
||||
Items: items,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return addonCandidates, nil
|
||||
}
|
||||
|
||||
func (g *gitlabReader) listAddonItem(item []Item, path string) ([]Item, error) {
|
||||
ref := g.GetRef()
|
||||
tree, _, err := g.h.Client.Repositories.ListTree(g.GetProjectID(), &gitlab.ListTreeOptions{Path: &path, Ref: &ref})
|
||||
if err != nil {
|
||||
return item, err
|
||||
}
|
||||
for _, node := range tree {
|
||||
switch node.Type {
|
||||
case TreeType:
|
||||
item, err = g.listAddonItem(item, node.Path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case BlobType:
|
||||
item = append(item, &GitLabItem{
|
||||
basePath: g.GetProjectPath(),
|
||||
tp: FileType,
|
||||
path: node.Path,
|
||||
name: node.Name,
|
||||
})
|
||||
}
|
||||
}
|
||||
return item, nil
|
||||
}
|
||||
|
||||
// ReadFile read file content from gitlab
|
||||
func (g *gitlabReader) ReadFile(path string) (content string, err error) {
|
||||
ref := g.GetRef()
|
||||
getFile, _, err := g.h.Client.RepositoryFiles.GetFile(g.GetProjectID(), g.GetProjectPath()+"/"+path, &gitlab.GetFileOptions{Ref: &ref})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
decodeString, err := base64.StdEncoding.DecodeString(getFile.Content)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(decodeString), nil
|
||||
}
|
||||
|
||||
func (g *gitlabReader) RelativePath(item Item) string {
|
||||
return item.GetPath()
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
/*
|
||||
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 addon
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"path"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/xanzy/go-gitlab"
|
||||
|
||||
"github.com/oam-dev/kubevela/pkg/utils"
|
||||
)
|
||||
|
||||
var baseUrl = "/api/v4"
|
||||
|
||||
func gitlabSetup() (client *gitlab.Client, mux *http.ServeMux, teardown func()) {
|
||||
// mux is the HTTP request multiplexer used with the test server.
|
||||
mux = http.NewServeMux()
|
||||
|
||||
apiHandler := http.NewServeMux()
|
||||
apiHandler.Handle(baseUrl+"/", http.StripPrefix(baseUrl, mux))
|
||||
|
||||
// server is a test HTTP server used to provide mock API responses.
|
||||
server := httptest.NewServer(apiHandler)
|
||||
|
||||
// client is the Gitlab client being tested and is
|
||||
// configured to use test server.
|
||||
client, err := gitlab.NewClient("", gitlab.WithBaseURL(server.URL+baseUrl+"/"))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return client, mux, server.Close
|
||||
}
|
||||
|
||||
func TestGitlabReader(t *testing.T) {
|
||||
client, mux, teardown := gitlabSetup()
|
||||
gitlabPattern := "/projects/9999/repository/files/"
|
||||
mux.HandleFunc(gitlabPattern, func(rw http.ResponseWriter, req *http.Request) {
|
||||
queryPath := strings.TrimPrefix(req.URL.Path, gitlabPattern)
|
||||
localPath := path.Join(testdataPrefix, queryPath)
|
||||
file, err := testdata.ReadFile(localPath)
|
||||
// test if it's a file
|
||||
if err == nil {
|
||||
content := &gitlab.File{
|
||||
FilePath: localPath,
|
||||
FileName: path.Base(queryPath),
|
||||
Size: *Int(len(file)),
|
||||
Encoding: "base64",
|
||||
Ref: "master",
|
||||
Content: base64.StdEncoding.EncodeToString(file),
|
||||
}
|
||||
res, _ := json.Marshal(content)
|
||||
rw.Write(res)
|
||||
return
|
||||
}
|
||||
|
||||
// otherwise, it could be directory
|
||||
dir, err := testdata.ReadDir(localPath)
|
||||
if err == nil {
|
||||
contents := make([]*gitlab.TreeNode, 0)
|
||||
for _, item := range dir {
|
||||
tp := "file"
|
||||
if item.IsDir() {
|
||||
tp = "dir"
|
||||
}
|
||||
contents = append(contents, &gitlab.TreeNode{
|
||||
ID: "",
|
||||
Name: item.Name(),
|
||||
Type: tp,
|
||||
Path: localPath + "/" + item.Name(),
|
||||
Mode: "",
|
||||
})
|
||||
}
|
||||
dRes, _ := json.Marshal(contents)
|
||||
rw.Write(dRes)
|
||||
return
|
||||
}
|
||||
|
||||
rw.Write([]byte("invalid gitlab query"))
|
||||
})
|
||||
defer teardown()
|
||||
|
||||
gith := &gitlabHelper{
|
||||
Client: client,
|
||||
Meta: &utils.Content{GitlabContent: utils.GitlabContent{
|
||||
PId: 9999,
|
||||
}},
|
||||
}
|
||||
var r AsyncReader = &gitlabReader{gith}
|
||||
_, err := r.ReadFile("example/metadata.yaml")
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
@@ -37,11 +37,10 @@ const registriesKey = "registries"
|
||||
type Registry struct {
|
||||
Name string `json:"name"`
|
||||
|
||||
Helm *HelmSource `json:"helm,omitempty"`
|
||||
Git *GitAddonSource `json:"git,omitempty"`
|
||||
OSS *OSSAddonSource `json:"oss,omitempty"`
|
||||
Gitee *GiteeAddonSource `json:"gitee,omitempty"`
|
||||
Gitlab *GitlabAddonSource `json:"gitlab,omitempty"`
|
||||
Helm *HelmSource `json:"helm,omitempty"`
|
||||
Git *GitAddonSource `json:"git,omitempty"`
|
||||
OSS *OSSAddonSource `json:"oss,omitempty"`
|
||||
Gitee *GiteeAddonSource `json:"gitee,omitempty"`
|
||||
}
|
||||
|
||||
// RegistryDataStore CRUD addon registry data in configmap
|
||||
|
||||
@@ -24,7 +24,6 @@ import (
|
||||
|
||||
"github.com/go-resty/resty/v2"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/xanzy/go-gitlab"
|
||||
|
||||
"github.com/oam-dev/kubevela/pkg/utils"
|
||||
)
|
||||
@@ -36,10 +35,6 @@ const (
|
||||
DirType = "dir"
|
||||
// FileType means a file
|
||||
FileType = "file"
|
||||
// BlobType means a blob
|
||||
BlobType = "blob"
|
||||
// TreeType means a tree
|
||||
TreeType = "tree"
|
||||
|
||||
bucketTmpl = "%s://%s.%s"
|
||||
singleOSSFileTmpl = "%s/%s"
|
||||
@@ -68,14 +63,6 @@ type GiteeAddonSource struct {
|
||||
Token string `json:"token,omitempty"`
|
||||
}
|
||||
|
||||
// GitlabAddonSource defines the information about the Gitlab as addon source
|
||||
type GitlabAddonSource struct {
|
||||
URL string `json:"url,omitempty" validate:"required"`
|
||||
Repo string `json:"repo,omitempty" validate:"required"`
|
||||
Path string `json:"path,omitempty"`
|
||||
Token string `json:"token,omitempty"`
|
||||
}
|
||||
|
||||
// HelmSource defines the information about the helm repo addon source
|
||||
type HelmSource struct {
|
||||
URL string `json:"url,omitempty" validate:"required"`
|
||||
@@ -135,16 +122,15 @@ func pathWithParent(subPath, parent string) string {
|
||||
type ReaderType string
|
||||
|
||||
const (
|
||||
gitType ReaderType = "git"
|
||||
ossType ReaderType = "oss"
|
||||
giteeType ReaderType = "gitee"
|
||||
gitlabType ReaderType = "gitlab"
|
||||
gitType ReaderType = "git"
|
||||
ossType ReaderType = "oss"
|
||||
giteeType ReaderType = "gitee"
|
||||
)
|
||||
|
||||
// NewAsyncReader create AsyncReader from
|
||||
// 1. GitHub url and directory
|
||||
// 2. OSS endpoint and bucket
|
||||
func NewAsyncReader(baseURL, bucket, repo, subPath, token string, rdType ReaderType) (AsyncReader, error) {
|
||||
func NewAsyncReader(baseURL, bucket, subPath, token string, rdType ReaderType) (AsyncReader, error) {
|
||||
|
||||
switch rdType {
|
||||
case gitType:
|
||||
@@ -196,63 +182,23 @@ func NewAsyncReader(baseURL, bucket, repo, subPath, token string, rdType ReaderT
|
||||
return &giteeReader{
|
||||
h: gitee,
|
||||
}, nil
|
||||
case gitlabType:
|
||||
baseURL = strings.TrimSuffix(baseURL, ".git")
|
||||
u, err := url.Parse(baseURL)
|
||||
if err != nil {
|
||||
return nil, errors.New("addon registry invalid")
|
||||
}
|
||||
_, content, err := utils.ParseGitlab(u.String(), repo)
|
||||
content.GitlabContent.Path = subPath
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
gitlabHelper, err := createGitlabHelper(content, token)
|
||||
if err != nil {
|
||||
return nil, errors.New("addon registry connect fail")
|
||||
}
|
||||
|
||||
err = gitlabHelper.getGitlabProject(content)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &gitlabReader{
|
||||
h: gitlabHelper,
|
||||
}, nil
|
||||
}
|
||||
return nil, fmt.Errorf("invalid addon registry type '%s'", rdType)
|
||||
}
|
||||
|
||||
// getGitlabProject get gitlab project , set project id
|
||||
func (h *gitlabHelper) getGitlabProject(content *utils.Content) error {
|
||||
projectURL := content.GitlabContent.Owner + "/" + content.GitlabContent.Repo
|
||||
projects, _, err := h.Client.Projects.GetProject(projectURL, &gitlab.GetProjectOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
content.GitlabContent.PId = projects.ID
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// BuildReader will build a AsyncReader from registry, AsyncReader are needed to read addon files
|
||||
func (r *Registry) BuildReader() (AsyncReader, error) {
|
||||
if r.OSS != nil {
|
||||
o := r.OSS
|
||||
return NewAsyncReader(o.Endpoint, o.Bucket, "", o.Path, "", ossType)
|
||||
return NewAsyncReader(o.Endpoint, o.Bucket, o.Path, "", ossType)
|
||||
}
|
||||
if r.Git != nil {
|
||||
g := r.Git
|
||||
return NewAsyncReader(g.URL, "", "", g.Path, g.Token, gitType)
|
||||
return NewAsyncReader(g.URL, "", g.Path, g.Token, gitType)
|
||||
}
|
||||
if r.Gitee != nil {
|
||||
g := r.Gitee
|
||||
return NewAsyncReader(g.URL, "", "", g.Path, g.Token, giteeType)
|
||||
}
|
||||
if r.Gitlab != nil {
|
||||
g := r.Gitlab
|
||||
return NewAsyncReader(g.URL, "", g.Repo, g.Path, g.Token, gitlabType)
|
||||
return NewAsyncReader(g.URL, "", g.Path, g.Token, giteeType)
|
||||
}
|
||||
return nil, errors.New("registry don't have enough info to build a reader")
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ func TestPathWithParent(t *testing.T) {
|
||||
|
||||
func TestConvert2OssItem(t *testing.T) {
|
||||
subPath := "sub-addons"
|
||||
reader, err := NewAsyncReader("ep-beijing.com", "bucket", "", subPath, "", ossType)
|
||||
reader, err := NewAsyncReader("ep-beijing.com", "bucket", subPath, "", ossType)
|
||||
|
||||
assert.NoError(t, err)
|
||||
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
/*
|
||||
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 collect
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/utils/pointer"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/envtest"
|
||||
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/clients"
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/datastore"
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/datastore/kubeapi"
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/datastore/mongodb"
|
||||
"github.com/oam-dev/kubevela/pkg/utils/common"
|
||||
)
|
||||
|
||||
var cfg *rest.Config
|
||||
var k8sClient client.Client
|
||||
var testEnv *envtest.Environment
|
||||
|
||||
func TestCalculateJob(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
RunSpecs(t, "Caclculate systemInfo cronJob")
|
||||
}
|
||||
|
||||
var _ = BeforeSuite(func(done Done) {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
By("bootstrapping test environment")
|
||||
|
||||
testEnv = &envtest.Environment{
|
||||
ControlPlaneStartTimeout: time.Minute * 3,
|
||||
ControlPlaneStopTimeout: time.Minute,
|
||||
UseExistingCluster: pointer.BoolPtr(false),
|
||||
CRDDirectoryPaths: []string{"../../../charts/vela-core/crds"},
|
||||
}
|
||||
|
||||
By("start kube test env")
|
||||
var err error
|
||||
cfg, err = testEnv.Start()
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(cfg).ToNot(BeNil())
|
||||
|
||||
By("new kube client")
|
||||
cfg.Timeout = time.Minute * 2
|
||||
k8sClient, err = client.New(cfg, client.Options{Scheme: common.Scheme})
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(k8sClient).ToNot(BeNil())
|
||||
By("new kube client success")
|
||||
clients.SetKubeClient(k8sClient)
|
||||
Expect(err).Should(BeNil())
|
||||
close(done)
|
||||
}, 240)
|
||||
|
||||
var _ = AfterSuite(func() {
|
||||
By("tearing down the test environment")
|
||||
err := testEnv.Stop()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
})
|
||||
|
||||
func NewDatastore(cfg datastore.Config) (ds datastore.DataStore, err error) {
|
||||
switch cfg.Type {
|
||||
case "mongodb":
|
||||
ds, err = mongodb.New(context.Background(), cfg)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create mongodb datastore instance failure %w", err)
|
||||
}
|
||||
case "kubeapi":
|
||||
ds, err = kubeapi.New(context.Background(), cfg)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create mongodb datastore instance failure %w", err)
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("not support datastore type %s", cfg.Type)
|
||||
}
|
||||
return ds, nil
|
||||
}
|
||||
@@ -1,331 +0,0 @@
|
||||
/*
|
||||
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 collect
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
client2 "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"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"
|
||||
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/clients"
|
||||
"github.com/oam-dev/kubevela/pkg/multicluster"
|
||||
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/datastore"
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/log"
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/model"
|
||||
|
||||
"github.com/robfig/cron/v3"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/client-go/util/retry"
|
||||
)
|
||||
|
||||
// TopKFrequent top frequency component or trait definition
|
||||
var TopKFrequent = 5
|
||||
|
||||
// CrontabSpec the cron spec of job running
|
||||
var CrontabSpec = "0 0 * * *"
|
||||
|
||||
// maximum tires is 5, initial duration is 1 minute
|
||||
var waitBackOff = wait.Backoff{
|
||||
Steps: 5,
|
||||
Duration: 1 * time.Minute,
|
||||
Factor: 5.0,
|
||||
Jitter: 0.1,
|
||||
}
|
||||
|
||||
// InfoCalculateCronJob is the cronJob to calculate the system info store in db
|
||||
type InfoCalculateCronJob struct {
|
||||
ds datastore.DataStore
|
||||
}
|
||||
|
||||
// StartCalculatingInfoCronJob will start the system info calculating job.
|
||||
func StartCalculatingInfoCronJob(ds datastore.DataStore) {
|
||||
i := InfoCalculateCronJob{
|
||||
ds: ds,
|
||||
}
|
||||
|
||||
// run calculate job in 0:00 of every day
|
||||
i.start(CrontabSpec)
|
||||
}
|
||||
|
||||
func (i InfoCalculateCronJob) start(cronSpec string) {
|
||||
c := cron.New(cron.WithChain(
|
||||
// don't let job panic crash whole api-server process
|
||||
cron.Recover(cron.DefaultLogger),
|
||||
))
|
||||
|
||||
// ignore the entityId and error, the cron spec is defined by hard code, mustn't generate error
|
||||
_, _ = c.AddFunc(cronSpec, func() {
|
||||
|
||||
// ExponentialBackoff retry this job
|
||||
err := retry.OnError(waitBackOff, func(err error) bool {
|
||||
// always retry
|
||||
return true
|
||||
}, func() error {
|
||||
if err := i.run(); err != nil {
|
||||
log.Logger.Errorf("Failed to calculate systemInfo, will try again after several minute error %v", err)
|
||||
return err
|
||||
}
|
||||
log.Logger.Info("Successfully to calculate systemInfo")
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
log.Logger.Errorf("After 5 tries the calculating cronJob failed: %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
c.Start()
|
||||
}
|
||||
|
||||
func (i InfoCalculateCronJob) run() error {
|
||||
ctx := context.Background()
|
||||
systemInfo := model.SystemInfo{}
|
||||
e, err := i.ds.List(ctx, &systemInfo, &datastore.ListOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// if no systemInfo means velaux have not have not send get request,so skip calculate job
|
||||
if len(e) == 0 {
|
||||
return nil
|
||||
}
|
||||
info, ok := e[0].(*model.SystemInfo)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
// if disable collection skip calculate job
|
||||
if !info.EnableCollection {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := i.calculateAndUpdate(ctx, *info); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i InfoCalculateCronJob) calculateAndUpdate(ctx context.Context, systemInfo model.SystemInfo) error {
|
||||
|
||||
appCount, topKComp, topKTrait, topWorkflowStep, topKPolicy, err := i.calculateAppInfo(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
enabledAddon, err := i.calculateAddonInfo(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
clusterCount, err := i.calculateClusterInfo(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
statisticInfo := model.StatisticInfo{
|
||||
AppCount: genCountInfo(appCount),
|
||||
TopKCompDef: topKComp,
|
||||
TopKTraitDef: topKTrait,
|
||||
TopKWorkflowStepDef: topWorkflowStep,
|
||||
TopKPolicyDef: topKPolicy,
|
||||
ClusterCount: genClusterCountInfo(clusterCount),
|
||||
EnabledAddon: enabledAddon,
|
||||
UpdateTime: time.Now(),
|
||||
}
|
||||
|
||||
systemInfo.StatisticInfo = statisticInfo
|
||||
if err := i.ds.Put(ctx, &systemInfo); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i InfoCalculateCronJob) calculateAppInfo(ctx context.Context) (int, []string, []string, []string, []string, error) {
|
||||
var err error
|
||||
var appCount int
|
||||
compDef := map[string]int{}
|
||||
traitDef := map[string]int{}
|
||||
workflowDef := map[string]int{}
|
||||
policyDef := map[string]int{}
|
||||
|
||||
var app = model.Application{}
|
||||
entities, err := i.ds.List(ctx, &app, &datastore.ListOptions{})
|
||||
if err != nil {
|
||||
return 0, nil, nil, nil, nil, err
|
||||
}
|
||||
for _, entity := range entities {
|
||||
appModel, ok := entity.(*model.Application)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
appCount++
|
||||
comp := model.ApplicationComponent{
|
||||
AppPrimaryKey: appModel.Name,
|
||||
}
|
||||
comps, err := i.ds.List(ctx, &comp, &datastore.ListOptions{})
|
||||
if err != nil {
|
||||
return 0, nil, nil, nil, nil, err
|
||||
}
|
||||
for _, e := range comps {
|
||||
c, ok := e.(*model.ApplicationComponent)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
compDef[c.Type]++
|
||||
for _, t := range c.Traits {
|
||||
traitDef[t.Type]++
|
||||
}
|
||||
}
|
||||
|
||||
workflow := model.Workflow{
|
||||
AppPrimaryKey: app.PrimaryKey(),
|
||||
}
|
||||
workflows, err := i.ds.List(ctx, &workflow, &datastore.ListOptions{})
|
||||
if err != nil {
|
||||
return 0, nil, nil, nil, nil, err
|
||||
}
|
||||
for _, e := range workflows {
|
||||
w, ok := e.(*model.Workflow)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
for _, step := range w.Steps {
|
||||
workflowDef[step.Type]++
|
||||
}
|
||||
}
|
||||
|
||||
policy := model.ApplicationPolicy{
|
||||
AppPrimaryKey: app.PrimaryKey(),
|
||||
}
|
||||
policies, err := i.ds.List(ctx, &policy, &datastore.ListOptions{})
|
||||
if err != nil {
|
||||
return 0, nil, nil, nil, nil, err
|
||||
}
|
||||
for _, e := range policies {
|
||||
p, ok := e.(*model.ApplicationPolicy)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
policyDef[p.Type]++
|
||||
}
|
||||
}
|
||||
|
||||
return appCount, topKFrequent(compDef, TopKFrequent), topKFrequent(traitDef, TopKFrequent), topKFrequent(workflowDef, TopKFrequent), topKFrequent(policyDef, TopKFrequent), nil
|
||||
}
|
||||
|
||||
func (i InfoCalculateCronJob) calculateAddonInfo(ctx context.Context) (map[string]string, error) {
|
||||
client, err := clients.GetKubeClient()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
apps := &v1beta1.ApplicationList{}
|
||||
if err := client.List(ctx, apps, client2.InNamespace(types.DefaultKubeVelaNS), client2.HasLabels{oam.LabelAddonName}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res := map[string]string{}
|
||||
for _, application := range apps.Items {
|
||||
if addonName := application.Labels[oam.LabelAddonName]; addonName != "" {
|
||||
var status string
|
||||
switch application.Status.Phase {
|
||||
case common.ApplicationRunning:
|
||||
status = "enabled"
|
||||
case common.ApplicationDeleting:
|
||||
status = "disabling"
|
||||
default:
|
||||
status = "enabling"
|
||||
}
|
||||
res[addonName] = status
|
||||
}
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (i InfoCalculateCronJob) calculateClusterInfo(ctx context.Context) (int, error) {
|
||||
client, err := clients.GetKubeClient()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
cs, err := multicluster.ListVirtualClusters(ctx, client)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return len(cs), nil
|
||||
}
|
||||
|
||||
type defPair struct {
|
||||
name string
|
||||
count int
|
||||
}
|
||||
|
||||
func topKFrequent(defs map[string]int, k int) []string {
|
||||
var pairs []defPair
|
||||
var res []string
|
||||
for name, num := range defs {
|
||||
pairs = append(pairs, defPair{name: name, count: num})
|
||||
}
|
||||
sort.Slice(pairs, func(i, j int) bool {
|
||||
return pairs[i].count >= pairs[j].count
|
||||
})
|
||||
i := 0
|
||||
for _, pair := range pairs {
|
||||
res = append(res, pair.name)
|
||||
i++
|
||||
if i == k {
|
||||
break
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func genCountInfo(num int) string {
|
||||
switch {
|
||||
case num < 10:
|
||||
return "<10"
|
||||
case num < 50:
|
||||
return "<50"
|
||||
case num < 100:
|
||||
return "<100"
|
||||
case num < 500:
|
||||
return "<500"
|
||||
case num < 2000:
|
||||
return "<2000"
|
||||
case num < 5000:
|
||||
return "<5000"
|
||||
case num < 10000:
|
||||
return "<10000"
|
||||
default:
|
||||
return ">=10000"
|
||||
}
|
||||
}
|
||||
|
||||
func genClusterCountInfo(num int) string {
|
||||
switch {
|
||||
case num < 3:
|
||||
return "<3"
|
||||
case num < 10:
|
||||
return "<10"
|
||||
case num < 50:
|
||||
return "<50"
|
||||
default:
|
||||
return ">=50"
|
||||
}
|
||||
}
|
||||
@@ -1,273 +0,0 @@
|
||||
/*
|
||||
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 collect
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/onsi/gomega/format"
|
||||
|
||||
"gotest.tools/assert"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"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/pkg/apiserver/datastore"
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/model"
|
||||
"github.com/oam-dev/kubevela/pkg/oam"
|
||||
"github.com/oam-dev/kubevela/pkg/oam/util"
|
||||
)
|
||||
|
||||
var _ = Describe("Test calculate cronJob", func() {
|
||||
var (
|
||||
ds datastore.DataStore
|
||||
testProject string
|
||||
i InfoCalculateCronJob
|
||||
ctx = context.Background()
|
||||
)
|
||||
|
||||
mockDataInDs := func() {
|
||||
app1 := model.Application{BaseModel: model.BaseModel{CreateTime: time.Now()}, Name: "app1", Project: testProject}
|
||||
app2 := model.Application{BaseModel: model.BaseModel{CreateTime: time.Now()}, Name: "app2", Project: testProject}
|
||||
trait1 := model.ApplicationTrait{Type: "rollout"}
|
||||
trait2 := model.ApplicationTrait{Type: "expose"}
|
||||
trait3 := model.ApplicationTrait{Type: "rollout"}
|
||||
trait4 := model.ApplicationTrait{Type: "patch"}
|
||||
trait5 := model.ApplicationTrait{Type: "patch"}
|
||||
trait6 := model.ApplicationTrait{Type: "rollout"}
|
||||
appComp1 := model.ApplicationComponent{AppPrimaryKey: app1.PrimaryKey(), Name: "comp1", Type: "helm", Traits: []model.ApplicationTrait{trait1, trait4}}
|
||||
appComp2 := model.ApplicationComponent{AppPrimaryKey: app2.PrimaryKey(), Name: "comp2", Type: "webservice", Traits: []model.ApplicationTrait{trait3}}
|
||||
appComp3 := model.ApplicationComponent{AppPrimaryKey: app2.PrimaryKey(), Name: "comp3", Type: "webservice", Traits: []model.ApplicationTrait{trait2, trait5, trait6}}
|
||||
Expect(ds.Add(ctx, &app1)).Should(SatisfyAny(BeNil(), DataExistMatcher{}))
|
||||
Expect(ds.Add(ctx, &app2)).Should(SatisfyAny(BeNil(), DataExistMatcher{}))
|
||||
Expect(ds.Add(ctx, &appComp1)).Should(SatisfyAny(BeNil(), DataExistMatcher{}))
|
||||
Expect(ds.Add(ctx, &appComp2)).Should(SatisfyAny(BeNil(), DataExistMatcher{}))
|
||||
Expect(ds.Add(ctx, &appComp3)).Should(SatisfyAny(BeNil(), DataExistMatcher{}))
|
||||
Expect(k8sClient.Create(ctx, &v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "vela-system"}})).Should(SatisfyAny(BeNil(), util.AlreadyExistMatcher{}))
|
||||
Expect(k8sClient.Create(ctx, &v1beta1.Application{ObjectMeta: metav1.ObjectMeta{Namespace: "vela-system", Name: "addon-fluxcd", Labels: map[string]string{oam.LabelAddonName: "fluxcd"}}, Spec: v1beta1.ApplicationSpec{
|
||||
Components: []common.ApplicationComponent{},
|
||||
}})).Should(SatisfyAny(BeNil(), util.AlreadyExistMatcher{}))
|
||||
Expect(k8sClient.Create(ctx, &v1beta1.Application{ObjectMeta: metav1.ObjectMeta{Namespace: "vela-system", Name: "addon-rollout", Labels: map[string]string{oam.LabelAddonName: "rollout"}}, Spec: v1beta1.ApplicationSpec{
|
||||
Components: []common.ApplicationComponent{},
|
||||
}})).Should(SatisfyAny(BeNil(), util.AlreadyExistMatcher{}))
|
||||
}
|
||||
|
||||
BeforeEach(func() {
|
||||
var err error
|
||||
ds, err = NewDatastore(datastore.Config{Type: "kubeapi", Database: "target-test-kubevela"})
|
||||
Expect(ds).ShouldNot(BeNil())
|
||||
Expect(err).Should(BeNil())
|
||||
|
||||
testProject = "test-cronjob-project"
|
||||
mockDataInDs()
|
||||
i = InfoCalculateCronJob{
|
||||
ds: ds,
|
||||
}
|
||||
systemInfo := model.SystemInfo{InstallID: "test-id", EnableCollection: true}
|
||||
Expect(ds.Add(ctx, &systemInfo)).Should(SatisfyAny(BeNil(), DataExistMatcher{}))
|
||||
})
|
||||
|
||||
It("Test calculate app Info", func() {
|
||||
appNum, topKCom, topKTrait, _, _, err := i.calculateAppInfo(ctx)
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(appNum).Should(BeEquivalentTo(2))
|
||||
Expect(topKCom).Should(BeEquivalentTo([]string{"webservice", "helm"}))
|
||||
Expect(topKTrait).Should(BeEquivalentTo([]string{"rollout", "patch", "expose"}))
|
||||
})
|
||||
|
||||
It("Test calculate addon Info", func() {
|
||||
enabledAddon, err := i.calculateAddonInfo(ctx)
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(enabledAddon).Should(BeEquivalentTo(map[string]string{
|
||||
"fluxcd": "enabling",
|
||||
"rollout": "enabling",
|
||||
}))
|
||||
})
|
||||
|
||||
It("Test calculate cluster Info", func() {
|
||||
clusterNum, err := i.calculateClusterInfo(ctx)
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(clusterNum).Should(BeEquivalentTo(1))
|
||||
})
|
||||
|
||||
It("Test calculateAndUpdate func", func() {
|
||||
systemInfo := model.SystemInfo{}
|
||||
es, err := ds.List(ctx, &systemInfo, &datastore.ListOptions{})
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(len(es)).Should(BeEquivalentTo(1))
|
||||
info, ok := es[0].(*model.SystemInfo)
|
||||
Expect(ok).Should(BeTrue())
|
||||
Expect(info.InstallID).Should(BeEquivalentTo("test-id"))
|
||||
|
||||
Expect(i.calculateAndUpdate(ctx, *info)).Should(BeNil())
|
||||
|
||||
systemInfo = model.SystemInfo{}
|
||||
es, err = ds.List(ctx, &systemInfo, &datastore.ListOptions{})
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(len(es)).Should(BeEquivalentTo(1))
|
||||
info, ok = es[0].(*model.SystemInfo)
|
||||
Expect(ok).Should(BeTrue())
|
||||
Expect(info.InstallID).Should(BeEquivalentTo("test-id"))
|
||||
Expect(info.StatisticInfo.AppCount).Should(BeEquivalentTo("<10"))
|
||||
Expect(info.StatisticInfo.ClusterCount).Should(BeEquivalentTo("<3"))
|
||||
Expect(info.StatisticInfo.TopKCompDef).Should(BeEquivalentTo([]string{"webservice", "helm"}))
|
||||
Expect(info.StatisticInfo.TopKTraitDef).Should(BeEquivalentTo([]string{"rollout", "patch", "expose"}))
|
||||
Expect(info.StatisticInfo.EnabledAddon).Should(BeEquivalentTo(map[string]string{
|
||||
"fluxcd": "enabling",
|
||||
"rollout": "enabling",
|
||||
}))
|
||||
})
|
||||
|
||||
It("Test run func", func() {
|
||||
app3 := model.Application{BaseModel: model.BaseModel{CreateTime: time.Now()}, Name: "app3", Project: testProject}
|
||||
Expect(ds.Add(ctx, &app3)).Should(BeNil())
|
||||
|
||||
systemInfo := model.SystemInfo{InstallID: "test-id", EnableCollection: false}
|
||||
Expect(ds.Put(ctx, &systemInfo)).Should(BeNil())
|
||||
Expect(i.run()).Should(BeNil())
|
||||
})
|
||||
})
|
||||
|
||||
func TestGenCountInfo(t *testing.T) {
|
||||
testcases := []struct {
|
||||
count int
|
||||
res string
|
||||
}{
|
||||
{
|
||||
count: 3,
|
||||
res: "<10",
|
||||
},
|
||||
{
|
||||
count: 14,
|
||||
res: "<50",
|
||||
},
|
||||
{
|
||||
count: 80,
|
||||
res: "<100",
|
||||
},
|
||||
{
|
||||
count: 350,
|
||||
res: "<500",
|
||||
},
|
||||
{
|
||||
count: 1800,
|
||||
res: "<2000",
|
||||
},
|
||||
{
|
||||
count: 4000,
|
||||
res: "<5000",
|
||||
},
|
||||
{
|
||||
count: 9000,
|
||||
res: "<10000",
|
||||
},
|
||||
{
|
||||
count: 30000,
|
||||
res: ">=10000",
|
||||
},
|
||||
}
|
||||
for _, testcase := range testcases {
|
||||
assert.Equal(t, genCountInfo(testcase.count), testcase.res)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenClusterCountInfo(t *testing.T) {
|
||||
testcases := []struct {
|
||||
count int
|
||||
res string
|
||||
}{
|
||||
{
|
||||
count: 2,
|
||||
res: "<3",
|
||||
},
|
||||
{
|
||||
count: 7,
|
||||
res: "<10",
|
||||
},
|
||||
{
|
||||
count: 34,
|
||||
res: "<50",
|
||||
},
|
||||
{
|
||||
count: 100,
|
||||
res: ">=50",
|
||||
},
|
||||
}
|
||||
for _, testcase := range testcases {
|
||||
assert.Equal(t, genClusterCountInfo(testcase.count), testcase.res)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTopKFrequent(t *testing.T) {
|
||||
testCases := []struct {
|
||||
def map[string]int
|
||||
k int
|
||||
res []string
|
||||
}{
|
||||
{
|
||||
def: map[string]int{
|
||||
"rollout": 4,
|
||||
"patch": 3,
|
||||
"expose": 6,
|
||||
},
|
||||
k: 3,
|
||||
res: []string{"expose", "rollout", "patch"},
|
||||
},
|
||||
{
|
||||
// just return top2
|
||||
def: map[string]int{
|
||||
"rollout": 4,
|
||||
"patch": 3,
|
||||
"expose": 6,
|
||||
},
|
||||
k: 2,
|
||||
res: []string{"expose", "rollout"},
|
||||
},
|
||||
}
|
||||
for _, testCase := range testCases {
|
||||
assert.DeepEqual(t, topKFrequent(testCase.def, testCase.k), testCase.res)
|
||||
}
|
||||
}
|
||||
|
||||
type DataExistMatcher struct{}
|
||||
|
||||
// Match matches error.
|
||||
func (matcher DataExistMatcher) Match(actual interface{}) (success bool, err error) {
|
||||
if actual == nil {
|
||||
return false, nil
|
||||
}
|
||||
actualError := actual.(error)
|
||||
return errors.Is(actualError, datastore.ErrRecordExist), nil
|
||||
}
|
||||
|
||||
// FailureMessage builds an error message.
|
||||
func (matcher DataExistMatcher) FailureMessage(actual interface{}) (message string) {
|
||||
return format.Message(actual, "to be already exist")
|
||||
}
|
||||
|
||||
// NegatedFailureMessage builds an error message.
|
||||
func (matcher DataExistMatcher) NegatedFailureMessage(actual interface{}) (message string) {
|
||||
return format.Message(actual, "not to be already exist")
|
||||
}
|
||||
@@ -16,8 +16,6 @@ limitations under the License.
|
||||
|
||||
package model
|
||||
|
||||
import "time"
|
||||
|
||||
func init() {
|
||||
RegisterModel(&SystemInfo{})
|
||||
}
|
||||
@@ -32,11 +30,10 @@ const (
|
||||
// SystemInfo systemInfo model
|
||||
type SystemInfo struct {
|
||||
BaseModel
|
||||
InstallID string `json:"installID"`
|
||||
EnableCollection bool `json:"enableCollection"`
|
||||
LoginType string `json:"loginType"`
|
||||
DexConfig DexConfig `json:"dexConfig,omitempty"`
|
||||
StatisticInfo StatisticInfo `json:"statisticInfo,omitempty"`
|
||||
InstallID string `json:"installID"`
|
||||
EnableCollection bool `json:"enableCollection"`
|
||||
LoginType string `json:"loginType"`
|
||||
DexConfig DexConfig `json:"dexConfig,omitempty"`
|
||||
}
|
||||
|
||||
// DexConfig dex config
|
||||
@@ -49,18 +46,6 @@ type DexConfig struct {
|
||||
EnablePasswordDB bool `json:"enablePasswordDB"`
|
||||
}
|
||||
|
||||
// StatisticInfo the system statistic info
|
||||
type StatisticInfo struct {
|
||||
ClusterCount string `json:"clusterCount,omitempty"`
|
||||
AppCount string `json:"appCount,omitempty"`
|
||||
EnabledAddon map[string]string `json:"enabledAddon,omitempty"`
|
||||
TopKCompDef []string `json:"topKCompDef,omitempty"`
|
||||
TopKTraitDef []string `json:"topKTraitDef,omitempty"`
|
||||
TopKWorkflowStepDef []string `json:"topKWorkflowStepDef,omitempty"`
|
||||
TopKPolicyDef []string `json:"topKPolicyDef,omitempty"`
|
||||
UpdateTime time.Time `json:"updateTime,omitempty"`
|
||||
}
|
||||
|
||||
// DexStorage dex storage
|
||||
type DexStorage struct {
|
||||
Type string `json:"type"`
|
||||
|
||||
@@ -74,31 +74,28 @@ type NameAlias struct {
|
||||
|
||||
// CreateAddonRegistryRequest defines the format for addon registry create request
|
||||
type CreateAddonRegistryRequest struct {
|
||||
Name string `json:"name" validate:"checkname"`
|
||||
Helm *addon.HelmSource `json:"helm,omitempty"`
|
||||
Git *addon.GitAddonSource `json:"git,omitempty" `
|
||||
Oss *addon.OSSAddonSource `json:"oss,omitempty"`
|
||||
Gitee *addon.GiteeAddonSource `json:"gitee,omitempty" `
|
||||
Gitlab *addon.GitlabAddonSource `json:"gitlab,omitempty" `
|
||||
Name string `json:"name" validate:"checkname"`
|
||||
Helm *addon.HelmSource `json:"helm,omitempty"`
|
||||
Git *addon.GitAddonSource `json:"git,omitempty" `
|
||||
Oss *addon.OSSAddonSource `json:"oss,omitempty"`
|
||||
Gitee *addon.GiteeAddonSource `json:"gitee,omitempty" `
|
||||
}
|
||||
|
||||
// UpdateAddonRegistryRequest defines the format for addon registry update request
|
||||
type UpdateAddonRegistryRequest struct {
|
||||
Helm *addon.HelmSource `json:"helm,omitempty"`
|
||||
Git *addon.GitAddonSource `json:"git,omitempty"`
|
||||
Oss *addon.OSSAddonSource `json:"oss,omitempty"`
|
||||
Gitee *addon.GiteeAddonSource `json:"gitee,omitempty" `
|
||||
Gitlab *addon.GitlabAddonSource `json:"gitlab,omitempty" `
|
||||
Helm *addon.HelmSource `json:"helm,omitempty"`
|
||||
Git *addon.GitAddonSource `json:"git,omitempty"`
|
||||
Oss *addon.OSSAddonSource `json:"oss,omitempty"`
|
||||
Gitee *addon.GiteeAddonSource `json:"gitee,omitempty" `
|
||||
}
|
||||
|
||||
// AddonRegistry defines the format for a single addon registry
|
||||
type AddonRegistry struct {
|
||||
Name string `json:"name" validate:"required"`
|
||||
Helm *addon.HelmSource `json:"helm,omitempty"`
|
||||
Git *addon.GitAddonSource `json:"git,omitempty"`
|
||||
OSS *addon.OSSAddonSource `json:"oss,omitempty"`
|
||||
Gitee *addon.GiteeAddonSource `json:"gitee,omitempty" `
|
||||
Gitlab *addon.GitlabAddonSource `json:"gitlab,omitempty" `
|
||||
Name string `json:"name" validate:"required"`
|
||||
Helm *addon.HelmSource `json:"helm,omitempty"`
|
||||
Git *addon.GitAddonSource `json:"git,omitempty"`
|
||||
OSS *addon.OSSAddonSource `json:"oss,omitempty"`
|
||||
Gitee *addon.GiteeAddonSource `json:"gitee,omitempty" `
|
||||
}
|
||||
|
||||
// ListAddonRegistryResponse list addon registry
|
||||
@@ -202,7 +199,6 @@ type Config struct {
|
||||
Name string `json:"name"`
|
||||
Project string `json:"project"`
|
||||
Identifier string `json:"identifier"`
|
||||
Alias string `json:"alias"`
|
||||
Description string `json:"description"`
|
||||
CreatedTime *time.Time `json:"createdTime"`
|
||||
UpdatedTime *time.Time `json:"updatedTime"`
|
||||
@@ -412,7 +408,6 @@ type CreateApplicationRequest struct {
|
||||
type CreateConfigRequest struct {
|
||||
Name string `json:"name" validate:"checkname"`
|
||||
Alias string `json:"alias"`
|
||||
Description string `json:"description"`
|
||||
Project string `json:"project"`
|
||||
ComponentType string `json:"componentType" validate:"checkname"`
|
||||
Properties string `json:"properties,omitempty"`
|
||||
@@ -1119,27 +1114,13 @@ type DetailRevisionResponse struct {
|
||||
type SystemInfoResponse struct {
|
||||
SystemInfo
|
||||
SystemVersion SystemVersion `json:"systemVersion"`
|
||||
StatisticInfo StatisticInfo `json:"statisticInfo,omitempty"`
|
||||
}
|
||||
|
||||
// SystemInfo system info
|
||||
type SystemInfo struct {
|
||||
PlatformID string `json:"platformID"`
|
||||
EnableCollection bool `json:"enableCollection"`
|
||||
LoginType string `json:"loginType"`
|
||||
InstallTime time.Time `json:"installTime,omitempty"`
|
||||
}
|
||||
|
||||
// StatisticInfo generated by cronJob running in backend
|
||||
type StatisticInfo struct {
|
||||
ClusterCount string `json:"clusterCount,omitempty"`
|
||||
AppCount string `json:"appCount,omitempty"`
|
||||
EnableAddonList map[string]string `json:"enableAddonList,omitempty"`
|
||||
ComponentDefinitionTopList []string `json:"componentDefinitionTopList,omitempty"`
|
||||
TraitDefinitionTopList []string `json:"traitDefinitionTopList,omitempty"`
|
||||
WorkflowDefinitionTopList []string `json:"workflowDefinitionTopList,omitempty"`
|
||||
PolicyDefinitionTopList []string `json:"policyDefinitionTopList,omitempty"`
|
||||
UpdateTime time.Time `json:"updateTime,omitempty"`
|
||||
InstallID string `json:"installID"`
|
||||
EnableCollection bool `json:"enableCollection"`
|
||||
LoginType string `json:"loginType"`
|
||||
}
|
||||
|
||||
// SystemInfoRequest request by update SystemInfo
|
||||
|
||||
@@ -23,8 +23,6 @@ import (
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/collect"
|
||||
|
||||
restfulspec "github.com/emicklei/go-restful-openapi/v2"
|
||||
"github.com/emicklei/go-restful/v3"
|
||||
"github.com/go-openapi/spec"
|
||||
@@ -62,9 +60,6 @@ type Config struct {
|
||||
|
||||
// AddonCacheTime is how long between two cache operations
|
||||
AddonCacheTime time.Duration
|
||||
|
||||
// DisableStatisticCronJob close the calculate system info cronJob
|
||||
DisableStatisticCronJob bool
|
||||
}
|
||||
|
||||
type leaderConfig struct {
|
||||
@@ -146,10 +141,6 @@ func (s *restServer) setupLeaderElection() (*leaderelection.LeaderElectionConfig
|
||||
Callbacks: leaderelection.LeaderCallbacks{
|
||||
OnStartedLeading: func(ctx context.Context) {
|
||||
go velasync.Start(ctx, s.dataStore, restCfg, s.usecases)
|
||||
if !s.cfg.DisableStatisticCronJob {
|
||||
collect.StartCalculatingInfoCronJob(s.dataStore)
|
||||
}
|
||||
// this process would block the whole process, any other handler should start before this func
|
||||
s.runWorkflowRecordSync(ctx, s.cfg.LeaderConfig.Duration)
|
||||
},
|
||||
OnStoppedLeading: func() {
|
||||
|
||||
@@ -313,12 +313,11 @@ func (u *defaultAddonHandler) CreateAddonRegistry(ctx context.Context, req apis.
|
||||
|
||||
func convertAddonRegistry(r pkgaddon.Registry) *apis.AddonRegistry {
|
||||
return &apis.AddonRegistry{
|
||||
Name: r.Name,
|
||||
Git: r.Git,
|
||||
Gitee: r.Gitee,
|
||||
OSS: r.OSS,
|
||||
Helm: r.Helm,
|
||||
Gitlab: r.Gitlab,
|
||||
Name: r.Name,
|
||||
Git: r.Git,
|
||||
Gitee: r.Gitee,
|
||||
OSS: r.OSS,
|
||||
Helm: r.Helm,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -344,8 +343,6 @@ func (u defaultAddonHandler) UpdateAddonRegistry(ctx context.Context, name strin
|
||||
r.OSS = req.Oss
|
||||
case req.Helm != nil:
|
||||
r.Helm = req.Helm
|
||||
case req.Gitlab != nil:
|
||||
r.Gitlab = req.Gitlab
|
||||
}
|
||||
|
||||
err = u.addonRegistryDS.UpdateRegistry(ctx, r)
|
||||
@@ -479,12 +476,11 @@ func (u *defaultAddonHandler) UpdateAddon(ctx context.Context, name string, args
|
||||
|
||||
func addonRegistryModelFromCreateAddonRegistryRequest(req apis.CreateAddonRegistryRequest) pkgaddon.Registry {
|
||||
return pkgaddon.Registry{
|
||||
Name: req.Name,
|
||||
Git: req.Git,
|
||||
OSS: req.Oss,
|
||||
Gitee: req.Gitee,
|
||||
Helm: req.Helm,
|
||||
Gitlab: req.Gitlab,
|
||||
Name: req.Name,
|
||||
Git: req.Git,
|
||||
OSS: req.Oss,
|
||||
Gitee: req.Gitee,
|
||||
Helm: req.Helm,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
set "github.com/deckarep/golang-set"
|
||||
"github.com/pkg/errors"
|
||||
@@ -135,27 +134,12 @@ func (u *configUseCaseImpl) GetConfigType(ctx context.Context, configType string
|
||||
}
|
||||
|
||||
func (u *configUseCaseImpl) CreateConfig(ctx context.Context, req apis.CreateConfigRequest) error {
|
||||
p := req.Properties
|
||||
// If the component is Terraform type, set the provider name same as the application name and the component name
|
||||
if strings.HasPrefix(req.ComponentType, types.TerrfaormComponentPrefix) {
|
||||
var properties map[string]interface{}
|
||||
if err := json.Unmarshal([]byte(p), &properties); err != nil {
|
||||
return errors.Wrapf(err, "unable to process the properties of %s", req.ComponentType)
|
||||
}
|
||||
properties["name"] = req.Name
|
||||
tmp, err := json.Marshal(properties)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "unable to process the properties of %s", req.ComponentType)
|
||||
}
|
||||
p = string(tmp)
|
||||
}
|
||||
app := v1beta1.Application{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: req.Name,
|
||||
Namespace: types.DefaultKubeVelaNS,
|
||||
Annotations: map[string]string{
|
||||
types.AnnotationConfigAlias: req.Alias,
|
||||
types.AnnotationConfigDescription: req.Description,
|
||||
types.AnnotationConfigAlias: req.Alias,
|
||||
},
|
||||
Labels: map[string]string{
|
||||
model.LabelSourceOfTruth: model.FromInner,
|
||||
@@ -169,7 +153,7 @@ func (u *configUseCaseImpl) CreateConfig(ctx context.Context, req apis.CreateCon
|
||||
{
|
||||
Name: req.Name,
|
||||
Type: req.ComponentType,
|
||||
Properties: &runtime.RawExtension{Raw: []byte(p)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(req.Properties)},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -217,7 +201,12 @@ func (u *configUseCaseImpl) getConfigsByConfigType(ctx context.Context, configTy
|
||||
|
||||
configs := make([]*apis.Config, len(apps.Items))
|
||||
for i, a := range apps.Items {
|
||||
configs[i] = retrieveConfigFromApplication(a, a.Labels[types.LabelConfigProject])
|
||||
configs[i] = &apis.Config{
|
||||
ConfigType: a.Labels[types.LabelConfigType],
|
||||
Name: a.Name,
|
||||
Project: a.Labels[types.LabelConfigProject],
|
||||
CreatedTime: &(a.CreationTimestamp.Time),
|
||||
}
|
||||
switch a.Status.Phase {
|
||||
case common.ApplicationRunning:
|
||||
configs[i].Status = configIsReady
|
||||
|
||||
@@ -236,11 +236,6 @@ func TestCreateConfig(t *testing.T) {
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
properties, err := json.Marshal(map[string]interface{}{
|
||||
"name": "default",
|
||||
})
|
||||
assert.NilError(t, err)
|
||||
|
||||
testcases := []struct {
|
||||
name string
|
||||
args args
|
||||
@@ -257,18 +252,6 @@ func TestCreateConfig(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "create terraform-alibaba config",
|
||||
args: args{
|
||||
h: h,
|
||||
req: apis.CreateConfigRequest{
|
||||
Name: "n1",
|
||||
ComponentType: "terraform-alibaba",
|
||||
Project: "p1",
|
||||
Properties: string(properties),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testcases {
|
||||
|
||||
@@ -190,7 +190,7 @@ func (d *definitionUsecaseImpl) listDefinitions(ctx context.Context, list *unstr
|
||||
|
||||
// DetailDefinition get definition detail
|
||||
func (d *definitionUsecaseImpl) DetailDefinition(ctx context.Context, name, defType string) (*apisv1.DetailDefinitionResponse, error) {
|
||||
if !utils.StringsContain([]string{"component", "trait", "workflowstep", "policy"}, defType) {
|
||||
if !utils.StringsContain([]string{"component", "trait", "workflowstep"}, defType) {
|
||||
return nil, bcode.ErrDefinitionTypeNotSupport
|
||||
}
|
||||
var cm v1.ConfigMap
|
||||
|
||||
@@ -520,10 +520,16 @@ func (p *projectUsecaseImpl) GetConfigs(ctx context.Context, projectName, config
|
||||
for _, a := range apps.Items {
|
||||
appProject := a.Labels[types.LabelConfigProject]
|
||||
if a.Status.Phase != common.ApplicationRunning || (appProject != "" && appProject != projectName) ||
|
||||
!strings.Contains(a.Labels[types.LabelConfigType], types.TerrfaormComponentPrefix) {
|
||||
!strings.Contains(a.Labels[types.LabelConfigType], "terraform-") {
|
||||
continue
|
||||
}
|
||||
configs = append(configs, retrieveConfigFromApplication(a, appProject))
|
||||
configs = append(configs, &apisv1.Config{
|
||||
ConfigType: a.Labels[types.LabelConfigType],
|
||||
Name: a.Name,
|
||||
Project: appProject,
|
||||
CreatedTime: &(a.CreationTimestamp.Time),
|
||||
ApplicationStatus: a.Status.Phase,
|
||||
})
|
||||
}
|
||||
|
||||
configs = append(configs, legacyTerraformProviders...)
|
||||
@@ -533,7 +539,13 @@ func (p *projectUsecaseImpl) GetConfigs(ctx context.Context, projectName, config
|
||||
if appProject != "" && appProject != projectName {
|
||||
continue
|
||||
}
|
||||
configs = append(configs, retrieveConfigFromApplication(a, appProject))
|
||||
configs = append(configs, &apisv1.Config{
|
||||
ConfigType: a.Labels[types.LabelConfigType],
|
||||
Name: a.Name,
|
||||
Project: appProject,
|
||||
CreatedTime: &(a.CreationTimestamp.Time),
|
||||
ApplicationStatus: a.Status.Phase,
|
||||
})
|
||||
}
|
||||
configs = append(configs, legacyTerraformProviders...)
|
||||
case types.DexConnector, types.HelmRepository, types.ImageRegistry:
|
||||
@@ -544,7 +556,13 @@ func (p *projectUsecaseImpl) GetConfigs(ctx context.Context, projectName, config
|
||||
continue
|
||||
}
|
||||
if a.Labels[types.LabelConfigType] == t {
|
||||
configs = append(configs, retrieveConfigFromApplication(a, appProject))
|
||||
configs = append(configs, &apisv1.Config{
|
||||
ConfigType: a.Labels[types.LabelConfigType],
|
||||
Name: a.Name,
|
||||
Project: appProject,
|
||||
CreatedTime: &(a.CreationTimestamp.Time),
|
||||
ApplicationStatus: a.Status.Phase,
|
||||
})
|
||||
}
|
||||
}
|
||||
default:
|
||||
@@ -598,15 +616,3 @@ func ConvertProjectUserModel2Base(user *model.ProjectUser) *apisv1.ProjectUserBa
|
||||
}
|
||||
return base
|
||||
}
|
||||
|
||||
func retrieveConfigFromApplication(a v1beta1.Application, project string) *apisv1.Config {
|
||||
return &apisv1.Config{
|
||||
ConfigType: a.Labels[types.LabelConfigType],
|
||||
Name: a.Name,
|
||||
Project: project,
|
||||
CreatedTime: &(a.CreationTimestamp.Time),
|
||||
ApplicationStatus: a.Status.Phase,
|
||||
Alias: a.Annotations[types.AnnotationConfigAlias],
|
||||
Description: a.Annotations[types.AnnotationConfigDescription],
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
@@ -82,7 +81,6 @@ func (u systemInfoUsecaseImpl) Get(ctx context.Context) (*model.SystemInfo, erro
|
||||
info.InstallID = installID
|
||||
info.EnableCollection = true
|
||||
info.LoginType = model.LoginTypeLocal
|
||||
info.BaseModel = model.BaseModel{CreateTime: time.Now()}
|
||||
err = u.ds.Add(ctx, info)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -102,16 +100,6 @@ func (u systemInfoUsecaseImpl) GetSystemInfo(ctx context.Context) (*v1.SystemInf
|
||||
VelaVersion: version.VelaVersion,
|
||||
GitVersion: version.GitRevision,
|
||||
},
|
||||
StatisticInfo: v1.StatisticInfo{
|
||||
AppCount: info.StatisticInfo.AppCount,
|
||||
ClusterCount: info.StatisticInfo.ClusterCount,
|
||||
EnableAddonList: info.StatisticInfo.EnabledAddon,
|
||||
ComponentDefinitionTopList: info.StatisticInfo.TopKCompDef,
|
||||
TraitDefinitionTopList: info.StatisticInfo.TopKTraitDef,
|
||||
WorkflowDefinitionTopList: info.StatisticInfo.TopKWorkflowStepDef,
|
||||
PolicyDefinitionTopList: info.StatisticInfo.TopKPolicyDef,
|
||||
UpdateTime: info.StatisticInfo.UpdateTime,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -126,9 +114,7 @@ func (u systemInfoUsecaseImpl) UpdateSystemInfo(ctx context.Context, sysInfo v1.
|
||||
LoginType: sysInfo.LoginType,
|
||||
BaseModel: model.BaseModel{
|
||||
CreateTime: info.CreateTime,
|
||||
UpdateTime: time.Now(),
|
||||
},
|
||||
StatisticInfo: info.StatisticInfo,
|
||||
}
|
||||
|
||||
if sysInfo.LoginType == model.LoginTypeDex {
|
||||
@@ -149,11 +135,9 @@ func (u systemInfoUsecaseImpl) UpdateSystemInfo(ctx context.Context, sysInfo v1.
|
||||
}
|
||||
return &v1.SystemInfoResponse{
|
||||
SystemInfo: v1.SystemInfo{
|
||||
PlatformID: modifiedInfo.InstallID,
|
||||
InstallID: modifiedInfo.InstallID,
|
||||
EnableCollection: modifiedInfo.EnableCollection,
|
||||
LoginType: modifiedInfo.LoginType,
|
||||
// always use the initial createTime as system's installTime
|
||||
InstallTime: info.CreateTime,
|
||||
},
|
||||
SystemVersion: v1.SystemVersion{VelaVersion: version.VelaVersion, GitVersion: version.GitRevision},
|
||||
}, nil
|
||||
@@ -171,10 +155,9 @@ func (u systemInfoUsecaseImpl) Init(ctx context.Context) error {
|
||||
|
||||
func convertInfoToBase(info *model.SystemInfo) v1.SystemInfo {
|
||||
return v1.SystemInfo{
|
||||
PlatformID: info.InstallID,
|
||||
InstallID: info.InstallID,
|
||||
EnableCollection: info.EnableCollection,
|
||||
LoginType: info.LoginType,
|
||||
InstallTime: info.CreateTime,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -296,7 +296,7 @@ func (s *enabledAddonWebService) GetWebService() *restful.WebService {
|
||||
Filter(s.rbacUsecase.CheckPerm("addon", "list")).
|
||||
Param(ws.QueryParameter("registry", "filter addons from given registry").DataType("string")).
|
||||
Param(ws.QueryParameter("query", "Fuzzy search based on name and description.").DataType("string")).
|
||||
Returns(200, "OK", apis.ListEnabledAddonResponse{}).
|
||||
Returns(200, "OK", apis.ListAddonResponse{}).
|
||||
Returns(400, "Bad Request", bcode.Bcode{}).
|
||||
Writes(apis.ListAddonResponse{}))
|
||||
|
||||
|
||||
@@ -22,11 +22,11 @@ import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/emicklei/go-restful/v3"
|
||||
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/datastore"
|
||||
apisv1 "github.com/oam-dev/kubevela/pkg/apiserver/rest/apis/v1"
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/rest/usecase"
|
||||
|
||||
"github.com/emicklei/go-restful/v3"
|
||||
)
|
||||
|
||||
// versionPrefix API version prefix.
|
||||
|
||||
@@ -182,8 +182,6 @@ type Appfile struct {
|
||||
|
||||
parser *Parser
|
||||
app *v1beta1.Application
|
||||
|
||||
Debug bool
|
||||
}
|
||||
|
||||
// GeneratePolicyManifests generates policy manifests from an appFile
|
||||
|
||||
@@ -345,8 +345,6 @@ func (p *Parser) parsePoliciesFromRevision(ctx context.Context, af *Appfile) (er
|
||||
case v1alpha1.EnvBindingPolicyType:
|
||||
case v1alpha1.TopologyPolicyType:
|
||||
case v1alpha1.OverridePolicyType:
|
||||
case v1alpha1.DebugPolicyType:
|
||||
af.Debug = true
|
||||
default:
|
||||
w, err := p.makeWorkloadFromRevision(policy.Name, policy.Type, types.TypePolicy, policy.Properties, af.AppRevision)
|
||||
if err != nil {
|
||||
@@ -369,8 +367,6 @@ func (p *Parser) parsePolicies(ctx context.Context, af *Appfile) (err error) {
|
||||
case v1alpha1.ApplyOncePolicyType:
|
||||
case v1alpha1.EnvBindingPolicyType:
|
||||
case v1alpha1.TopologyPolicyType:
|
||||
case v1alpha1.DebugPolicyType:
|
||||
af.Debug = true
|
||||
case v1alpha1.OverridePolicyType:
|
||||
compDefs, traitDefs, err := policypkg.ParseOverridePolicyRelatedDefinitions(ctx, p.client, af.app, policy)
|
||||
if err != nil {
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
Copyright 2022 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 auth
|
||||
|
||||
import (
|
||||
"k8s.io/apiserver/pkg/authentication/user"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/types"
|
||||
)
|
||||
|
||||
const (
|
||||
// DefaultAuthenticateGroupPattern default value of groups patterns for authentication
|
||||
DefaultAuthenticateGroupPattern = types.KubeVelaName + ":*"
|
||||
)
|
||||
|
||||
var (
|
||||
// AuthenticationWithUser flag for enable the authentication of User in requests
|
||||
AuthenticationWithUser = false
|
||||
// AuthenticationDefaultUser the default user to use while no User is set in application
|
||||
AuthenticationDefaultUser = user.Anonymous
|
||||
// AuthenticationGroupPattern pattern for the authentication of Group in requests
|
||||
AuthenticationGroupPattern = DefaultAuthenticateGroupPattern
|
||||
)
|
||||
@@ -22,17 +22,13 @@ import (
|
||||
"net/http"
|
||||
|
||||
utilnet "k8s.io/apimachinery/pkg/util/net"
|
||||
"k8s.io/apiserver/pkg/endpoints/request"
|
||||
"k8s.io/client-go/transport"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/types"
|
||||
"github.com/oam-dev/kubevela/pkg/multicluster"
|
||||
oamutil "github.com/oam-dev/kubevela/pkg/oam/util"
|
||||
"github.com/oam-dev/kubevela/pkg/utils"
|
||||
)
|
||||
|
||||
const (
|
||||
impersonateKey = "impersonate"
|
||||
)
|
||||
|
||||
var _ utilnet.RoundTripperWrapper = &impersonatingRoundTripper{}
|
||||
|
||||
type impersonatingRoundTripper struct {
|
||||
@@ -49,22 +45,18 @@ func NewImpersonatingRoundTripper(rt http.RoundTripper) http.RoundTripper {
|
||||
|
||||
func (rt *impersonatingRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
ctx := req.Context()
|
||||
req = req.Clone(ctx)
|
||||
userInfo, exists := request.UserFrom(ctx)
|
||||
if exists && userInfo != nil {
|
||||
if name := userInfo.GetName(); name != "" {
|
||||
req.Header.Set(transport.ImpersonateUserHeader, name)
|
||||
req.Header.Set(transport.ImpersonateGroupHeader, types.ClusterGatewayAccessorGroup)
|
||||
for _, group := range userInfo.GetGroups() {
|
||||
if group != types.ClusterGatewayAccessorGroup {
|
||||
req.Header.Add(transport.ImpersonateGroupHeader, group)
|
||||
}
|
||||
}
|
||||
q := req.URL.Query()
|
||||
q.Add(impersonateKey, "true")
|
||||
req.URL.RawQuery = q.Encode()
|
||||
}
|
||||
|
||||
// Skip impersonation on non-local cluster requests
|
||||
if !multicluster.IsInLocalCluster(ctx) {
|
||||
return rt.rt.RoundTrip(req)
|
||||
}
|
||||
|
||||
sa := oamutil.GetServiceAccountInContext(ctx)
|
||||
if sa == "" {
|
||||
return rt.rt.RoundTrip(req)
|
||||
}
|
||||
req = req.Clone(req.Context())
|
||||
req.Header.Set(transport.ImpersonateUserHeader, sa)
|
||||
return rt.rt.RoundTrip(req)
|
||||
}
|
||||
|
||||
|
||||
@@ -24,16 +24,10 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
authv1 "k8s.io/api/authentication/v1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/client-go/transport"
|
||||
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
|
||||
"github.com/oam-dev/kubevela/apis/types"
|
||||
"github.com/oam-dev/kubevela/pkg/features"
|
||||
"github.com/oam-dev/kubevela/pkg/oam"
|
||||
"github.com/oam-dev/kubevela/pkg/multicluster"
|
||||
oamutil "github.com/oam-dev/kubevela/pkg/oam/util"
|
||||
)
|
||||
|
||||
type testRoundTripper struct {
|
||||
@@ -48,51 +42,30 @@ func (rt *testRoundTripper) RoundTrip(req *http.Request) (*http.Response, error)
|
||||
}
|
||||
|
||||
func TestImpersonatingRoundTripper(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.AuthenticateApplication, true)()
|
||||
AuthenticationWithUser = true
|
||||
defer func() {
|
||||
AuthenticationWithUser = false
|
||||
}()
|
||||
testSets := map[string]struct {
|
||||
ctxFn func(context.Context) context.Context
|
||||
expectedUser string
|
||||
expectedGroup []string
|
||||
ctxFn func(context.Context) context.Context
|
||||
expected string
|
||||
}{
|
||||
"with service account": {
|
||||
ctxFn: func(ctx context.Context) context.Context {
|
||||
app := &v1beta1.Application{}
|
||||
app.SetNamespace("vela-system")
|
||||
v1.SetMetaDataAnnotation(&app.ObjectMeta, oam.AnnotationApplicationServiceAccountName, "default")
|
||||
return ContextWithUserInfo(ctx, app)
|
||||
ctx = oamutil.SetServiceAccountInContext(ctx, "vela-system", "default")
|
||||
return ctx
|
||||
},
|
||||
expectedUser: "system:serviceaccount:vela-system:default",
|
||||
expectedGroup: []string{types.ClusterGatewayAccessorGroup},
|
||||
},
|
||||
"without service account and app": {
|
||||
ctxFn: func(ctx context.Context) context.Context {
|
||||
return ContextWithUserInfo(ctx, nil)
|
||||
},
|
||||
expectedUser: "",
|
||||
expectedGroup: []string{types.ClusterGatewayAccessorGroup},
|
||||
expected: "system:serviceaccount:vela-system:default",
|
||||
},
|
||||
"without service account": {
|
||||
ctxFn: func(ctx context.Context) context.Context {
|
||||
return ContextWithUserInfo(ctx, &v1beta1.Application{})
|
||||
return ctx
|
||||
},
|
||||
expectedUser: AuthenticationDefaultUser,
|
||||
expectedGroup: []string{types.ClusterGatewayAccessorGroup},
|
||||
expected: "",
|
||||
},
|
||||
"with user and groups": {
|
||||
"ignore if non-local cluster request": {
|
||||
ctxFn: func(ctx context.Context) context.Context {
|
||||
app := &v1beta1.Application{}
|
||||
SetUserInfoInAnnotation(&app.ObjectMeta, authv1.UserInfo{
|
||||
Username: "username",
|
||||
Groups: []string{"kubevela:group1", "kubevela:group2"},
|
||||
})
|
||||
return ContextWithUserInfo(ctx, app)
|
||||
ctx = multicluster.ContextWithClusterName(ctx, "test-cluster")
|
||||
ctx = oamutil.SetServiceAccountInContext(ctx, "vela-system", "default")
|
||||
return ctx
|
||||
},
|
||||
expectedUser: "username",
|
||||
expectedGroup: []string{types.ClusterGatewayAccessorGroup, "kubevela:group1", "kubevela:group2"},
|
||||
expected: "",
|
||||
},
|
||||
}
|
||||
for name, ts := range testSets {
|
||||
@@ -103,13 +76,12 @@ func TestImpersonatingRoundTripper(t *testing.T) {
|
||||
rt := &testRoundTripper{}
|
||||
_, err := NewImpersonatingRoundTripper(rt).RoundTrip(req)
|
||||
require.NoError(t, err)
|
||||
if ts.expectedUser == "" {
|
||||
if ts.expected == "" {
|
||||
_, ok := rt.Request.Header[transport.ImpersonateUserHeader]
|
||||
require.False(t, ok)
|
||||
return
|
||||
}
|
||||
require.Equal(t, ts.expectedUser, rt.Request.Header.Get(transport.ImpersonateUserHeader))
|
||||
require.Equal(t, ts.expectedGroup, rt.Request.Header.Values(transport.ImpersonateGroupHeader))
|
||||
require.Equal(t, ts.expected, rt.Request.Header.Get(transport.ImpersonateUserHeader))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
/*
|
||||
Copyright 2022 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 auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
authv1 "k8s.io/api/authentication/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apiserver/pkg/authentication/user"
|
||||
"k8s.io/apiserver/pkg/endpoints/request"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/utils/strings/slices"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
|
||||
"github.com/oam-dev/kubevela/pkg/features"
|
||||
"github.com/oam-dev/kubevela/pkg/oam"
|
||||
)
|
||||
|
||||
const (
|
||||
groupSeparator = ","
|
||||
)
|
||||
|
||||
// ContextWithUserInfo inject username & group from app annotations into context
|
||||
// If serviceAccount is set and username is empty, identity will user the serviceAccount
|
||||
func ContextWithUserInfo(ctx context.Context, app *v1beta1.Application) context.Context {
|
||||
if app == nil {
|
||||
return ctx
|
||||
}
|
||||
return request.WithUser(ctx, GetUserInfoInAnnotation(&app.ObjectMeta))
|
||||
}
|
||||
|
||||
// SetUserInfoInAnnotation set username and group from userInfo into annotations
|
||||
// it will clear the existing service account annotation in avoid of permission leak
|
||||
func SetUserInfoInAnnotation(obj *metav1.ObjectMeta, userInfo authv1.UserInfo) {
|
||||
if AuthenticationWithUser {
|
||||
metav1.SetMetaDataAnnotation(obj, oam.AnnotationApplicationUsername, userInfo.Username)
|
||||
}
|
||||
re := regexp.MustCompile(strings.ReplaceAll(AuthenticationGroupPattern, "*", ".*"))
|
||||
var groups []string
|
||||
for _, group := range userInfo.Groups {
|
||||
if re.MatchString(group) {
|
||||
groups = append(groups, group)
|
||||
}
|
||||
}
|
||||
metav1.SetMetaDataAnnotation(obj, oam.AnnotationApplicationGroup, strings.Join(groups, groupSeparator))
|
||||
}
|
||||
|
||||
// GetUserInfoInAnnotation extract user info from annotations
|
||||
// support compatibility for serviceAccount when name is empty
|
||||
func GetUserInfoInAnnotation(obj *metav1.ObjectMeta) user.Info {
|
||||
annotations := obj.GetAnnotations()
|
||||
if annotations == nil {
|
||||
annotations = map[string]string{}
|
||||
}
|
||||
|
||||
name := annotations[oam.AnnotationApplicationUsername]
|
||||
if serviceAccountName := annotations[oam.AnnotationApplicationServiceAccountName]; serviceAccountName != "" && name == "" {
|
||||
name = fmt.Sprintf("system:serviceaccount:%s:%s", obj.GetNamespace(), serviceAccountName)
|
||||
}
|
||||
|
||||
if name == "" && utilfeature.DefaultMutableFeatureGate.Enabled(features.AuthenticateApplication) {
|
||||
name = AuthenticationDefaultUser
|
||||
}
|
||||
|
||||
return &user.DefaultInfo{
|
||||
Name: name,
|
||||
Groups: slices.Filter(
|
||||
[]string{},
|
||||
strings.Split(annotations[oam.AnnotationApplicationGroup], groupSeparator),
|
||||
func(s string) bool {
|
||||
return len(strings.TrimSpace(s)) > 0
|
||||
}),
|
||||
}
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
/*
|
||||
Copyright 2022 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 auth
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
authv1 "k8s.io/api/authentication/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apiserver/pkg/authentication/user"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
|
||||
"github.com/oam-dev/kubevela/pkg/features"
|
||||
"github.com/oam-dev/kubevela/pkg/oam"
|
||||
)
|
||||
|
||||
func TestContextWithUserInfo(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.AuthenticateApplication, true)()
|
||||
AuthenticationWithUser = true
|
||||
defer func() {
|
||||
AuthenticationWithUser = false
|
||||
}()
|
||||
testCases := map[string]struct {
|
||||
UserInfo *authv1.UserInfo
|
||||
ServiceAccount string
|
||||
ExpectUserInfo user.Info
|
||||
}{
|
||||
"empty": {
|
||||
ExpectUserInfo: &user.DefaultInfo{
|
||||
Name: user.Anonymous,
|
||||
Groups: []string{},
|
||||
},
|
||||
},
|
||||
"service-account": {
|
||||
ServiceAccount: "sa",
|
||||
ExpectUserInfo: &user.DefaultInfo{
|
||||
Name: "system:serviceaccount:default:sa",
|
||||
Groups: []string{},
|
||||
},
|
||||
},
|
||||
"user-with-groups": {
|
||||
UserInfo: &authv1.UserInfo{
|
||||
Username: "user",
|
||||
Groups: []string{"group0", "kubevela:group1", "kubevela:group2"},
|
||||
},
|
||||
ServiceAccount: "override",
|
||||
ExpectUserInfo: &user.DefaultInfo{
|
||||
Name: "user",
|
||||
Groups: []string{"kubevela:group1", "kubevela:group2"},
|
||||
},
|
||||
},
|
||||
}
|
||||
for name, tt := range testCases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
r := require.New(t)
|
||||
app := &v1beta1.Application{}
|
||||
app.SetNamespace("default")
|
||||
if tt.UserInfo != nil {
|
||||
SetUserInfoInAnnotation(&app.ObjectMeta, *tt.UserInfo)
|
||||
}
|
||||
if tt.ServiceAccount != "" {
|
||||
metav1.SetMetaDataAnnotation(&app.ObjectMeta, oam.AnnotationApplicationServiceAccountName, tt.ServiceAccount)
|
||||
}
|
||||
r.Equal(tt.ExpectUserInfo, GetUserInfoInAnnotation(&app.ObjectMeta))
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -40,7 +40,7 @@ type Meta struct {
|
||||
func (m *Meta) Lookup(field string) cue.Value {
|
||||
f := m.Obj.Lookup(field)
|
||||
if !f.Exists() {
|
||||
m.Err = fmt.Errorf("invalid lookup argument")
|
||||
m.Err = fmt.Errorf("invalid string argument")
|
||||
return cue.Value{}
|
||||
}
|
||||
if err := f.Err(); err != nil {
|
||||
@@ -54,7 +54,7 @@ func (m *Meta) Int64(field string) int64 {
|
||||
f := m.Obj.Lookup(field)
|
||||
value, err := f.Int64()
|
||||
if err != nil {
|
||||
m.Err = fmt.Errorf("invalid int64 argument, %w", err)
|
||||
m.Err = fmt.Errorf("invalid string argument, %w", err)
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -197,7 +197,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
|
||||
}
|
||||
app.Status.SetConditions(condition.ReadyCondition(common.RenderCondition.String()))
|
||||
r.Recorder.Event(app, event.Normal(velatypes.ReasonRendered, velatypes.MessageRendered))
|
||||
wf := workflow.NewWorkflow(app, r.Client, appFile.WorkflowMode, appFile.Debug, handler.resourceKeeper)
|
||||
wf := workflow.NewWorkflow(app, r.Client, appFile.WorkflowMode)
|
||||
workflowState, err := wf.ExecuteSteps(logCtx.Fork("workflow"), handler.currentAppRev, steps)
|
||||
if err != nil {
|
||||
logCtx.Error(err, "[handle workflow]")
|
||||
@@ -213,36 +213,23 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
|
||||
case common.WorkflowStateInitializing:
|
||||
logCtx.Info("Workflow return state=Initializing")
|
||||
handler.UpdateApplicationRevisionStatus(logCtx, handler.currentAppRev, false, app.Status.Workflow)
|
||||
return r.gcResourceTrackers(logCtx, handler, common.ApplicationRendering, false, false)
|
||||
return r.gcResourceTrackers(logCtx, handler, common.ApplicationRendering, false)
|
||||
case common.WorkflowStateSuspended:
|
||||
logCtx.Info("Workflow return state=Suspend")
|
||||
doWaiting, durationWaiting, err := wf.HandleSuspendWait(logCtx)
|
||||
if err != nil {
|
||||
return r.endWithNegativeCondition(logCtx, app, condition.ErrorCondition(common.WorkflowCondition.String(), err), common.ApplicationRunningWorkflow)
|
||||
}
|
||||
if doWaiting {
|
||||
if durationWaiting > 0 {
|
||||
_, err = r.gcResourceTrackers(logCtx, handler, common.ApplicationWorkflowSuspending, false, true)
|
||||
return r.result(err).requeue(durationWaiting).ret()
|
||||
}
|
||||
handler.app.Status.Workflow.Suspend = false
|
||||
handler.app.Status.Workflow.SuspendState = ""
|
||||
return r.gcResourceTrackers(logCtx, handler, common.ApplicationRunningWorkflow, false, false)
|
||||
}
|
||||
if !workflow.IsFailedAfterRetry(app) {
|
||||
r.stateKeep(logCtx, handler, app)
|
||||
}
|
||||
return r.gcResourceTrackers(logCtx, handler, common.ApplicationWorkflowSuspending, false, true)
|
||||
return r.gcResourceTrackers(logCtx, handler, common.ApplicationWorkflowSuspending, false)
|
||||
case common.WorkflowStateTerminated:
|
||||
logCtx.Info("Workflow return state=Terminated")
|
||||
handler.UpdateApplicationRevisionStatus(logCtx, handler.latestAppRev, false, app.Status.Workflow)
|
||||
if err := r.doWorkflowFinish(app, wf); err != nil {
|
||||
return r.endWithNegativeCondition(ctx, app, condition.ErrorCondition(common.WorkflowCondition.String(), errors.WithMessage(err, "DoWorkflowFinish")), common.ApplicationRunningWorkflow)
|
||||
}
|
||||
return r.gcResourceTrackers(logCtx, handler, common.ApplicationWorkflowTerminated, false, true)
|
||||
return r.gcResourceTrackers(logCtx, handler, common.ApplicationWorkflowTerminated, false)
|
||||
case common.WorkflowStateExecuting:
|
||||
logCtx.Info("Workflow return state=Executing")
|
||||
_, err = r.gcResourceTrackers(logCtx, handler, common.ApplicationRunningWorkflow, false, true)
|
||||
_, err = r.gcResourceTrackers(logCtx, handler, common.ApplicationRunningWorkflow, false)
|
||||
return r.result(err).requeue(wf.GetBackoffWaitTime()).ret()
|
||||
case common.WorkflowStateSucceeded:
|
||||
logCtx.Info("Workflow return state=Succeeded")
|
||||
@@ -254,7 +241,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
|
||||
r.Recorder.Event(app, event.Normal(velatypes.ReasonApplied, velatypes.MessageWorkflowFinished))
|
||||
logCtx.Info("Application manifests has applied by workflow successfully")
|
||||
if !EnableReconcileLoopReduction {
|
||||
return r.gcResourceTrackers(logCtx, handler, common.ApplicationWorkflowFinished, false, true)
|
||||
return r.gcResourceTrackers(logCtx, handler, common.ApplicationWorkflowFinished, false)
|
||||
}
|
||||
case common.WorkflowStateFinished:
|
||||
logCtx.Info("Workflow state=Finished")
|
||||
@@ -288,7 +275,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
|
||||
Reason: condition.ReasonReconcileSuccess,
|
||||
})
|
||||
r.Recorder.Event(app, event.Normal(velatypes.ReasonDeployed, velatypes.MessageDeployed))
|
||||
return r.gcResourceTrackers(logCtx, handler, phase, true, true)
|
||||
return r.gcResourceTrackers(logCtx, handler, phase, true)
|
||||
}
|
||||
|
||||
func (r *Reconciler) stateKeep(logCtx monitorContext.Context, handler *AppHandler, app *v1beta1.Application) {
|
||||
@@ -299,7 +286,7 @@ func (r *Reconciler) stateKeep(logCtx monitorContext.Context, handler *AppHandle
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Reconciler) gcResourceTrackers(logCtx monitorContext.Context, handler *AppHandler, phase common.ApplicationPhase, gcOutdated bool, isPatch bool) (ctrl.Result, error) {
|
||||
func (r *Reconciler) gcResourceTrackers(logCtx monitorContext.Context, handler *AppHandler, phase common.ApplicationPhase, gcOutdated bool) (ctrl.Result, error) {
|
||||
subCtx := logCtx.Fork("gc_resourceTrackers", monitorContext.DurationMetric(func(v float64) {
|
||||
metrics.GCResourceTrackersDurationHistogram.WithLabelValues("-").Observe(v)
|
||||
}))
|
||||
@@ -325,7 +312,7 @@ func (r *Reconciler) gcResourceTrackers(logCtx monitorContext.Context, handler *
|
||||
return r.result(r.patchStatus(logCtx, handler.app, phase)).requeue(baseGCBackoffWaitTime).ret()
|
||||
}
|
||||
logCtx.Info("GarbageCollected resourcetrackers")
|
||||
if !isPatch {
|
||||
if phase == common.ApplicationRendering {
|
||||
return r.result(r.updateStatus(logCtx, handler.app, common.ApplicationRunningWorkflow)).ret()
|
||||
}
|
||||
return r.result(r.patchStatus(logCtx, handler.app, phase)).ret()
|
||||
@@ -384,7 +371,7 @@ func (r *Reconciler) handleFinalizers(ctx monitorContext.Context, app *v1beta1.A
|
||||
if err != nil {
|
||||
return r.result(err).end(true)
|
||||
}
|
||||
result, err := r.gcResourceTrackers(ctx, handler, common.ApplicationDeleting, true, true)
|
||||
result, err := r.gcResourceTrackers(ctx, handler, common.ApplicationDeleting, true)
|
||||
if err != nil {
|
||||
return true, result, err
|
||||
}
|
||||
|
||||
@@ -54,7 +54,6 @@ import (
|
||||
"github.com/oam-dev/kubevela/pkg/oam/util"
|
||||
common2 "github.com/oam-dev/kubevela/pkg/utils/common"
|
||||
"github.com/oam-dev/kubevela/pkg/workflow"
|
||||
"github.com/oam-dev/kubevela/pkg/workflow/debug"
|
||||
"github.com/oam-dev/kubevela/pkg/workflow/tasks/custom"
|
||||
)
|
||||
|
||||
@@ -293,35 +292,6 @@ var _ = Describe("Test Application Controller", func() {
|
||||
},
|
||||
}
|
||||
|
||||
appWithMountToEnvs := &v1beta1.Application{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "Application",
|
||||
APIVersion: "core.oam.dev/v1beta1",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "app-with-mount-to-envs",
|
||||
},
|
||||
Spec: v1beta1.ApplicationSpec{
|
||||
Components: []common.ApplicationComponent{
|
||||
{
|
||||
Name: "myweb",
|
||||
Type: "worker",
|
||||
Properties: &runtime.RawExtension{Raw: []byte("{\"cmd\":[\"sleep\",\"1000\"],\"image\":\"busybox\"}")},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
appWithMountToEnvs.Spec.Components[0].Traits = []common.ApplicationTrait{
|
||||
{
|
||||
Type: "storage",
|
||||
Properties: &runtime.RawExtension{Raw: []byte("{\"secret\": [{\"name\": \"myweb-secret\",\"mountToEnv\": {\"envName\": \"firstEnv\",\"secretKey\": \"firstKey\"},\"mountToEnvs\": [{\"envName\": \"secondEnv\",\"secretKey\": \"secondKey\"}],\"data\": {\"firstKey\": \"dmFsdWUwMQo=\",\"secondKey\": \"dmFsdWUwMgo=\"}}]}")},
|
||||
},
|
||||
{
|
||||
Type: "storage",
|
||||
Properties: &runtime.RawExtension{Raw: []byte("{\"configMap\": [{\"name\": \"myweb-cm\",\"mountToEnvs\": [{\"envName\":\"thirdEnv\",\"configMapKey\":\"thirdKey\"},{\"envName\":\"fourthEnv\",\"configMapKey\":\"fourthKey\"}],\"data\": {\"thirdKey\": \"Value03\",\"fourthKey\": \"Value04\"}}]}")},
|
||||
},
|
||||
}
|
||||
|
||||
cd := &v1beta1.ComponentDefinition{}
|
||||
cDDefJson, _ := yaml.YAMLToJSON([]byte(componentDefYaml))
|
||||
k8sObjectsCDJson, _ := yaml.YAMLToJSON([]byte(k8sObjectsComponentDefinitionYaml))
|
||||
@@ -2598,124 +2568,6 @@ var _ = Describe("Test Application Controller", func() {
|
||||
Expect(k8sClient.Delete(ctx, secret)).Should(BeNil())
|
||||
Expect(k8sClient.Delete(ctx, app)).Should(BeNil())
|
||||
})
|
||||
|
||||
It("test application with multi-mountToEnv will create application", func() {
|
||||
|
||||
ns := &corev1.Namespace{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "app-with-mount-to-envs",
|
||||
},
|
||||
}
|
||||
Expect(k8sClient.Create(ctx, ns)).Should(BeNil())
|
||||
|
||||
appWithMountToEnvs.SetNamespace(ns.Name)
|
||||
app := appWithMountToEnvs.DeepCopy()
|
||||
Expect(k8sClient.Create(ctx, app)).Should(BeNil())
|
||||
|
||||
appKey := client.ObjectKey{
|
||||
Name: app.Name,
|
||||
Namespace: app.Namespace,
|
||||
}
|
||||
testutil.ReconcileOnceAfterFinalizer(reconciler, reconcile.Request{NamespacedName: appKey})
|
||||
|
||||
By("Check App running successfully")
|
||||
curApp := &v1beta1.Application{}
|
||||
Expect(k8sClient.Get(ctx, appKey, curApp)).Should(BeNil())
|
||||
Expect(curApp.Status.Phase).Should(Equal(common.ApplicationRunning))
|
||||
|
||||
appRevision := &v1beta1.ApplicationRevision{}
|
||||
Expect(k8sClient.Get(ctx, client.ObjectKey{
|
||||
Namespace: app.Namespace,
|
||||
Name: curApp.Status.LatestRevision.Name,
|
||||
}, appRevision)).Should(BeNil())
|
||||
By("Check affiliated resource tracker is created")
|
||||
expectRTName := fmt.Sprintf("%s-%s", appRevision.GetName(), appRevision.GetNamespace())
|
||||
Eventually(func() error {
|
||||
return k8sClient.Get(ctx, client.ObjectKey{Name: expectRTName}, &v1beta1.ResourceTracker{})
|
||||
}, 10*time.Second, 500*time.Millisecond).Should(Succeed())
|
||||
|
||||
By("Check AppRevision Created with the expected workload spec")
|
||||
appRev := &v1beta1.ApplicationRevision{}
|
||||
Eventually(func() error {
|
||||
return k8sClient.Get(ctx, client.ObjectKey{Name: app.Name + "-v1", Namespace: app.GetNamespace()}, appRev)
|
||||
}, 10*time.Second, 500*time.Millisecond).Should(Succeed())
|
||||
|
||||
By("Check secret Created with the expected trait-storage spec")
|
||||
secret := &corev1.Secret{}
|
||||
Expect(k8sClient.Get(ctx, client.ObjectKey{
|
||||
Namespace: ns.Name,
|
||||
Name: app.Spec.Components[0].Name + "-secret",
|
||||
}, secret)).Should(BeNil())
|
||||
|
||||
By("Check configMap Created with the expected trait-storage spec")
|
||||
cm := &corev1.ConfigMap{}
|
||||
Expect(k8sClient.Get(ctx, client.ObjectKey{
|
||||
Namespace: ns.Name,
|
||||
Name: app.Spec.Components[0].Name + "-cm",
|
||||
}, cm)).Should(BeNil())
|
||||
|
||||
Expect(k8sClient.Delete(ctx, cm)).Should(BeNil())
|
||||
Expect(k8sClient.Delete(ctx, secret)).Should(BeNil())
|
||||
Expect(k8sClient.Delete(ctx, app)).Should(BeNil())
|
||||
})
|
||||
|
||||
It("app with debug policy", func() {
|
||||
app := &v1beta1.Application{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "Application",
|
||||
APIVersion: "core.oam.dev/v1beta1",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "app-debug",
|
||||
Namespace: "default",
|
||||
},
|
||||
Spec: v1beta1.ApplicationSpec{
|
||||
Components: []common.ApplicationComponent{
|
||||
{
|
||||
Name: "myworker",
|
||||
Type: "worker",
|
||||
Properties: &runtime.RawExtension{Raw: []byte("{\"cmd\":[\"sleep\",\"1000\"],\"image\":\"busybox\",\"env\":[{\"name\":\"firstKey\",\"value\":\"firstValue\"}]}")},
|
||||
},
|
||||
},
|
||||
Policies: []v1beta1.AppPolicy{
|
||||
{
|
||||
Type: "debug",
|
||||
Name: "debug",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
Expect(k8sClient.Create(ctx, app)).Should(BeNil())
|
||||
|
||||
appKey := client.ObjectKey{
|
||||
Name: app.Name,
|
||||
Namespace: app.Namespace,
|
||||
}
|
||||
testutil.ReconcileOnceAfterFinalizer(reconciler, reconcile.Request{NamespacedName: appKey})
|
||||
|
||||
By("Check App running successfully")
|
||||
curApp := &v1beta1.Application{}
|
||||
Expect(k8sClient.Get(ctx, appKey, curApp)).Should(BeNil())
|
||||
Expect(curApp.Status.Phase).Should(Equal(common.ApplicationRunning))
|
||||
|
||||
By("Check debug Config Map is created")
|
||||
debugCM := &corev1.ConfigMap{}
|
||||
Expect(k8sClient.Get(ctx, types.NamespacedName{
|
||||
Name: debug.GenerateContextName(app.Name, "myworker"),
|
||||
Namespace: "default",
|
||||
}, debugCM)).Should(BeNil())
|
||||
|
||||
By("Update the application to update the debug Config Map")
|
||||
app.Spec.Components[0].Properties = &runtime.RawExtension{Raw: []byte("{\"cmd\":[\"sleep\",\"1000\"],\"image\":\"busybox\",\"env\":[{\"name\":\"firstKey\",\"value\":\"updateValue\"}]}")}
|
||||
testutil.ReconcileOnce(reconciler, reconcile.Request{NamespacedName: appKey})
|
||||
updatedCM := &corev1.ConfigMap{}
|
||||
Expect(k8sClient.Get(ctx, types.NamespacedName{
|
||||
Name: debug.GenerateContextName(app.Name, "myworker"),
|
||||
Namespace: "default",
|
||||
}, updatedCM)).Should(BeNil())
|
||||
|
||||
Expect(k8sClient.Delete(ctx, app)).Should(BeNil())
|
||||
})
|
||||
})
|
||||
|
||||
const (
|
||||
@@ -3752,17 +3604,6 @@ spec:
|
||||
}
|
||||
},
|
||||
] | []
|
||||
configMapMountToEnvsList: *[
|
||||
for v in parameter.configMap if v.mountToEnvs != _|_ for k in v.mountToEnvs {
|
||||
{
|
||||
name: k.envName
|
||||
valueFrom: configMapKeyRef: {
|
||||
name: v.name
|
||||
key: k.configMapKey
|
||||
}
|
||||
}
|
||||
},
|
||||
] | []
|
||||
secretVolumeMountsList: *[
|
||||
for v in parameter.secret if v.mountPath != _|_ {
|
||||
{
|
||||
@@ -3782,17 +3623,6 @@ spec:
|
||||
}
|
||||
},
|
||||
] | []
|
||||
secretMountToEnvsList: *[
|
||||
for v in parameter.secret if v.mountToEnvs != _|_ for k in v.mountToEnvs {
|
||||
{
|
||||
name: k.envName
|
||||
valueFrom: secretKeyRef: {
|
||||
name: v.name
|
||||
key: k.secretKey
|
||||
}
|
||||
}
|
||||
},
|
||||
] | []
|
||||
emptyDirVolumeMountsList: *[
|
||||
for v in parameter.emptyDir {
|
||||
{
|
||||
@@ -3815,7 +3645,7 @@ spec:
|
||||
|
||||
containers: [{
|
||||
// +patchKey=name
|
||||
env: configMapEnvMountsList + secretEnvMountsList + configMapMountToEnvsList + secretMountToEnvsList
|
||||
env: configMapEnvMountsList + secretEnvMountsList
|
||||
// +patchKey=name
|
||||
volumeDevices: volumeDevicesList
|
||||
// +patchKey=name
|
||||
@@ -3935,10 +3765,6 @@ spec:
|
||||
envName: string
|
||||
configMapKey: string
|
||||
}
|
||||
mountToEnvs?: [...{
|
||||
envName: string
|
||||
configMapKey: string
|
||||
}]
|
||||
mountPath?: string
|
||||
defaultMode: *420 | int
|
||||
readOnly: *false | bool
|
||||
@@ -3958,10 +3784,6 @@ spec:
|
||||
envName: string
|
||||
secretKey: string
|
||||
}
|
||||
mountToEnvs?: [...{
|
||||
envName: string
|
||||
secretKey: string
|
||||
}]
|
||||
mountPath?: string
|
||||
defaultMode: *420 | int
|
||||
readOnly: *false | bool
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user