mirror of
https://github.com/kubevela/kubevela.git
synced 2026-02-14 18:10:21 +00:00
Merge pull request #65 from cloud-native-application/env
support rudr env
This commit is contained in:
54
Makefile
54
Makefile
@@ -1,9 +1,3 @@
|
||||
|
||||
# Image URL to use all building/pushing image targets
|
||||
IMG ?= controller:latest
|
||||
# Produce CRDs that work back to Kubernetes 1.11 (no version conversion)
|
||||
CRD_OPTIONS ?= "crd:trivialVersions=true"
|
||||
|
||||
# Rudrx version
|
||||
RUDRX_VERSION ?= 0.1.0
|
||||
# Repo info
|
||||
@@ -16,38 +10,20 @@ else
|
||||
GOBIN=$(shell go env GOBIN)
|
||||
endif
|
||||
|
||||
all: manager
|
||||
all: build
|
||||
|
||||
# Run tests
|
||||
test: generate fmt vet manifests
|
||||
test: fmt vet
|
||||
go test ./... -coverprofile cover.out
|
||||
|
||||
# Build manager binary
|
||||
manager: generate fmt vet
|
||||
go build -o bin/manager cmd/server/main.go
|
||||
build: fmt vet
|
||||
go build -ldflags "-X main.RudrxVersion=${RUDRX_VERSION} -X main.GitRevision=${GIT_COMMIT}" -o bin/rudrx cmd/rudrx/main.go
|
||||
|
||||
# Run against the configured Kubernetes cluster in ~/.kube/config
|
||||
run: generate fmt vet manifests
|
||||
run: fmt vet
|
||||
go run ./cmd/server/main.go
|
||||
|
||||
# Install CRDs into a cluster
|
||||
install: manifests
|
||||
kustomize build config/crd | kubectl apply -f -
|
||||
|
||||
# Uninstall CRDs from a cluster
|
||||
uninstall: manifests
|
||||
kustomize build config/crd | kubectl delete -f -
|
||||
|
||||
# Deploy controller in the configured Kubernetes cluster in ~/.kube/config
|
||||
deploy: manifests
|
||||
cd config/manager && kustomize edit set image controller=${IMG}
|
||||
kustomize build config/default | kubectl apply -f -
|
||||
|
||||
# Generate manifests e.g. CRD, RBAC etc.
|
||||
manifests: controller-gen
|
||||
$(CONTROLLER_GEN) $(CRD_OPTIONS) rbac:roleName=manager-role webhook paths="./..." output:crd:artifacts:config=config/crd/bases
|
||||
|
||||
# Run go fmt against code
|
||||
fmt:
|
||||
go fmt ./...
|
||||
@@ -56,10 +32,6 @@ fmt:
|
||||
vet:
|
||||
go vet ./...
|
||||
|
||||
# Generate code
|
||||
generate: controller-gen
|
||||
$(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..."
|
||||
|
||||
# Build the docker image
|
||||
docker-build: test
|
||||
docker build . -t ${IMG}
|
||||
@@ -68,28 +40,12 @@ docker-build: test
|
||||
docker-push:
|
||||
docker push ${IMG}
|
||||
|
||||
# find or download controller-gen
|
||||
# download controller-gen if necessary
|
||||
controller-gen:
|
||||
ifeq (, $(shell which controller-gen))
|
||||
@{ \
|
||||
set -e ;\
|
||||
CONTROLLER_GEN_TMP_DIR=$$(mktemp -d) ;\
|
||||
cd $$CONTROLLER_GEN_TMP_DIR ;\
|
||||
go mod init tmp ;\
|
||||
go get sigs.k8s.io/controller-tools/cmd/controller-gen@v0.2.5 ;\
|
||||
rm -rf $$CONTROLLER_GEN_TMP_DIR ;\
|
||||
}
|
||||
CONTROLLER_GEN=$(GOBIN)/controller-gen
|
||||
else
|
||||
CONTROLLER_GEN=$(shell which controller-gen)
|
||||
endif
|
||||
|
||||
e2e-setup:
|
||||
# install oam-k8s-runtime
|
||||
|
||||
e2e-test:
|
||||
# Run e2e test
|
||||
go test ./pkg/test
|
||||
|
||||
e2e-cleanup:
|
||||
# Clean up
|
||||
@@ -83,12 +83,16 @@ func newCommand() *cobra.Command {
|
||||
|
||||
cmds.AddCommand(
|
||||
cmd.NewRunCommand(f, client, ioStream, os.Args[1:]),
|
||||
cmd.NewTraitsCommand(f, client, ioStream),
|
||||
cmd.NewTraitsCommand(f, client, ioStream, []string{}),
|
||||
cmd.NewWorkloadsCommand(f, client, ioStream, os.Args[1:]),
|
||||
cmd.NewBindCommand(f, client, ioStream),
|
||||
cmd.NewBindCommand(f, client, ioStream, []string{}),
|
||||
cmd.NewInitCommand(f, client, ioStream),
|
||||
cmd.NewDeleteCommand(f, client, ioStream, os.Args[1:]),
|
||||
cmd.NewAppsCommand(f, client, ioStream),
|
||||
cmd.NewEnvInitCommand(f, ioStream),
|
||||
cmd.NewEnvSwitchCommand(f, ioStream),
|
||||
cmd.NewEnvDeleteCommand(f, ioStream),
|
||||
cmd.NewEnvCommand(f, ioStream),
|
||||
NewVersionCommand(),
|
||||
)
|
||||
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
/*
|
||||
|
||||
|
||||
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 main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"os"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
|
||||
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/log/zap"
|
||||
|
||||
coreoamdevv1alpha2 "github.com/cloud-native-application/rudrx/api/v1alpha2"
|
||||
"github.com/cloud-native-application/rudrx/controllers"
|
||||
// +kubebuilder:scaffold:imports
|
||||
)
|
||||
|
||||
var (
|
||||
scheme = runtime.NewScheme()
|
||||
setupLog = ctrl.Log.WithName("setup")
|
||||
)
|
||||
|
||||
func init() {
|
||||
_ = clientgoscheme.AddToScheme(scheme)
|
||||
|
||||
_ = coreoamdevv1alpha2.AddToScheme(scheme)
|
||||
// +kubebuilder:scaffold:scheme
|
||||
}
|
||||
|
||||
func main() {
|
||||
var metricsAddr string
|
||||
var enableLeaderElection bool
|
||||
flag.StringVar(&metricsAddr, "metrics-addr", ":8080", "The address the metric endpoint binds to.")
|
||||
flag.BoolVar(&enableLeaderElection, "enable-leader-election", false,
|
||||
"Enable leader election for controller manager. "+
|
||||
"Enabling this will ensure there is only one active controller manager.")
|
||||
flag.Parse()
|
||||
|
||||
ctrl.SetLogger(zap.New(zap.UseDevMode(true)))
|
||||
|
||||
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
|
||||
Scheme: scheme,
|
||||
MetricsBindAddress: metricsAddr,
|
||||
Port: 9443,
|
||||
LeaderElection: enableLeaderElection,
|
||||
LeaderElectionID: "285a4034.my.domain",
|
||||
})
|
||||
if err != nil {
|
||||
setupLog.Error(err, "unable to start manager")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if err = (&controllers.TemplateReconciler{
|
||||
Client: mgr.GetClient(),
|
||||
Log: ctrl.Log.WithName("controllers").WithName("Template"),
|
||||
Scheme: mgr.GetScheme(),
|
||||
}).SetupWithManager(mgr); err != nil {
|
||||
setupLog.Error(err, "unable to create controller", "controller", "Template")
|
||||
os.Exit(1)
|
||||
}
|
||||
// +kubebuilder:scaffold:builder
|
||||
|
||||
setupLog.Info("starting manager")
|
||||
if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
|
||||
setupLog.Error(err, "problem running manager")
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.2.5
|
||||
creationTimestamp: null
|
||||
name: templates.admin.oam.dev
|
||||
spec:
|
||||
group: admin.oam.dev
|
||||
names:
|
||||
kind: Template
|
||||
listKind: TemplateList
|
||||
plural: templates
|
||||
singular: template
|
||||
scope: Namespaced
|
||||
validation:
|
||||
openAPIV3Schema:
|
||||
description: Template is the Schema for the templates API
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation
|
||||
of an object. Servers should convert recognized schemas to the latest
|
||||
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this
|
||||
object represents. Servers may infer this from the endpoint the client
|
||||
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: TemplateSpec defines the desired state of Template
|
||||
properties:
|
||||
lastCommandParam:
|
||||
type: string
|
||||
object:
|
||||
description: 'INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
|
||||
Important: Run "make" to regenerate code after modifying this file'
|
||||
type: object
|
||||
parameters:
|
||||
items:
|
||||
properties:
|
||||
default:
|
||||
type: string
|
||||
fieldPaths:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
name:
|
||||
type: string
|
||||
required:
|
||||
type: boolean
|
||||
short:
|
||||
type: string
|
||||
type:
|
||||
type: string
|
||||
usage:
|
||||
type: string
|
||||
required:
|
||||
- fieldPaths
|
||||
- name
|
||||
type: object
|
||||
type: array
|
||||
required:
|
||||
- object
|
||||
type: object
|
||||
status:
|
||||
description: TemplateStatus defines the observed state of Template
|
||||
type: object
|
||||
type: object
|
||||
version: v1alpha2
|
||||
versions:
|
||||
- name: v1alpha2
|
||||
served: true
|
||||
storage: true
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
plural: ""
|
||||
conditions: []
|
||||
storedVersions: []
|
||||
@@ -1,11 +0,0 @@
|
||||
# This kustomization.yaml is not intended to be run by itself,
|
||||
# since it depends on service name and namespace that are out of this kustomize package.
|
||||
# It should be run by config/default
|
||||
resources:
|
||||
- bases/admin.oam.dev_templates.yaml
|
||||
# +kubebuilder:scaffold:crdkustomizeresource
|
||||
|
||||
|
||||
# the following config is for teaching kustomize how to do kustomization for CRDs.
|
||||
configurations:
|
||||
- kustomizeconfig.yaml
|
||||
@@ -1,3 +0,0 @@
|
||||
# This file is for teaching kustomize how to substitute name and namespace reference in CRD
|
||||
varReference:
|
||||
- path: metadata/annotations
|
||||
@@ -1,70 +0,0 @@
|
||||
# Adds namespace to all resources.
|
||||
namespace: rudrx-system
|
||||
|
||||
# Value of this field is prepended to the
|
||||
# names of all resources, e.g. a deployment named
|
||||
# "wordpress" becomes "alices-wordpress".
|
||||
# Note that it should also match with the prefix (text before '-') of the namespace
|
||||
# field above.
|
||||
namePrefix: rudrx-
|
||||
|
||||
# Labels to add to all resources and selectors.
|
||||
#commonLabels:
|
||||
# someName: someValue
|
||||
|
||||
bases:
|
||||
- ../crd
|
||||
- ../rbac
|
||||
- ../manager
|
||||
# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in
|
||||
# crd/kustomization.yaml
|
||||
#- ../webhook
|
||||
# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 'WEBHOOK' components are required.
|
||||
#- ../certmanager
|
||||
# [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'.
|
||||
#- ../prometheus
|
||||
|
||||
patchesStrategicMerge:
|
||||
# Protect the /metrics endpoint by putting it behind auth.
|
||||
# If you want your controller-manager to expose the /metrics
|
||||
# endpoint w/o any authn/z, please comment the following line.
|
||||
- manager_auth_proxy_patch.yaml
|
||||
|
||||
# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in
|
||||
# crd/kustomization.yaml
|
||||
#- manager_webhook_patch.yaml
|
||||
|
||||
# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'.
|
||||
# Uncomment 'CERTMANAGER' sections in crd/kustomization.yaml to enable the CA injection in the admission webhooks.
|
||||
# 'CERTMANAGER' needs to be enabled to use ca injection
|
||||
#- webhookcainjection_patch.yaml
|
||||
|
||||
# the following config is for teaching kustomize how to do var substitution
|
||||
vars:
|
||||
# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER' prefix.
|
||||
#- name: CERTIFICATE_NAMESPACE # namespace of the certificate CR
|
||||
# objref:
|
||||
# kind: Certificate
|
||||
# group: cert-manager.io
|
||||
# version: v1alpha2
|
||||
# name: serving-cert # this name should match the one in certificate.yaml
|
||||
# fieldref:
|
||||
# fieldpath: metadata.namespace
|
||||
#- name: CERTIFICATE_NAME
|
||||
# objref:
|
||||
# kind: Certificate
|
||||
# group: cert-manager.io
|
||||
# version: v1alpha2
|
||||
# name: serving-cert # this name should match the one in certificate.yaml
|
||||
#- name: SERVICE_NAMESPACE # namespace of the service
|
||||
# objref:
|
||||
# kind: Service
|
||||
# version: v1
|
||||
# name: webhook-service
|
||||
# fieldref:
|
||||
# fieldpath: metadata.namespace
|
||||
#- name: SERVICE_NAME
|
||||
# objref:
|
||||
# kind: Service
|
||||
# version: v1
|
||||
# name: webhook-service
|
||||
@@ -1,25 +0,0 @@
|
||||
# This patch inject a sidecar container which is a HTTP proxy for the
|
||||
# controller manager, it performs RBAC authorization against the Kubernetes API using SubjectAccessReviews.
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: controller-manager
|
||||
namespace: system
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: kube-rbac-proxy
|
||||
image: gcr.io/kubebuilder/kube-rbac-proxy:v0.5.0
|
||||
args:
|
||||
- "--secure-listen-address=0.0.0.0:8443"
|
||||
- "--upstream=http://127.0.0.1:8080/"
|
||||
- "--logtostderr=true"
|
||||
- "--v=10"
|
||||
ports:
|
||||
- containerPort: 8443
|
||||
name: https
|
||||
- name: manager
|
||||
args:
|
||||
- "--metrics-addr=127.0.0.1:8080"
|
||||
- "--enable-leader-election"
|
||||
@@ -1,2 +0,0 @@
|
||||
resources:
|
||||
- manager.yaml
|
||||
@@ -1,39 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
labels:
|
||||
control-plane: controller-manager
|
||||
name: system
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: controller-manager
|
||||
namespace: system
|
||||
labels:
|
||||
control-plane: controller-manager
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
control-plane: controller-manager
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
control-plane: controller-manager
|
||||
spec:
|
||||
containers:
|
||||
- command:
|
||||
- /manager
|
||||
args:
|
||||
- --enable-leader-election
|
||||
image: controller:latest
|
||||
name: manager
|
||||
resources:
|
||||
limits:
|
||||
cpu: 100m
|
||||
memory: 30Mi
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 20Mi
|
||||
terminationGracePeriodSeconds: 10
|
||||
@@ -1,7 +0,0 @@
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: metrics-reader
|
||||
rules:
|
||||
- nonResourceURLs: ["/metrics"]
|
||||
verbs: ["get"]
|
||||
@@ -1,13 +0,0 @@
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: proxy-role
|
||||
rules:
|
||||
- apiGroups: ["authentication.k8s.io"]
|
||||
resources:
|
||||
- tokenreviews
|
||||
verbs: ["create"]
|
||||
- apiGroups: ["authorization.k8s.io"]
|
||||
resources:
|
||||
- subjectaccessreviews
|
||||
verbs: ["create"]
|
||||
@@ -1,12 +0,0 @@
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: proxy-rolebinding
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: proxy-role
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: default
|
||||
namespace: system
|
||||
@@ -1,14 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
control-plane: controller-manager
|
||||
name: controller-manager-metrics-service
|
||||
namespace: system
|
||||
spec:
|
||||
ports:
|
||||
- name: https
|
||||
port: 8443
|
||||
targetPort: https
|
||||
selector:
|
||||
control-plane: controller-manager
|
||||
@@ -1,12 +0,0 @@
|
||||
resources:
|
||||
- role.yaml
|
||||
- role_binding.yaml
|
||||
- leader_election_role.yaml
|
||||
- leader_election_role_binding.yaml
|
||||
# Comment the following 4 lines if you want to disable
|
||||
# the auth proxy (https://github.com/brancz/kube-rbac-proxy)
|
||||
# which protects your /metrics endpoint.
|
||||
- auth_proxy_service.yaml
|
||||
- auth_proxy_role.yaml
|
||||
- auth_proxy_role_binding.yaml
|
||||
- auth_proxy_client_clusterrole.yaml
|
||||
@@ -1,32 +0,0 @@
|
||||
# permissions to do leader election.
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: leader-election-role
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- configmaps
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- create
|
||||
- update
|
||||
- patch
|
||||
- delete
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- configmaps/status
|
||||
verbs:
|
||||
- get
|
||||
- update
|
||||
- patch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- events
|
||||
verbs:
|
||||
- create
|
||||
@@ -1,12 +0,0 @@
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: leader-election-rolebinding
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: leader-election-role
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: default
|
||||
namespace: system
|
||||
@@ -1,28 +0,0 @@
|
||||
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: manager-role
|
||||
rules:
|
||||
- apiGroups:
|
||||
- admin.oam.dev
|
||||
resources:
|
||||
- templates
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- admin.oam.dev
|
||||
resources:
|
||||
- templates/status
|
||||
verbs:
|
||||
- get
|
||||
- patch
|
||||
- update
|
||||
@@ -1,12 +0,0 @@
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: manager-rolebinding
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: manager-role
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: default
|
||||
namespace: system
|
||||
@@ -1,24 +0,0 @@
|
||||
# permissions for end users to edit templates.
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: template-editor-role
|
||||
rules:
|
||||
- apiGroups:
|
||||
- admin.oam.dev
|
||||
resources:
|
||||
- templates
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- admin.oam.dev
|
||||
resources:
|
||||
- templates/status
|
||||
verbs:
|
||||
- get
|
||||
@@ -1,20 +0,0 @@
|
||||
# permissions for end users to view templates.
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: template-viewer-role
|
||||
rules:
|
||||
- apiGroups:
|
||||
- admin.oam.dev
|
||||
resources:
|
||||
- templates
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- admin.oam.dev
|
||||
resources:
|
||||
- templates/status
|
||||
verbs:
|
||||
- get
|
||||
@@ -1,79 +0,0 @@
|
||||
/*
|
||||
|
||||
|
||||
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 controllers
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"k8s.io/client-go/rest"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/envtest"
|
||||
"sigs.k8s.io/controller-runtime/pkg/envtest/printer"
|
||||
logf "sigs.k8s.io/controller-runtime/pkg/log"
|
||||
"sigs.k8s.io/controller-runtime/pkg/log/zap"
|
||||
// +kubebuilder:scaffold:imports
|
||||
)
|
||||
|
||||
// These tests use Ginkgo (BDD-style Go testing framework). Refer to
|
||||
// http://onsi.github.io/ginkgo/ to learn more about Ginkgo.
|
||||
|
||||
var cfg *rest.Config
|
||||
var k8sClient client.Client
|
||||
var testEnv *envtest.Environment
|
||||
|
||||
func TestAPIs(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
|
||||
RunSpecsWithDefaultAndCustomReporters(t,
|
||||
"Controller Suite",
|
||||
[]Reporter{printer.NewlineReporter{}})
|
||||
}
|
||||
|
||||
var _ = BeforeSuite(func(done Done) {
|
||||
logf.SetLogger(zap.LoggerTo(GinkgoWriter, true))
|
||||
|
||||
By("bootstrapping test environment")
|
||||
testEnv = &envtest.Environment{
|
||||
CRDDirectoryPaths: []string{filepath.Join("..", "config", "crd", "bases")},
|
||||
}
|
||||
|
||||
// TODO add later
|
||||
// var err error
|
||||
// cfg, err = testEnv.Start()
|
||||
// Expect(err).ToNot(HaveOccurred())
|
||||
// Expect(cfg).ToNot(BeNil())
|
||||
|
||||
// err = coreoamdevv1alpha2.AddToScheme(scheme.Scheme)
|
||||
// Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
// // +kubebuilder:scaffold:scheme
|
||||
|
||||
// k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme})
|
||||
// Expect(err).ToNot(HaveOccurred())
|
||||
// Expect(k8sClient).ToNot(BeNil())
|
||||
|
||||
close(done)
|
||||
}, 60)
|
||||
|
||||
var _ = AfterSuite(func() {
|
||||
By("tearing down the test environment")
|
||||
err := testEnv.Stop()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
})
|
||||
3
go.mod
3
go.mod
@@ -4,13 +4,14 @@ go 1.13
|
||||
|
||||
require (
|
||||
github.com/crossplane/crossplane-runtime v0.8.0
|
||||
github.com/crossplane/oam-kubernetes-runtime v0.0.5
|
||||
github.com/crossplane/oam-kubernetes-runtime v0.0.8
|
||||
github.com/go-logr/logr v0.1.0
|
||||
github.com/gosuri/uitable v0.0.4
|
||||
github.com/onsi/ginkgo v1.11.0
|
||||
github.com/onsi/gomega v1.8.1
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/spf13/cobra v1.0.0
|
||||
github.com/stretchr/testify v1.6.1
|
||||
gotest.tools v2.2.0+incompatible
|
||||
helm.sh/helm/v3 v3.2.4
|
||||
k8s.io/api v0.18.6
|
||||
|
||||
6
go.sum
6
go.sum
@@ -122,6 +122,10 @@ github.com/crossplane/crossplane-runtime v0.8.0/go.mod h1:gNY/21MLBaz5KNP7hmfXbB
|
||||
github.com/crossplane/crossplane-tools v0.0.0-20200219001116-bb8b2ce46330/go.mod h1:C735A9X0x0lR8iGVOOxb49Mt70Ua4EM2b7PGaRPBLd4=
|
||||
github.com/crossplane/oam-kubernetes-runtime v0.0.5 h1:eOhRsrJBjCQfb79+59qtUt2q5i4iA7vSBL8E9/RgF5Q=
|
||||
github.com/crossplane/oam-kubernetes-runtime v0.0.5/go.mod h1:qICT3mLgVRW3PSH0wbJTswj36lZWIDK7Pdofmvy19fg=
|
||||
github.com/crossplane/oam-kubernetes-runtime v0.0.7 h1:vwCkzB+0vIsfXO6BCDbIxAFK3b/w4zIEuIWrdyLteOA=
|
||||
github.com/crossplane/oam-kubernetes-runtime v0.0.7/go.mod h1:f5xqmo0B2WtaOTZh8jhP+0f0XuzqhJG2xRtxfMZR3jA=
|
||||
github.com/crossplane/oam-kubernetes-runtime v0.0.8 h1:LzAPVtcWY5uqK81SpnsLqzVqYGU+lFiuXDGzBbA8zaI=
|
||||
github.com/crossplane/oam-kubernetes-runtime v0.0.8/go.mod h1:f5xqmo0B2WtaOTZh8jhP+0f0XuzqhJG2xRtxfMZR3jA=
|
||||
github.com/cyphar/filepath-securejoin v0.2.2 h1:jCwT2GTP+PY5nBz3c/YL5PAIbusElVrPujOBSCj8xRg=
|
||||
github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4=
|
||||
github.com/dave/jennifer v1.3.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg=
|
||||
@@ -824,6 +828,8 @@ gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20190905181640-827449938966/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
helm.sh/helm v2.16.9+incompatible h1:31XFG6KPAbh2A/oDgIaQFR8L63vtyxN7tOt64URUJvY=
|
||||
|
||||
@@ -17,7 +17,7 @@ import (
|
||||
)
|
||||
|
||||
type commandOptions struct {
|
||||
Namespace string
|
||||
Env *EnvMeta
|
||||
Template cmdutil.Template
|
||||
Component corev1alpha2.Component
|
||||
AppConfig corev1alpha2.ApplicationConfiguration
|
||||
@@ -29,10 +29,18 @@ func NewCommandOptions(ioStreams cmdutil.IOStreams) *commandOptions {
|
||||
return &commandOptions{IOStreams: ioStreams}
|
||||
}
|
||||
|
||||
func NewBindCommand(f cmdutil.Factory, c client.Client, ioStreams cmdutil.IOStreams) *cobra.Command {
|
||||
func NewBindCommand(f cmdutil.Factory, c client.Client, ioStreams cmdutil.IOStreams, args []string) *cobra.Command {
|
||||
|
||||
var err error
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
o := NewCommandOptions(ioStreams)
|
||||
o.Env, err = GetEnv()
|
||||
if err != nil {
|
||||
fmt.Printf("Listing trait definitions hit an issue: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
o.Client = c
|
||||
cmd := &cobra.Command{
|
||||
Use: "bind APPLICATION-NAME TRAIT-NAME [FLAG]",
|
||||
@@ -45,19 +53,20 @@ func NewBindCommand(f cmdutil.Factory, c client.Client, ioStreams cmdutil.IOStre
|
||||
cmdutil.CheckErr(o.Run(f, cmd, ctx))
|
||||
},
|
||||
}
|
||||
|
||||
cmd.SetArgs(args)
|
||||
var traitDefinitions corev1alpha2.TraitDefinitionList
|
||||
c.List(ctx, &traitDefinitions)
|
||||
//if err != nil {
|
||||
// fmt.Println("Listing trait definitions hit an issue:", err)
|
||||
// os.Exit(1)
|
||||
//}
|
||||
err = c.List(ctx, &traitDefinitions)
|
||||
if err != nil {
|
||||
fmt.Println("Listing trait definitions hit an issue:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
for _, t := range traitDefinitions.Items {
|
||||
var traitTemplate cmdutil.Template
|
||||
traitTemplate, err := cmdutil.ConvertTemplateJson2Object(t.Spec.Extension)
|
||||
if err != nil {
|
||||
fmt.Errorf("applying the trait hit an issue: %s", err)
|
||||
fmt.Printf("extract template from traitDefinition %v err: %v, ignore it\n", t.Name, err)
|
||||
continue
|
||||
}
|
||||
|
||||
for _, p := range traitTemplate.Parameters {
|
||||
@@ -65,6 +74,7 @@ func NewBindCommand(f cmdutil.Factory, c client.Client, ioStreams cmdutil.IOStre
|
||||
v, err := strconv.Atoi(p.Default)
|
||||
if err != nil {
|
||||
fmt.Println("Parameters type is wrong: ", err, ".Please report this to OAM maintainer, thanks.")
|
||||
os.Exit(1)
|
||||
}
|
||||
cmd.PersistentFlags().Int(p.Name, v, p.Usage)
|
||||
} else {
|
||||
@@ -82,16 +92,13 @@ func (o *commandOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []
|
||||
|
||||
c := o.Client
|
||||
|
||||
namespace := cmd.Flag("namespace").Value.String()
|
||||
if namespace == "" {
|
||||
namespace = "default"
|
||||
}
|
||||
namespace := o.Env.Namespace
|
||||
|
||||
if argsLength == 0 {
|
||||
return errors.New("please append the name of an application. Use `rudr bind -h` for more detailed information")
|
||||
} else if argsLength <= 2 {
|
||||
componentName = args[0]
|
||||
err := c.Get(ctx, client.ObjectKey{Namespace: namespace, Name: componentName}, &o.AppConfig)
|
||||
err := c.Get(ctx, client.ObjectKey{Namespace: o.Env.Namespace, Name: componentName}, &o.AppConfig)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
@@ -164,8 +171,7 @@ func (o *commandOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []
|
||||
o.AppConfig.Spec.Components = []corev1alpha2.ApplicationConfigurationComponent{{
|
||||
ComponentName: componentName,
|
||||
Traits: []corev1alpha2.ComponentTrait{t},
|
||||
},
|
||||
}
|
||||
}}
|
||||
}
|
||||
} else {
|
||||
cmdutil.PrintErrorMessage("Unknown command is specified, please check and try again.", 1)
|
||||
|
||||
@@ -1,50 +1,11 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
"github.com/cloud-native-application/rudrx/pkg/test"
|
||||
)
|
||||
|
||||
/*
|
||||
func TestNewBindCommand(t *testing.T) {
|
||||
TraitsNotApply := traitDefinitionExample.DeepCopy()
|
||||
TraitsNotApply.Spec.AppliesToWorkloads = []string{"core.oam.dev/v1alpha2.ContainerizedWorkload"}
|
||||
|
||||
cases := map[string]*test.CliTestCase{
|
||||
"WithNoArgs": {
|
||||
Resources: test.InitResources{
|
||||
Create: []runtime.Object{
|
||||
traitDefinitionExample.DeepCopy(),
|
||||
//traitTemplateExample.DeepCopy(),
|
||||
},
|
||||
},
|
||||
ExpectedOutput: "Please append the name of an application. Use `rudr bind -h` for more detailed information.",
|
||||
Args: []string{},
|
||||
WantException: true,
|
||||
},
|
||||
"WithWrongAppconfig": {
|
||||
Resources: test.InitResources{
|
||||
Create: []runtime.Object{
|
||||
traitDefinitionExample.DeepCopy(),
|
||||
//traitTemplateExample.DeepCopy(),
|
||||
},
|
||||
},
|
||||
ExpectedOutput: "applicationconfigurations.core.oam.dev \"frontend\" not found",
|
||||
Args: []string{"frontend"},
|
||||
WantException: true,
|
||||
},
|
||||
"TemplateParametersWork": {
|
||||
Resources: test.InitResources{
|
||||
Create: []runtime.Object{
|
||||
traitDefinitionExample.DeepCopy(),
|
||||
//traitTemplateExample.DeepCopy(),
|
||||
},
|
||||
},
|
||||
ExpectedString: "--replicaCount int",
|
||||
Args: []string{"-h"},
|
||||
},
|
||||
"WorkSuccess": {
|
||||
Resources: test.InitResources{
|
||||
Create: []runtime.Object{
|
||||
@@ -54,10 +15,11 @@ func TestNewBindCommand(t *testing.T) {
|
||||
//traitTemplateExample.DeepCopy(),
|
||||
},
|
||||
},
|
||||
ExpectedOutput: "Applying trait for component app2060\nSucceeded!",
|
||||
ExpectedOutput: "Applying trait for component app2060\nSucceeded!\n",
|
||||
Args: []string{"app2060", "ManualScaler", "--replicaCount", "5"},
|
||||
},
|
||||
}
|
||||
|
||||
test.NewCliTest(t, scheme, NewBindCommand, cases).Run()
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
cmdutil "github.com/cloud-native-application/rudrx/pkg/cmd/util"
|
||||
corev1alpha2 "github.com/crossplane/oam-kubernetes-runtime/apis/core/v1alpha2"
|
||||
"github.com/spf13/cobra"
|
||||
@@ -15,6 +16,7 @@ type deleteOptions struct {
|
||||
AppConfig corev1alpha2.ApplicationConfiguration
|
||||
client client.Client
|
||||
cmdutil.IOStreams
|
||||
Env *EnvMeta
|
||||
}
|
||||
|
||||
func newDeleteOptions(ioStreams cmdutil.IOStreams) *deleteOptions {
|
||||
@@ -39,6 +41,7 @@ func NewDeleteCommand(f cmdutil.Factory, c client.Client, ioStreams cmdutil.IOSt
|
||||
cmd.SetOut(ioStreams.Out)
|
||||
o := newDeleteOptions(ioStreams)
|
||||
o.client = c
|
||||
o.Env, _ = GetEnv()
|
||||
cmd.RunE = func(cmd *cobra.Command, args []string) error {
|
||||
if err := o.Complete(f, cmd, args); err != nil {
|
||||
return err
|
||||
@@ -49,19 +52,13 @@ func NewDeleteCommand(f cmdutil.Factory, c client.Client, ioStreams cmdutil.IOSt
|
||||
}
|
||||
|
||||
func (o *deleteOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
|
||||
namespace, _, err := f.ToRawKubeConfigLoader().Namespace()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(args) < 1 {
|
||||
return errors.New("must specify name for workload")
|
||||
}
|
||||
|
||||
namespaceCover := cmd.Flag("namespace").Value.String()
|
||||
if namespaceCover != "" {
|
||||
namespace = namespaceCover
|
||||
}
|
||||
namespace := o.Env.Namespace
|
||||
|
||||
o.Component.Name = args[0]
|
||||
o.Component.Namespace = namespace
|
||||
o.AppConfig.Name = args[0]
|
||||
|
||||
276
pkg/cmd/env.go
Normal file
276
pkg/cmd/env.go
Normal file
@@ -0,0 +1,276 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
cmdutil "github.com/cloud-native-application/rudrx/pkg/cmd/util"
|
||||
"github.com/gosuri/uitable"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
const DefaultEnvName = "default"
|
||||
|
||||
func NewEnvInitCommand(f cmdutil.Factory, ioStreams cmdutil.IOStreams) *cobra.Command {
|
||||
var envArgs EnvMeta
|
||||
ctx := context.Background()
|
||||
cmd := &cobra.Command{
|
||||
Use: "env:init",
|
||||
DisableFlagsInUseLine: true,
|
||||
Short: "Create environments",
|
||||
Long: "Create environment and switch to it",
|
||||
Example: `rudr env:init test --namespace test`,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return CreateOrUpdateEnv(ctx, &envArgs, args, ioStreams)
|
||||
},
|
||||
}
|
||||
cmd.SetOut(ioStreams.Out)
|
||||
cmd.Flags().StringVar(&envArgs.Namespace, "namespace", "default", "specify K8s namespace for env")
|
||||
return cmd
|
||||
}
|
||||
|
||||
func NewEnvDeleteCommand(f cmdutil.Factory, ioStreams cmdutil.IOStreams) *cobra.Command {
|
||||
ctx := context.Background()
|
||||
cmd := &cobra.Command{
|
||||
Use: "env:delete",
|
||||
DisableFlagsInUseLine: true,
|
||||
Short: "Delete environment",
|
||||
Long: "Delete environment",
|
||||
Example: `rudr env:delete test`,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return DeleteEnv(ctx, args, ioStreams)
|
||||
},
|
||||
}
|
||||
cmd.SetOut(ioStreams.Out)
|
||||
return cmd
|
||||
}
|
||||
|
||||
func NewEnvCommand(f cmdutil.Factory, ioStreams cmdutil.IOStreams) *cobra.Command {
|
||||
ctx := context.Background()
|
||||
cmd := &cobra.Command{
|
||||
Use: "env",
|
||||
DisableFlagsInUseLine: true,
|
||||
Short: "List environments",
|
||||
Long: "List all environments",
|
||||
Example: `rudr env [env-name]`,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return ListEnvs(ctx, args, ioStreams)
|
||||
},
|
||||
}
|
||||
cmd.SetOut(ioStreams.Out)
|
||||
return cmd
|
||||
}
|
||||
|
||||
func NewEnvSwitchCommand(f cmdutil.Factory, ioStreams cmdutil.IOStreams) *cobra.Command {
|
||||
ctx := context.Background()
|
||||
cmd := &cobra.Command{
|
||||
Use: "env:sw",
|
||||
DisableFlagsInUseLine: true,
|
||||
Short: "Switch environments",
|
||||
Long: "switch to another environment",
|
||||
Example: `rudr env test`,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return SwitchEnv(ctx, args, ioStreams)
|
||||
},
|
||||
}
|
||||
cmd.SetOut(ioStreams.Out)
|
||||
return cmd
|
||||
}
|
||||
|
||||
type EnvMeta struct {
|
||||
Namespace string `json:"namespace"`
|
||||
}
|
||||
|
||||
func ListEnvs(ctx context.Context, args []string, ioStreams cmdutil.IOStreams) error {
|
||||
table := uitable.New()
|
||||
table.MaxColWidth = 60
|
||||
table.AddRow("NAME", "NAMESPACE")
|
||||
if len(args) > 0 {
|
||||
envName := args[0]
|
||||
env, err := getEnvByName(envName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
table.AddRow(envName, env.Namespace)
|
||||
ioStreams.Infof(table.String())
|
||||
return nil
|
||||
}
|
||||
envDir, err := getEnvDir()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
files, err := ioutil.ReadDir(envDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, f := range files {
|
||||
if f.IsDir() {
|
||||
continue
|
||||
}
|
||||
data, err := ioutil.ReadFile(filepath.Join(envDir, f.Name()))
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
var envMeta EnvMeta
|
||||
if err = json.Unmarshal(data, &envMeta); err != nil {
|
||||
continue
|
||||
}
|
||||
table.AddRow(f.Name(), envMeta.Namespace)
|
||||
}
|
||||
ioStreams.Infof(table.String())
|
||||
return nil
|
||||
}
|
||||
|
||||
func DeleteEnv(ctx context.Context, args []string, ioStreams cmdutil.IOStreams) error {
|
||||
if len(args) < 1 {
|
||||
return fmt.Errorf("you must specify env name for rudr env:delete command")
|
||||
}
|
||||
envname := args[0]
|
||||
curEnv, err := GetCurrentEnvName()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if envname == curEnv {
|
||||
return fmt.Errorf("you can't delete current using env %s", curEnv)
|
||||
}
|
||||
envdir, err := getEnvDir()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = os.Remove(filepath.Join(envdir, envname)); err != nil {
|
||||
return err
|
||||
}
|
||||
ioStreams.Info(envname + " deleted")
|
||||
return nil
|
||||
}
|
||||
|
||||
func InitDefaultEnv() error {
|
||||
envDir, err := getEnvDir()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = os.MkdirAll(envDir, 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
data, _ := json.Marshal(&EnvMeta{Namespace: DefaultEnvName})
|
||||
if err = ioutil.WriteFile(filepath.Join(envDir, DefaultEnvName), data, 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
curEnvPath, err := getCurrentEnvPath()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = ioutil.WriteFile(curEnvPath, []byte(DefaultEnvName), 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func CreateOrUpdateEnv(ctx context.Context, envArgs *EnvMeta, args []string, ioStreams cmdutil.IOStreams) error {
|
||||
if len(args) < 1 {
|
||||
return fmt.Errorf("you must specify env name for rudr env:init command")
|
||||
}
|
||||
envname := args[0]
|
||||
data, err := json.Marshal(envArgs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
envdir, err := getEnvDir()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = ioutil.WriteFile(filepath.Join(envdir, envname), data, 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
curEnvPath, err := getCurrentEnvPath()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = ioutil.WriteFile(curEnvPath, []byte(envname), 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
ioStreams.Info("Create env succeed, current env is " + envname)
|
||||
return nil
|
||||
}
|
||||
|
||||
func getCurrentEnvPath() (string, error) {
|
||||
home, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return filepath.Join(home, ".rudr", "curenv"), nil
|
||||
}
|
||||
|
||||
func getEnvDir() (string, error) {
|
||||
home, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return filepath.Join(home, ".rudr", "envs"), nil
|
||||
}
|
||||
|
||||
func SwitchEnv(ctx context.Context, args []string, ioStreams cmdutil.IOStreams) error {
|
||||
if len(args) < 1 {
|
||||
return fmt.Errorf("you must specify env name for rudr env command")
|
||||
}
|
||||
envname := args[0]
|
||||
currentEnvPath, err := getCurrentEnvPath()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = getEnvByName(envname)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = ioutil.WriteFile(currentEnvPath, []byte(envname), 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
ioStreams.Info("Switch env succeed, current env is " + envname)
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetCurrentEnvName() (string, error) {
|
||||
currentEnvPath, err := getCurrentEnvPath()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
data, err := ioutil.ReadFile(currentEnvPath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(data), nil
|
||||
}
|
||||
|
||||
func GetEnv() (*EnvMeta, error) {
|
||||
envName, err := GetCurrentEnvName()
|
||||
if err != nil {
|
||||
if !os.IsNotExist(err) {
|
||||
return nil, err
|
||||
}
|
||||
if err = InitDefaultEnv(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
envName = DefaultEnvName
|
||||
}
|
||||
return getEnvByName(envName)
|
||||
}
|
||||
|
||||
func getEnvByName(name string) (*EnvMeta, error) {
|
||||
envdir, err := getEnvDir()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data, err := ioutil.ReadFile(filepath.Join(envdir, name))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var meta EnvMeta
|
||||
if err = json.Unmarshal(data, &meta); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &meta, nil
|
||||
}
|
||||
88
pkg/cmd/env_test.go
Normal file
88
pkg/cmd/env_test.go
Normal file
@@ -0,0 +1,88 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
cmdutil "github.com/cloud-native-application/rudrx/pkg/cmd/util"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestENV(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
// Create Default Env
|
||||
err := InitDefaultEnv()
|
||||
assert.NoError(t, err)
|
||||
|
||||
// check and compare create default env success
|
||||
curEnvName, err := GetCurrentEnvName()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "default", curEnvName)
|
||||
gotEnv, err := GetEnv()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, &EnvMeta{
|
||||
Namespace: "default",
|
||||
}, gotEnv)
|
||||
|
||||
ioStream := cmdutil.IOStreams{In: os.Stdin, Out: os.Stdout, ErrOut: os.Stderr}
|
||||
exp := &EnvMeta{
|
||||
Namespace: "test1",
|
||||
}
|
||||
|
||||
// Create env1
|
||||
err = CreateOrUpdateEnv(ctx, exp, []string{"env1"}, ioStream)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// check and compare create env success
|
||||
curEnvName, err = GetCurrentEnvName()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "env1", curEnvName)
|
||||
gotEnv, err = GetEnv()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, exp, gotEnv)
|
||||
|
||||
// List all env
|
||||
var b bytes.Buffer
|
||||
ioStream.Out = &b
|
||||
err = ListEnvs(ctx, []string{}, ioStream)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, `NAME NAMESPACE
|
||||
default default
|
||||
env1 test1 `, b.String())
|
||||
b.Reset()
|
||||
err = ListEnvs(ctx, []string{"env1"}, ioStream)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, `NAME NAMESPACE
|
||||
env1 test1 `, b.String())
|
||||
ioStream.Out = os.Stdout
|
||||
|
||||
// can not delete current env
|
||||
err = DeleteEnv(ctx, []string{"env1"}, ioStream)
|
||||
assert.Error(t, err)
|
||||
|
||||
// switch to default env
|
||||
err = SwitchEnv(ctx, []string{"default"}, ioStream)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// check switch success
|
||||
gotEnv, err = GetEnv()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, &EnvMeta{
|
||||
Namespace: "default",
|
||||
}, gotEnv)
|
||||
|
||||
// delete env
|
||||
err = DeleteEnv(ctx, []string{"env1"}, ioStream)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// can not switch to non-exist env
|
||||
err = SwitchEnv(ctx, []string{"env1"}, ioStream)
|
||||
assert.Error(t, err)
|
||||
|
||||
// switch success
|
||||
err = SwitchEnv(ctx, []string{"default"}, ioStream)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
@@ -26,84 +26,60 @@ func init() {
|
||||
// used in testing
|
||||
var (
|
||||
workloadTemplateExample = &util.Template{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: "admin.oam.dev/v1alpha2",
|
||||
Kind: "Template",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "containerizedworkload-template",
|
||||
Annotations: map[string]string{
|
||||
"version": "0.0.1",
|
||||
},
|
||||
Namespace: "default",
|
||||
},
|
||||
Spec: util.TemplateSpec{
|
||||
Object: unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "core.oam.dev/v1alpha2",
|
||||
"kind": "ContainerizedWorkload",
|
||||
"metadata": map[string]interface{}{
|
||||
"name": "pod",
|
||||
},
|
||||
"spec": map[string]interface{}{
|
||||
"containers": "",
|
||||
},
|
||||
|
||||
Object: unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "core.oam.dev/v1alpha2",
|
||||
"kind": "ContainerizedWorkload",
|
||||
"metadata": map[string]interface{}{
|
||||
"name": "pod",
|
||||
},
|
||||
"spec": map[string]interface{}{
|
||||
"containers": "",
|
||||
},
|
||||
},
|
||||
LastCommandParam: "image",
|
||||
Parameters: []util.Parameter{
|
||||
util.Parameter{
|
||||
Name: "image",
|
||||
Short: "i",
|
||||
Required: true,
|
||||
Type: "string",
|
||||
FieldPaths: []string{"spec.containers[0].image"},
|
||||
},
|
||||
util.Parameter{
|
||||
Name: "port",
|
||||
Short: "p",
|
||||
Required: false,
|
||||
Type: "int",
|
||||
FieldPaths: []string{"spec.containers[0].ports[0].containerPort"},
|
||||
},
|
||||
},
|
||||
LastCommandParam: "image",
|
||||
Parameters: []util.Parameter{
|
||||
util.Parameter{
|
||||
Name: "image",
|
||||
Short: "i",
|
||||
Required: true,
|
||||
Type: "string",
|
||||
FieldPaths: []string{"spec.containers[0].image"},
|
||||
},
|
||||
util.Parameter{
|
||||
Name: "port",
|
||||
Short: "p",
|
||||
Required: false,
|
||||
Type: "int",
|
||||
FieldPaths: []string{"spec.containers[0].ports[0].containerPort"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
traitTemplateExample = &util.Template{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: "admin.oam.dev/v1alpha2",
|
||||
Kind: "Template",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "manualscalertrait.core.oam.dev-template",
|
||||
Annotations: map[string]string{
|
||||
"version": "0.0.1",
|
||||
},
|
||||
Namespace: "default",
|
||||
},
|
||||
Spec: util.TemplateSpec{
|
||||
Object: unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "core.oam.dev/v1alpha2",
|
||||
"kind": "ManualScalerTrait",
|
||||
"metadata": map[string]interface{}{
|
||||
"name": "pod",
|
||||
},
|
||||
"spec": map[string]interface{}{
|
||||
"replicaCount": "2",
|
||||
},
|
||||
|
||||
Object: unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "core.oam.dev/v1alpha2",
|
||||
"kind": "ManualScalerTrait",
|
||||
"metadata": map[string]interface{}{
|
||||
"name": "pod",
|
||||
},
|
||||
"spec": map[string]interface{}{
|
||||
"replicaCount": "2",
|
||||
},
|
||||
},
|
||||
Parameters: []util.Parameter{
|
||||
util.Parameter{
|
||||
Name: "replicaCount",
|
||||
Short: "i",
|
||||
Required: true,
|
||||
Type: "int",
|
||||
FieldPaths: []string{"spec.replicaCount"},
|
||||
Default: "5",
|
||||
},
|
||||
},
|
||||
Parameters: []util.Parameter{
|
||||
util.Parameter{
|
||||
Name: "replicaCount",
|
||||
Short: "i",
|
||||
Required: true,
|
||||
Type: "int",
|
||||
FieldPaths: []string{"spec.replicaCount"},
|
||||
Default: "5",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -17,8 +17,8 @@ import (
|
||||
)
|
||||
|
||||
type runOptions struct {
|
||||
Namespace string
|
||||
Template cmdutil.Template
|
||||
Env *EnvMeta
|
||||
Component corev1alpha2.Component
|
||||
AppConfig corev1alpha2.ApplicationConfiguration
|
||||
client client.Client
|
||||
@@ -49,6 +49,7 @@ func runSubRunCommand(parentCmd *cobra.Command, f cmdutil.Factory, c client.Clie
|
||||
workloadNames := []string{}
|
||||
o := newRunOptions(ioStreams)
|
||||
o.client = c
|
||||
o.Env, _ = GetEnv()
|
||||
|
||||
// init fake command and pass args to fake command
|
||||
// flags and subcommand append to fake comand and parent command
|
||||
@@ -84,7 +85,8 @@ func runSubRunCommand(parentCmd *cobra.Command, f cmdutil.Factory, c client.Clie
|
||||
var tmp cmdutil.Template
|
||||
tmp, err := cmdutil.ConvertTemplateJson2Object(wd.Spec.Extension)
|
||||
if err != nil {
|
||||
return fmt.Errorf("deploying application hit an issue: %s", err)
|
||||
fmt.Printf("extract template from traitDefinition %v err: %v, ignore it\n", wd.Name, err)
|
||||
continue
|
||||
}
|
||||
name := tmp.Alias
|
||||
workloadNames = append(workloadNames, name)
|
||||
@@ -119,12 +121,6 @@ func runSubRunCommand(parentCmd *cobra.Command, f cmdutil.Factory, c client.Clie
|
||||
}
|
||||
|
||||
func (o *runOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string, ctx context.Context) error {
|
||||
namespace, explicitNamespace, err := f.ToRawKubeConfigLoader().Namespace()
|
||||
if err != nil {
|
||||
return err
|
||||
} else if !explicitNamespace {
|
||||
namespace = "default"
|
||||
}
|
||||
|
||||
argsLength := len(args)
|
||||
lastCommandParam := o.Template.LastCommandParam
|
||||
@@ -167,10 +163,7 @@ func (o *runOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []stri
|
||||
}
|
||||
|
||||
pvd.SetString("metadata.name", strings.ToLower(workloadName))
|
||||
namespaceCover := cmd.Flag("namespace").Value.String()
|
||||
if namespaceCover != "" {
|
||||
namespace = namespaceCover
|
||||
}
|
||||
namespace := o.Env.Namespace
|
||||
o.Component.Spec.Workload.Object = &unstructured.Unstructured{Object: pvd.UnstructuredContent()}
|
||||
o.Component.Name = args[0]
|
||||
o.Component.Namespace = namespace
|
||||
|
||||
@@ -1,13 +1,6 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
"github.com/cloud-native-application/rudrx/pkg/test"
|
||||
)
|
||||
|
||||
/*
|
||||
func TestNewRunCommand(t *testing.T) {
|
||||
// workloadTemplateExample2 := workloadTemplateExample.DeepCopy()
|
||||
workloaddefExample2 := workloaddefExample.DeepCopy()
|
||||
@@ -72,10 +65,11 @@ func TestNewRunCommand(t *testing.T) {
|
||||
appconfigExample,
|
||||
componentExample,
|
||||
},
|
||||
ExpectedOutput: "Creating AppConfig app2060\nSUCCEED",
|
||||
ExpectedOutput: "Creating AppConfig app2060\nSUCCEED\n",
|
||||
Args: []string{"containerized", "app2060", "nginx:1.9.4", "-p", "80"},
|
||||
},
|
||||
}
|
||||
|
||||
test.NewCliTest(t, scheme, NewRunCommand, cases).Run()
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -28,7 +28,7 @@ func TestNewTraitCommand(t *testing.T) {
|
||||
TraitsNotApply,
|
||||
},
|
||||
},
|
||||
ExpectedOutput: "NAME SHORT DEFINITION APPLIES TO STATUS",
|
||||
ExpectedOutput: "NAME ALIAS DEFINITION APPLIES TO STATUS\n",
|
||||
Args: []string{},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
)
|
||||
|
||||
func NewTraitsCommand(f cmdutil.Factory, c client.Client, ioStreams cmdutil.IOStreams) *cobra.Command {
|
||||
func NewTraitsCommand(f cmdutil.Factory, c client.Client, ioStreams cmdutil.IOStreams, args []string) *cobra.Command {
|
||||
ctx := context.Background()
|
||||
var workloadName string
|
||||
cmd := &cobra.Command{
|
||||
@@ -41,7 +41,7 @@ func printTraitList(ctx context.Context, c client.Client, workloadName *string,
|
||||
return fmt.Errorf("Listing Trait Definition hit an issue: %s", err)
|
||||
}
|
||||
|
||||
table.AddRow("NAME", "Alias", "DEFINITION", "APPLIES TO", "STATUS")
|
||||
table.AddRow("NAME", "ALIAS", "DEFINITION", "APPLIES TO", "STATUS")
|
||||
for _, r := range traitList {
|
||||
table.AddRow(r.Name, r.Short, r.Definition, r.AppliesTo, r.Status)
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ func NewTestIOStreams() (IOStreams, *bytes.Buffer, *bytes.Buffer, *bytes.Buffer)
|
||||
}
|
||||
|
||||
func (i *IOStreams) Info(a ...interface{}) {
|
||||
i.Out.Write([]byte(fmt.Sprint(a...)))
|
||||
i.Out.Write([]byte(fmt.Sprintln(a...)))
|
||||
}
|
||||
|
||||
func (i *IOStreams) Infof(format string, a ...interface{}) {
|
||||
@@ -49,5 +49,5 @@ func (i *IOStreams) Errorf(format string, a ...interface{}) {
|
||||
}
|
||||
|
||||
func (i *IOStreams) Error(a ...interface{}) {
|
||||
i.ErrOut.Write([]byte(fmt.Sprint(a...)))
|
||||
i.ErrOut.Write([]byte(fmt.Sprintln(a...)))
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package util
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
@@ -31,7 +32,7 @@ import (
|
||||
type Template struct {
|
||||
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
|
||||
// Important: Run "make" to regenerate code after modifying this file
|
||||
Alias string `json:alias,omitempty`
|
||||
Alias string `json:"alias,omitempty"`
|
||||
Object unstructured.Unstructured `json:"object,omitempty"`
|
||||
LastCommandParam string `json:"lastCommandParam,omitempty"`
|
||||
Parameters []Parameter `json:"parameters,omitempty"`
|
||||
@@ -51,6 +52,12 @@ type Parameter struct {
|
||||
func ConvertTemplateJson2Object(in *runtime.RawExtension) (Template, error) {
|
||||
var t Template
|
||||
var extension Template
|
||||
if in == nil {
|
||||
return t, fmt.Errorf("extension field is nil")
|
||||
}
|
||||
if in.Raw == nil {
|
||||
return t, fmt.Errorf("template object is nil")
|
||||
}
|
||||
err := json.Unmarshal(in.Raw, &extension)
|
||||
if err == nil {
|
||||
t = extension
|
||||
|
||||
@@ -54,9 +54,6 @@ type WorkloadData struct {
|
||||
}
|
||||
|
||||
func ListWorkloads(ctx context.Context, c client.Client) ([]WorkloadData, error) {
|
||||
/*
|
||||
Get trait list by optional filter `workloadName`
|
||||
*/
|
||||
var workloadList []WorkloadData
|
||||
var workloadDefinitionList corev1alpha2.WorkloadDefinitionList
|
||||
err := c.List(ctx, &workloadDefinitionList)
|
||||
|
||||
@@ -4,60 +4,13 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client/config"
|
||||
)
|
||||
|
||||
var (
|
||||
rudrPath, _ = os.Getwd()
|
||||
)
|
||||
|
||||
func createKubernetesClient() (client.Client, error) {
|
||||
c, err := client.New(config.GetConfigOrDie(), client.Options{})
|
||||
|
||||
return c, err
|
||||
}
|
||||
|
||||
func TestCreateKubernetesClient(t *testing.T) {
|
||||
_, err := createKubernetesClient()
|
||||
if err != nil {
|
||||
t.Errorf("Failed to create a Kubernetes client: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
// TestBuildCliBinary is to build rudr binary.
|
||||
func TestBuildCliBinary(t *testing.T) {
|
||||
rudrPath, err := os.Getwd()
|
||||
mainPath := path.Join(rudrPath, "../../cmd/rudrx/main.go")
|
||||
if err != nil {
|
||||
t.Errorf("Failed to build rudr binary: %s", err)
|
||||
}
|
||||
|
||||
cmd := exec.Command("go", "build", "-o", path.Join(rudrPath, "rudr"), mainPath)
|
||||
|
||||
stdout, err := cmd.Output()
|
||||
if err != nil {
|
||||
t.Errorf("Failed to build rudr binary: %s", err)
|
||||
}
|
||||
t.Log(stdout, err)
|
||||
|
||||
// TODO(zzxwill) If this failed, all other test-cases should be terminated
|
||||
|
||||
}
|
||||
|
||||
func Command(name string, arg ...string) *exec.Cmd {
|
||||
commandName := path.Join(rudrPath, name)
|
||||
return exec.Command(commandName, arg...)
|
||||
}
|
||||
|
||||
func TestTraitsList(t *testing.T) {
|
||||
cmd := Command("rudr", []string{"traits", "list"}...)
|
||||
stdout, err := cmd.Output()
|
||||
t.Log(string(stdout), err)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to list traits: %s", err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user