Merge branch 'feature/shadow-debug-able'

* feature/shadow-debug-able:
  ci: add test coverage badges
  add test coverage badges
  add cc test report to travis
  ci: fixed docker login error
  ci: add go mod cache
  ci: clean up travis script
  ci: clean dockerfile.
  feat: add bug log
  test: add mock generator to makefile and regenerate mock
  feat: make shadow debug able
  ci: use datetime as default tag value.
  fix: remove private error check
This commit is contained in:
yunlzheng
2020-03-12 14:01:02 +08:00
23 changed files with 114 additions and 125 deletions
+2 -1
View File
@@ -10,4 +10,5 @@ note/
.jvmrc
.DS_Store
vendor/
vendor/
c.out
+14 -31
View File
@@ -3,49 +3,32 @@ language: go
go:
- 1.13.x
cache:
directories:
- $GOPATH/pkg/mod
services:
- docker
env:
global:
- REGISTRY=registry.cn-hangzhou.aliyuncs.com
- NAMESPACE=registry.cn-hangzhou.aliyuncs.com/rdc-incubator
- BUILDER_REPO=builder
- SHADOW_BASE_REPO=shadow-base
- SHADOW_REPO=kt-connect-shadow
- DASHBOARD_REPO=kt-connect-dashboard
- SERVER_REPO=kt-connect-server
- REGISTRY=registry.cn-hangzhou.aliyuncs.com
before_script:
- export TAG=$(echo $TRAVIS_BRANCH | sed "s/\//-/")
- echo "TAG=${TAG}"
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
- chmod +x ./cc-test-reporter
- ./cc-test-reporter before-build
# - openssl aes-256-cbc -K $encrypted_b5106b5f3da7_key -iv $encrypted_b5106b5f3da7_iv -in test/integration/testdata/config.yaml.enc -out test/integration/testdata/config.yaml -d
script:
# Unit Test
- make -f Makefile -B unit-test
# ktctl
- make -f Makefile build-connect
# Outhers
- docker pull ${NAMESPACE}/${SHADOW_BASE_REPO} || true
- docker pull ${NAMESPACE}/${SHADOW_REPO} || true
- docker pull golang:1.11 || true
- docker pull node:9.11.1 || true
- docker pull alpine || true
- docker build -t ${NAMESPACE}/${BUILDER_REPO} -f docker/builder/Dockerfile .
- docker build -t ${NAMESPACE}/${SHADOW_BASE_REPO} -f docker/shadow/Dockerfile_base .
- docker build -t ${NAMESPACE}/${SHADOW_REPO}:${TAG} --cache-from ${NAMESPACE}/${SHADOW_REPO} -f docker/shadow/Dockerfile .
- docker build -t ${NAMESPACE}/${SERVER_REPO}:${TAG} -f docker/apiserver/Dockerfile .
- docker build -t ${NAMESPACE}/${DASHBOARD_REPO}:${TAG} -f docker/dashboard/Dockerfile .
- docker tag ${NAMESPACE}/${SHADOW_REPO}:${TAG} ${NAMESPACE}/${SHADOW_REPO}
after_success:
- echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin ${REGISTRY}
- docker push ${NAMESPACE}/${SHADOW_REPO}:${TAG}
- docker push ${NAMESPACE}/${SHADOW_REPO}
- docker push ${NAMESPACE}/${DASHBOARD_REPO}:${TAG}
- docker push ${NAMESPACE}/${SERVER_REPO}:${TAG}
- docker push ${NAMESPACE}/${BUILDER_REPO}
- docker push ${NAMESPACE}/${SHADOW_BASE_REPO}
- make unit-test
- make build
after_script:
- ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
deploy:
provider: releases
+14 -13
View File
@@ -1,20 +1,26 @@
PREFIX ?= registry.cn-hangzhou.aliyuncs.com/rdc-incubator
TAG ?= latest
TAG ?= $(shell date +%s)
SHADOW_IMAGE = kt-connect-shadow
SHADOW_BASE_IMAGE = shadow-base
BUILDER_IMAGE = builder
DASHBOARD_IMAGE = kt-connect-dashboard
SERVER_IMAGE = kt-connect-server
# generate mock
generate-mock:
mockgen -source=pkg/kt/command/types.go -destination=pkg/mockd/mock/action_mock.go -package=mock
mockgen -source=pkg/kt/cluster/types.go -destination=pkg/mockd/mock/kubernetes_mock.go -package=mock
mockgen -source=pkg/kt/connect/types.go -destination=pkg/mockd/mock/connect_mock.go -package=mock
# run unit test
unit-test:
mkdir -p artifacts/report/coverage
go test -v -json -cover -coverprofile artifacts/report/coverage/cover.out ./...
go tool cover -html=artifacts/report/coverage/cover.out -o artifacts/report/coverage/index.html
go test -v -json -cover -coverprofile c.out ./...
go tool cover -html=c.out -o artifacts/report/coverage/index.html
# build kt project
build: build-connect build-shadow
build: build-connect build-shadow build-server build-dashboard
# build ktctl
build-connect:
@@ -31,23 +37,18 @@ build-shadow:
docker build -t $(PREFIX)/$(SHADOW_IMAGE):$(TAG) -f docker/shadow/Dockerfile .
docker push $(PREFIX)/$(SHADOW_IMAGE):$(TAG)
# build this first,it's the base image
build-builder:
docker build -t $(PREFIX)/$(BUILDER_IMAGE):$(TAG) -f docker/builder/Dockerfile .
# dlv for debug
build-shadow-dlv:
bin/build-shadow-dlv
build-dashboard:
docker build -t $(PREFIX)/$(DASHBOARD_IMAGE):$(TAG) -f docker/dashboard/Dockerfile . && \
docker build -t $(PREFIX)/$(DASHBOARD_IMAGE):$(TAG) -f docker/dashboard/Dockerfile .
docker push $(PREFIX)/$(DASHBOARD_IMAGE):$(TAG)
build-server:
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o artifacts/apiserver/apiserver-linux-amd64 cmd/server/main.go
docker build -t $(PREFIX)/$(SERVER_IMAGE):$(TAG) -f docker/apiserver/Dockerfile .
release-docker: build-builder build-shadow-base build-shadow build-connect build-dashboard build-server
docker push $(PREFIX)/$(SHADOW_IMAGE)
# todo: push as you want
docker push $(PREFIX)/$(SERVER_IMAGE):$(TAG)
git-release:
bin/release
+4 -1
View File
@@ -1,7 +1,10 @@
KT Connect
===========
[![Build Status](https://travis-ci.org/alibaba/kt-connect.svg?branch=master)](https://travis-ci.org/alibaba/kt-connect) ![License](https://img.shields.io/github/license/alibaba/kt-connect.svg)
[![Build Status](https://travis-ci.org/alibaba/kt-connect.svg?branch=master)](https://travis-ci.org/alibaba/kt-connect)
[![Test Coverage](https://api.codeclimate.com/v1/badges/eb13b3946784bd7c67cc/test_coverage)](https://codeclimate.com/github/alibaba/kt-connect/test_coverage)
[![Maintainability](https://api.codeclimate.com/v1/badges/eb13b3946784bd7c67cc/maintainability)](https://codeclimate.com/github/alibaba/kt-connect/maintainability)
![License](https://img.shields.io/github/license/alibaba/kt-connect.svg)
Management and Integration with your Kubernetes dev environment more efficient.
+4 -2
View File
@@ -14,11 +14,13 @@ func init() {
}
func main() {
log.Info().Msg("Start kt connect proxy")
log.Info().Msg("shadow staring...")
srv := dnsserver.NewDNSServerDefault()
err := srv.ListenAndServe()
if err != nil {
log.Error().Msg(err.Error())
panic(err.Error())
}
log.Info().Msgf("DNS Server Start At 53...\n")
log.Info().Msg("shadow(DNS) start at 53 successful")
log.Info().Msg("shadow start successful")
}
+1 -11
View File
@@ -1,13 +1,3 @@
FROM registry.cn-hangzhou.aliyuncs.com/rdc-incubator/builder as build-deps
LABEL MAINTAINER yunlong <zhenmu.zyl@alibaba-inc.com>
ENV GO111MODULE on
WORKDIR /go/src/github.com/alibaba/kt-connect
COPY . .
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o output/kt-apiserver-linux-amd64 cmd/server/main.go
FROM alpine
COPY --from=build-deps /go/src/github.com/alibaba/kt-connect/output/kt-apiserver-linux-amd64 /usr/local/bin/kt-apiserver
LABEL MAINTAINER yunlong <zhenmu.zyl@alibaba-inc.com>
COPY artifacts/apiserver/apiserver-linux-amd64 /usr/local/bin/kt-apiserver
CMD ["kt-apiserver"]
-12
View File
@@ -1,12 +0,0 @@
FROM golang:1.13
LABEL MAINTAINER yunlong <zhenmu.zyl@alibaba-inc.com>
ENV GO111MODULE on
# Install go debugger
RUN go get -u github.com/go-delve/delve/cmd/dlv
# Install project dependences
WORKDIR /go/src/github.com/alibaba/kt-connect
COPY go.mod .
COPY go.sum .
RUN go mod download
+1 -1
View File
@@ -9,6 +9,6 @@ RUN cnpm run build
FROM nginx:1.15
ENV APP_ENV PROD
COPY --from=build-deps /usr/src/app/build /usr/share/nginx/html
ADD config/nginx/default.conf /etc/nginx/conf.d/default.conf
ADD docker/dashboard/nginx/default.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
+1 -1
View File
@@ -10,4 +10,4 @@ RUN apt-get install -y net-tools
ADD docker/shadow/run.sh /run.sh
RUN chmod 755 /run.sh
CMD ["/run.sh"]
ENTRYPOINT ["/run.sh"]
+6 -1
View File
@@ -1,4 +1,9 @@
FROM registry.cn-hangzhou.aliyuncs.com/rdc-incubator/builder
FROM golang:1.13
LABEL MAINTAINER yunlong <zhenmu.zyl@alibaba-inc.com>
ENV GO111MODULE on
# Install go debugger
RUN go get -u github.com/go-delve/delve/cmd/dlv
FROM registry.cn-hangzhou.aliyuncs.com/rdc-incubator/kt-connect-shadow:latest
COPY --from=0 /go/bin/dlv /usr/sbin/dlv
+44 -31
View File
@@ -39,8 +39,8 @@ func (k *Kubernetes) Deployment(name, namespace string) (deployment *appV1.Deplo
}
// CreateShadow create shadow
func (k *Kubernetes) CreateShadow(name, namespace, image string, labels map[string]string) (podIP, podName, sshcm string, credential *util.SSHCredential, err error) {
return CreateShadow(k.Clientset, name, labels, namespace, image)
func (k *Kubernetes) CreateShadow(name, namespace, image string, labels map[string]string, debug bool) (podIP, podName, sshcm string, credential *util.SSHCredential, err error) {
return CreateShadow(k.Clientset, name, labels, namespace, image, debug)
}
// CreateService create kubernetes service
@@ -143,6 +143,7 @@ func CreateShadow(
labels map[string]string,
namespace,
image string,
debug bool,
) (podIP, podName, sshcm string, credential *util.SSHCredential, err error) {
component, version := labels["kt-component"], labels["version"]
@@ -175,7 +176,7 @@ func CreateShadow(
labels["kt"] = name
client := clientset.AppsV1().Deployments(namespace)
deployment := generatorDeployment(namespace, name, labels, image, sshcm)
deployment := generatorDeployment(namespace, name, labels, image, sshcm, debug)
result, err := client.Create(deployment)
if err != nil {
return
@@ -289,7 +290,44 @@ func generateService(name, namespace string, labels map[string]string, port int)
}
func generatorDeployment(namespace, name string, labels map[string]string, image, volume string) *appV1.Deployment {
func generatorDeployment(namespace, name string, labels map[string]string, image, volume string, debug bool) *appV1.Deployment {
args := []string{}
if debug {
log.Debug().Msg("create shadow with debug mode")
//args = append(args, "--debug")
}
container := v1.Container{
Name: "standalone",
Image: image,
ImagePullPolicy: "Always",
Args: args,
VolumeMounts: []v1.VolumeMount{
{
Name: "ssh-public-key",
MountPath: fmt.Sprintf("/root/%s", vars.SSHAuthKey),
},
},
}
sshVolume := v1.Volume{
Name: "ssh-public-key",
VolumeSource: v1.VolumeSource{
ConfigMap: &v1.ConfigMapVolumeSource{
LocalObjectReference: v1.LocalObjectReference{
Name: volume,
},
Items: []v1.KeyToPath{
{
Key: vars.SSHAuthKey,
Path: "authorized_keys",
},
},
},
},
}
return &appV1.Deployment{
ObjectMeta: metaV1.ObjectMeta{
Name: name,
@@ -306,35 +344,10 @@ func generatorDeployment(namespace, name string, labels map[string]string, image
},
Spec: v1.PodSpec{
Containers: []v1.Container{
{
Name: "standalone",
Image: image,
ImagePullPolicy: "Always",
VolumeMounts: []v1.VolumeMount{
{
Name: "ssh-public-key",
MountPath: fmt.Sprintf("/root/%s", vars.SSHAuthKey),
},
},
},
container,
},
Volumes: []v1.Volume{
{
Name: "ssh-public-key",
VolumeSource: v1.VolumeSource{
ConfigMap: &v1.ConfigMapVolumeSource{
LocalObjectReference: v1.LocalObjectReference{
Name: volume,
},
Items: []v1.KeyToPath{
{
Key: vars.SSHAuthKey,
Path: "authorized_keys",
},
},
},
},
},
sshVolume,
},
},
},
+1 -1
View File
@@ -26,7 +26,7 @@ type KubernetesInterface interface {
Scale(deployment *appV1.Deployment, replicas *int32) (err error)
ServiceHosts(namespace string) (hosts map[string]string)
ClusterCrids(podCIDR string) (cidrs []string, err error)
CreateShadow(name, namespace, image string, labels map[string]string) (podIP, podName, sshcm string, credential *util.SSHCredential, err error)
CreateShadow(name, namespace, image string, labels map[string]string, debug bool) (podIP, podName, sshcm string, credential *util.SSHCredential, err error)
CreateService(name, namespace string, port int, labels map[string]string) (*coreV1.Service, error)
}
+1 -1
View File
@@ -110,7 +110,7 @@ func connectToCluster(shadow connect.ShadowInterface, kubernetes cluster.Kuberne
workload := fmt.Sprintf("kt-connect-daemon-%s", strings.ToLower(util.RandomString(5)))
endPointIP, podName, sshcm, credential, err := kubernetes.CreateShadow(
workload, options.Namespace, options.Image, labels(workload, options),
workload, options.Namespace, options.Image, labels(workload, options), options.Debug,
)
if err != nil {
+3 -3
View File
@@ -59,7 +59,7 @@ func Test_shouldConnectToCluster(t *testing.T) {
ctl := gomock.NewController(t)
kubernetes := mock.NewMockKubernetesInterface(ctl)
shadow := mock.NewMockShadowInterface(ctl)
kubernetes.EXPECT().CreateShadow(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return("172.168.0.2", "shadowName", "sshcm", nil, nil).AnyTimes()
kubernetes.EXPECT().CreateShadow(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return("172.168.0.2", "shadowName", "sshcm", nil, nil).AnyTimes()
kubernetes.EXPECT().ClusterCrids(gomock.Any()).Return([]string{"10.10.10.0/24"}, nil)
shadow.EXPECT().Outbound("shadowName", "172.168.0.2", gomock.Any(), []string{"10.10.10.0/24"}).Return(nil)
@@ -90,7 +90,7 @@ func Test_shouldConnectClusterFailWhenFailCreateShadow(t *testing.T) {
ctl := gomock.NewController(t)
kubernetesInterface := mock.NewMockKubernetesInterface(ctl)
shadowInterface := mock.NewMockShadowInterface(ctl)
kubernetesInterface.EXPECT().CreateShadow(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return("", "", "", nil, errors.New("")).AnyTimes()
kubernetesInterface.EXPECT().CreateShadow(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return("", "", "", nil, errors.New("")).AnyTimes()
type args struct {
shadow connect.ShadowInterface
@@ -115,7 +115,7 @@ func Test_shouldConnectClusterFailWhenFailGetCrids(t *testing.T) {
ctl := gomock.NewController(t)
kubernetes := mock.NewMockKubernetesInterface(ctl)
shadow := mock.NewMockShadowInterface(ctl)
kubernetes.EXPECT().CreateShadow(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return("172.168.0.2", "shadowName", "sshcm", nil, nil).AnyTimes()
kubernetes.EXPECT().CreateShadow(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return("172.168.0.2", "shadowName", "sshcm", nil, nil).AnyTimes()
kubernetes.EXPECT().ClusterCrids(gomock.Any()).Return([]string{}, errors.New("fail to get crid"))
type args struct {
+1 -1
View File
@@ -70,7 +70,7 @@ func (action *Action) Exchange(exchange string, options *options.DaemonOptions)
workload := app.GetName() + "-kt-" + strings.ToLower(util.RandomString(5))
podIP, podName, sshcm, credential, err := kubernetes.CreateShadow(
workload, options.Namespace, options.Image, getExchangeLabels(options.Labels, workload, app))
workload, options.Namespace, options.Image, getExchangeLabels(options.Labels, workload, app), options.Debug)
log.Info().Msgf("create exchange shadow %s in namespace %s", workload, options.Namespace)
if err != nil {
+1 -1
View File
@@ -73,7 +73,7 @@ func (action *Action) Mesh(mesh string, options *options.DaemonOptions) error {
workload := app.GetObjectMeta().GetName() + "-kt-" + meshVersion
labels := getMeshLabels(workload, meshVersion, app, options)
podIP, podName, sshcm, credential, err := kubernetes.CreateShadow(workload, options.Namespace, options.Image, labels)
podIP, podName, sshcm, credential, err := kubernetes.CreateShadow(workload, options.Namespace, options.Image, labels, options.Debug)
if err != nil {
return err
}
+1 -1
View File
@@ -64,7 +64,7 @@ func (action *Action) Run(service string, options *options.DaemonOptions) error
labels[k] = v
}
podIP, podName, sshcm, credential, err := kubernetes.CreateShadow(service, options.Namespace, options.Image, labels)
podIP, podName, sshcm, credential, err := kubernetes.CreateShadow(service, options.Namespace, options.Image, labels, options.Debug)
if err != nil {
return err
}
+1 -1
View File
@@ -126,7 +126,7 @@ func removePrivateKey(options *options.DaemonOptions) {
splits := strings.Split(options.RuntimeOptions.SSHCM, "-")
component, version := splits[1], splits[len(splits)-1]
file := util.PrivateKeyPath(component, version)
if err := os.Remove(file); !os.IsNotExist(err) {
if err := os.Remove(file); os.IsNotExist(err) {
log.Error().Err(err).Msgf("can't delete %s", file)
}
}
+1 -1
View File
@@ -60,7 +60,7 @@ func Generate(privateKeyPath string) (*SSHGenerator, error) {
// PrivateKeyPath ...
func PrivateKeyPath(component, identifier string) string {
return fmt.Sprintf("%s/ktctl/%s/"+vars.SSHPrivateKeyName, HomeDir(), component, identifier)
return fmt.Sprintf("%s/.ktctl/%s/"+vars.SSHPrivateKeyName, HomeDir(), component, identifier)
}
// generatePrivateKey creates a RSA Private Key of specified byte size
+3 -2
View File
@@ -1,13 +1,14 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: ../kt/command/types.go
// Source: pkg/kt/command/types.go
// Package mock is a generated GoMock package.
package mock
import (
reflect "reflect"
options "github.com/alibaba/kt-connect/pkg/kt/options"
gomock "github.com/golang/mock/gomock"
reflect "reflect"
)
// MockActionInterface is a mock of ActionInterface interface
+3 -2
View File
@@ -1,13 +1,14 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: ../kt/connect/types.go
// Source: pkg/kt/connect/types.go
// Package mock is a generated GoMock package.
package mock
import (
reflect "reflect"
util "github.com/alibaba/kt-connect/pkg/kt/util"
gomock "github.com/golang/mock/gomock"
reflect "reflect"
)
// MockShadowInterface is a mock of ShadowInterface interface
+7 -6
View File
@@ -1,15 +1,16 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: ../kt/cluster/types.go
// Source: pkg/kt/cluster/types.go
// Package mock is a generated GoMock package.
package mock
import (
reflect "reflect"
util "github.com/alibaba/kt-connect/pkg/kt/util"
gomock "github.com/golang/mock/gomock"
v1 "k8s.io/api/apps/v1"
v10 "k8s.io/api/core/v1"
reflect "reflect"
)
// MockKubernetesInterface is a mock of KubernetesInterface interface
@@ -94,9 +95,9 @@ func (mr *MockKubernetesInterfaceMockRecorder) ClusterCrids(podCIDR interface{})
}
// CreateShadow mocks base method
func (m *MockKubernetesInterface) CreateShadow(name, namespace, image string, labels map[string]string) (string, string, string, *util.SSHCredential, error) {
func (m *MockKubernetesInterface) CreateShadow(name, namespace, image string, labels map[string]string, debug bool) (string, string, string, *util.SSHCredential, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "CreateShadow", name, namespace, image, labels)
ret := m.ctrl.Call(m, "CreateShadow", name, namespace, image, labels, debug)
ret0, _ := ret[0].(string)
ret1, _ := ret[1].(string)
ret2, _ := ret[2].(string)
@@ -106,9 +107,9 @@ func (m *MockKubernetesInterface) CreateShadow(name, namespace, image string, la
}
// CreateShadow indicates an expected call of CreateShadow
func (mr *MockKubernetesInterfaceMockRecorder) CreateShadow(name, namespace, image, labels interface{}) *gomock.Call {
func (mr *MockKubernetesInterfaceMockRecorder) CreateShadow(name, namespace, image, labels, debug interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateShadow", reflect.TypeOf((*MockKubernetesInterface)(nil).CreateShadow), name, namespace, image, labels)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateShadow", reflect.TypeOf((*MockKubernetesInterface)(nil).CreateShadow), name, namespace, image, labels, debug)
}
// CreateService mocks base method