├── .gitignore ├── LICENSE ├── README.md ├── README.zh-CN.md ├── dockctl ├── cmdbdocker.py ├── commontool.conf ├── commontool.py ├── dockctl.py ├── prettytable.py └── wcsssh.py ├── dockin-opagent ├── Dockerfile ├── Makefile ├── README.zh-CN.md ├── cmd │ └── main.go ├── configs │ ├── application.yaml │ └── log.yaml ├── docs │ ├── daemonset.yaml │ └── how-to-update.md ├── go.mod ├── go.sum ├── internal │ ├── api │ │ ├── exec │ │ │ ├── client.go │ │ │ ├── handler.go │ │ │ ├── handler_test.go │ │ │ ├── message.go │ │ │ └── stream.go │ │ └── prestop │ │ │ └── handle.go │ ├── common │ │ └── access_token.go │ ├── config │ │ ├── app_home.go │ │ ├── config.go │ │ └── config_test.go │ ├── docker │ │ ├── client.go │ │ ├── docker.go │ │ ├── docker_test.go │ │ └── shim │ │ │ ├── exec.go │ │ │ ├── io_stream.go │ │ │ ├── libdocker │ │ │ ├── agent_docker_client.go │ │ │ ├── client.go │ │ │ └── helpers.go │ │ │ └── terminal_size.go │ ├── log │ │ └── logger.go │ ├── model │ │ ├── const.go │ │ ├── container.go │ │ ├── req_dto.go │ │ ├── result.go │ │ └── rm_dto.go │ ├── oom │ │ ├── kmsgparser.go │ │ ├── oom_watcher_linux.go │ │ ├── oom_watcher_unsupported.go │ │ ├── oomparser.go │ │ ├── recorder.go │ │ └── types.go │ ├── rm │ │ └── api.go │ ├── server │ │ ├── api │ │ │ └── core │ │ │ │ └── types.go │ │ ├── remotecommand │ │ │ ├── BUILD │ │ │ ├── attach.go │ │ │ ├── doc.go │ │ │ ├── exec.go │ │ │ ├── httpstream.go │ │ │ └── websocket.go │ │ └── streaming │ │ │ ├── BUILD │ │ │ ├── errors.go │ │ │ ├── request_cache.go │ │ │ ├── request_cache_test.go │ │ │ └── server.go │ ├── utils │ │ ├── aes │ │ │ ├── aes.go │ │ │ └── aes_test.go │ │ ├── cmap │ │ │ ├── concurrent_map.go │ │ │ ├── concurrent_map_bench_test.go │ │ │ └── concurrent_map_test.go │ │ ├── exec_util.go │ │ ├── file_util.go │ │ ├── http │ │ │ ├── encode.go │ │ │ └── http.go │ │ └── string_util.go │ └── ws │ │ ├── client.go │ │ ├── message.go │ │ ├── server.go │ │ ├── stream.go │ │ └── wsstream │ │ ├── conn.go │ │ ├── conn_test.go │ │ ├── doc.go │ │ ├── stream.go │ │ └── stream_test.go ├── readme.md └── scripts │ ├── start.sh │ ├── stop.sh │ └── watchdog.sh ├── dockin-opsctl ├── Makefile ├── README.zh-CN.md ├── cmd │ └── main.go ├── go.mod ├── go.sum ├── internal │ ├── cmd │ │ ├── auth.go │ │ ├── auth_test.go │ │ ├── exec.go │ │ ├── get.go │ │ ├── list.go │ │ ├── root.go │ │ └── ssh.go │ ├── common │ │ ├── connection.go │ │ ├── const.go │ │ ├── describe │ │ │ └── describe.go │ │ ├── interface.go │ │ ├── printer │ │ │ ├── get_print.go │ │ │ ├── get_print_test.go │ │ │ ├── interface.go │ │ │ ├── tablegenerator.go │ │ │ ├── tableprinter.go │ │ │ └── tabwriter.go │ │ ├── protocol │ │ │ └── proto.go │ │ ├── scheme │ │ │ ├── install.go │ │ │ └── scheme.go │ │ └── url.go │ ├── log │ │ └── log.go │ ├── option │ │ ├── const.go │ │ ├── exec_option.go │ │ ├── get_option.go │ │ └── list_option.go │ ├── ssh │ │ ├── client.go │ │ ├── config.go │ │ ├── message.go │ │ ├── model.go │ │ ├── param.go │ │ ├── parser.go │ │ ├── parser_test.go │ │ ├── prompt │ │ │ ├── buffer.go │ │ │ ├── document.go │ │ │ ├── document_test.go │ │ │ ├── input.go │ │ │ ├── input_posix.go │ │ │ ├── input_posix_test.go │ │ │ ├── input_test.go │ │ │ ├── input_windows.go │ │ │ ├── key.go │ │ │ ├── key_bind.go │ │ │ └── key_bind_func.go │ │ ├── runner.go │ │ ├── stream.go │ │ ├── terminal.go │ │ ├── terminal_windows.go │ │ └── validate.go │ ├── utils │ │ ├── aes │ │ │ ├── aes.go │ │ │ └── aes_test.go │ │ ├── base │ │ │ ├── check.go │ │ │ ├── check_test.go │ │ │ └── interconv.go │ │ ├── cmd_parser.go │ │ ├── execCommand_util.go │ │ ├── file_test.go │ │ ├── file_util.go │ │ ├── helpers.go │ │ ├── http.go │ │ └── response_print.go │ └── version │ │ └── version.go └── readme.md ├── dockin-opserver ├── Makefile ├── README.md ├── README.zh-CN.md ├── cmd │ └── main.go ├── configs │ ├── application.yaml │ ├── banner.txt │ ├── cluster │ │ └── kube-config.yaml │ ├── log.yaml │ ├── redis_origin.yaml │ └── server.env ├── go.mod ├── go.sum ├── internal │ ├── api │ │ ├── common.go │ │ ├── ctrl │ │ │ ├── access.go │ │ │ ├── access_test.go │ │ │ ├── account.go │ │ │ ├── account_test.go │ │ │ ├── allow.go │ │ │ ├── control.go │ │ │ ├── templates.go │ │ │ └── version.go │ │ ├── echo │ │ │ ├── echo.go │ │ │ ├── echo_test.go │ │ │ ├── get.go │ │ │ ├── get_test.go │ │ │ ├── node_getter.go │ │ │ └── pod_getter.go │ │ ├── exec │ │ │ ├── common.go │ │ │ ├── exec.go │ │ │ ├── exec_test.go │ │ │ └── interact.go │ │ ├── rm │ │ │ ├── rm.go │ │ │ ├── rm_ops.go │ │ │ └── rm_ops_test.go │ │ ├── ssh │ │ │ └── ssh.go │ │ ├── terminal │ │ │ ├── client.go │ │ │ ├── message.go │ │ │ └── terminal.go │ │ └── validate.go │ ├── cache │ │ ├── keys │ │ │ └── keys.go │ │ └── redis │ │ │ ├── redis_client.go │ │ │ └── redis_test.go │ ├── client │ │ ├── client.go │ │ ├── k8sconfig.go │ │ ├── k8sconfig_test.go │ │ ├── list_watcher.go │ │ ├── manager.go │ │ ├── manager_test.go │ │ ├── whitelist.go │ │ └── whitelist_test.go │ ├── common │ │ ├── app_home.go │ │ ├── bench │ │ │ ├── bench.go │ │ │ ├── bench_test.go │ │ │ └── config.json │ │ ├── const.go │ │ ├── describe │ │ │ └── describe.go │ │ ├── env │ │ │ └── env.go │ │ ├── interface.go │ │ ├── option │ │ │ ├── desc_option.go │ │ │ ├── explain_option.go │ │ │ ├── get_option.go │ │ │ ├── logs_option.go │ │ │ └── utils │ │ │ │ ├── helpers.go │ │ │ │ ├── http.go │ │ │ │ └── url.go │ │ ├── printer │ │ │ ├── get_print.go │ │ │ ├── get_print_test.go │ │ │ ├── interface.go │ │ │ ├── tablegenerator.go │ │ │ ├── tableprinter.go │ │ │ └── tabwriter.go │ │ ├── scheme │ │ │ ├── install.go │ │ │ └── scheme.go │ │ └── ws │ │ │ ├── socketstream.go │ │ │ └── websocket.go │ ├── config │ │ └── config.go │ ├── controller │ │ ├── node.go │ │ └── response.go │ ├── dockin │ │ └── rm_api.go │ ├── informer │ │ ├── event.go │ │ ├── node.go │ │ └── pod.go │ ├── log │ │ └── logger.go │ ├── model │ │ ├── access_token.go │ │ ├── access_token_test.go │ │ ├── ctl.go │ │ ├── ops.go │ │ ├── param.go │ │ ├── result.go │ │ ├── rm.go │ │ └── wide_data.go │ ├── remote │ │ ├── banner.go │ │ ├── config.go │ │ ├── consts.go │ │ ├── context.go │ │ ├── context_test.go │ │ ├── executor.go │ │ ├── executor_docker.go │ │ ├── filter.go │ │ ├── filter_test.go │ │ ├── helpers.go │ │ ├── io_filter.go │ │ ├── io_manager.go │ │ ├── io_manager_test.go │ │ ├── message.go │ │ ├── parser.go │ │ ├── parser_test.go │ │ ├── prompt │ │ │ ├── buffer.go │ │ │ ├── document.go │ │ │ ├── document_test.go │ │ │ ├── input.go │ │ │ ├── input_posix.go │ │ │ ├── input_posix_test.go │ │ │ ├── input_test.go │ │ │ ├── input_windows.go │ │ │ ├── key.go │ │ │ ├── key_bind.go │ │ │ └── key_bind_func.go │ │ ├── runebuf.go │ │ ├── runes.go │ │ ├── session.go │ │ └── stream.go │ └── utils │ │ ├── aes │ │ ├── aes.go │ │ └── aes_test.go │ │ ├── base │ │ ├── check.go │ │ ├── check_test.go │ │ └── interconv.go │ │ ├── batch │ │ ├── batch.go │ │ └── batch_test.go │ │ ├── cmap │ │ ├── concurrent_map.go │ │ ├── concurrent_map_bench_test.go │ │ └── concurrent_map_test.go │ │ ├── cmd │ │ ├── parser.go │ │ └── parser_test.go │ │ ├── file │ │ ├── file.go │ │ └── file_test.go │ │ ├── ip │ │ └── ip.go │ │ ├── rest │ │ └── rest.go │ │ ├── str │ │ └── strings.go │ │ ├── trace │ │ └── seq.go │ │ └── url │ │ ├── codec.go │ │ └── codec_test.go └── scripts │ ├── start.sh │ ├── stop.sh │ └── watchdog.sh ├── dockin.code-workspace └── docs ├── README.zh-CN.md └── images └── dockin.png /.gitignore: -------------------------------------------------------------------------------- 1 | bin 2 | coverage.out 3 | .idea/ 4 | .idea/vcs.xml 5 | *.iml 6 | *.swp 7 | *.log 8 | tags 9 | temp_parser_file 10 | y.output 11 | .DS_Store 12 | build/ 13 | dist/ 14 | .gradle/ 15 | target/ 16 | vendor/ 17 | .vscode 18 | release/ 19 | -------------------------------------------------------------------------------- /dockctl/commontool.conf: -------------------------------------------------------------------------------- 1 | [common] 2 | env = UAT 3 | rule = default 4 | opsctl_name = wcs-opsctl -------------------------------------------------------------------------------- /dockin-opagent/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM centos:7 2 | 3 | WORKDIR /data/app 4 | ENV DOCKER true 5 | 6 | ADD release/*.tar.gz /data/app/ 7 | 8 | ENTRYPOINT ["sh", "-c", "/data/app/dockin-opagent/bin/start.sh"] 9 | -------------------------------------------------------------------------------- /dockin-opagent/Makefile: -------------------------------------------------------------------------------- 1 | BINARY="dockin-opagent" 2 | VERSION=0.1.0 3 | BUILD=`date +%FT%T%z` 4 | 5 | PACKAGES=`go list ./... | grep -v /vendor/` 6 | VETPACKAGES=`go list ./... | grep -v /vendor/ | grep -v /examples/` 7 | GOFILES=`find . -name "*.go" -type f -not -path "./vendor/*"` 8 | 9 | OS=linux 10 | ARCH=amd64 11 | 12 | default: 13 | go mod tidy 14 | go mod vendor 15 | mkdir -p build 16 | cd build && GOOS=${OS} GOARCH=${ARCH} go build -o ${BINARY} ../cmd 17 | 18 | list: 19 | @echo ${PACKAGES} 20 | @echo ${VETPACKAGES} 21 | @echo ${GOFILES} 22 | 23 | fmt: 24 | @gofmt -s -w ${GOFILES} 25 | 26 | fmt-check: 27 | @diff=?(gofmt -s -d $(GOFILES)); \ 28 | if [ -n "$$diff" ]; then \ 29 | echo "Please run 'make fmt' and commit the result:"; \ 30 | echo "$${diff}"; \ 31 | exit 1; \ 32 | fi; 33 | 34 | # test: 35 | # @go test -cpu=1,2,4 -v -tags integration ./... 36 | 37 | vet: 38 | @go vet $(VETPACKAGES) 39 | 40 | clean: 41 | @if [ -f ${BINARY} ] ; then rm ${BINARY} ; fi 42 | 43 | package: 44 | mkdir -p release/${BINARY} 45 | mkdir -p release/${BINARY}/apps 46 | mkdir -p release/${BINARY}/bin 47 | cp build/${BINARY} release/${BINARY}/apps 48 | cp scripts/* release/${BINARY}/bin 49 | cp -r configs release/${BINARY}/ 50 | chmod +rx release/${BINARY}/* 51 | cd release && tar -czf "${BINARY}_${VERSION}.tar.gz" ./${BINARY} 52 | 53 | docker-build: # default 54 | docker build -t ${BINARY}:${VERSION} . 55 | 56 | .PHONY: default fmt fmt-check install vet clean docker-build 57 | -------------------------------------------------------------------------------- /dockin-opagent/configs/application.yaml: -------------------------------------------------------------------------------- 1 | app: 2 | rm: 3 | api: http://127.0.0.1:10002/rmController 4 | container: 5 | ticker: 30 6 | http: 7 | port: 8085 8 | debug: 9 | port: 10102 10 | ims: 11 | logroot: /data/logs/ 12 | docker: 13 | sock: unix:///var/run/docker.sock 14 | qos: 15 | path: /data/cgroup 16 | logs: 17 | cmd-white-list: 18 | - grep 19 | - zgrep 20 | - cat 21 | - head 22 | - tail 23 | - awk 24 | - uniq 25 | - sort 26 | - ls 27 | cmd-timeout: 5000 28 | max-file-size: 3000 29 | max-line: 1000 30 | root: /data/logs/ 31 | -------------------------------------------------------------------------------- /dockin-opagent/configs/log.yaml: -------------------------------------------------------------------------------- 1 | appLogPath: "/data/logs/dockin-agent/app.log" 2 | logLevel: info -------------------------------------------------------------------------------- /dockin-opagent/docs/daemonset.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: DaemonSet 3 | metadata: 4 | labels: 5 | k8s-app: dockin-opagent 6 | name: dockin-opagent 7 | namespace: kube-system 8 | spec: 9 | selector: 10 | matchLabels: 11 | k8s-app: dockin-opagent 12 | template: 13 | metadata: 14 | labels: 15 | k8s-app: dockin-opagent 16 | spec: 17 | hostIPC: true 18 | hostPID: true 19 | containers: 20 | - image: REGISTRY_ENDPOINT/dockin-opagent:0.1.0 21 | imagePullPolicy: Always 22 | name: dockin-opagent 23 | resources: 24 | limits: 25 | cpu: "2000m" 26 | memory: "500Mi" 27 | requests: 28 | cpu: "100m" 29 | memory: "200Mi" 30 | securityContext: 31 | privileged: false 32 | volumeMounts: 33 | - mountPath: /data/logs/ 34 | name: logs-dir 35 | readOnly: false 36 | - mountPath: /var/run/ 37 | name: docker-run 38 | readOnly: false 39 | - mountPath: /data/cgroup/ 40 | name: kubepods 41 | readOnly: false 42 | - mountPath: /logs/ 43 | name: log 44 | readOnly: false 45 | - mountPath: /data/dockin_prestop_info/ 46 | name: prestop-info 47 | readOnly: false 48 | hostNetwork: true 49 | restartPolicy: Always 50 | terminationGracePeriodSeconds: 30 51 | volumes: 52 | - hostPath: 53 | path: /data/logs/ 54 | type: DirectoryOrCreate 55 | name: logs-dir 56 | - hostPath: 57 | path: /var/run/ 58 | type: DirectoryOrCreate 59 | name: docker-run 60 | - hostPath: 61 | path: /sys/fs/cgroup/ 62 | type: DirectoryOrCreate 63 | name: kubepods 64 | - hostPath: 65 | path: /data/logs/dockin-opagent 66 | type: DirectoryOrCreate 67 | name: log 68 | - hostPath: 69 | path: /data/dockin_prestop_info 70 | type: DirectoryOrCreate 71 | name: prestop-info -------------------------------------------------------------------------------- /dockin-opagent/docs/how-to-update.md: -------------------------------------------------------------------------------- 1 | how to remove ds 2 | --- 3 | 1. remove ds 4 | ``` 5 | kubectl delete ds dockin-opagent -n kube-system 6 | ``` 7 | 2. check pod exist 8 | ``` 9 | kubectl get pods -n kube-system|grep dockin-opagent 10 | ``` 11 | 12 | how to install ds 13 | --- 14 | 1. check all pod removed 15 | ``` 16 | kubectl get pods -n kube-system|grep dockin-opagent 17 | ``` 18 | 2. install new ds 19 | ``` 20 | kubectl apply -f daemonset.yaml -n kube-system 21 | ``` 22 | 3. check pod installed 23 | ``` 24 | kubectl get pods -n kube-system|grep dockin-opagent 25 | ``` -------------------------------------------------------------------------------- /dockin-opagent/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/webankfintech/dockin-opagent 2 | 3 | go 1.12 4 | 5 | require ( 6 | github.com/Microsoft/go-winio v0.4.16 // indirect 7 | github.com/Microsoft/hcsshim v0.8.14 // indirect 8 | github.com/containerd/containerd v1.4.3 // indirect 9 | github.com/containerd/continuity v0.0.0-20201208142359-180525291bb7 // indirect 10 | github.com/containerd/fifo v0.0.0-20201026212402-0724c46b320c // indirect 11 | github.com/containerd/ttrpc v1.0.2 // indirect 12 | github.com/containerd/typeurl v1.0.1 // indirect 13 | github.com/docker/distribution v2.7.1+incompatible 14 | github.com/docker/docker v20.10.1+incompatible 15 | github.com/docker/go-connections v0.4.0 // indirect 16 | github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect 17 | github.com/docker/go-units v0.4.0 // indirect 18 | github.com/gogo/googleapis v1.4.0 // indirect 19 | github.com/google/uuid v1.1.3 20 | github.com/gophercloud/gophercloud v0.1.0 // indirect 21 | github.com/gorilla/mux v1.8.0 // indirect 22 | github.com/gorilla/websocket v1.4.2 23 | github.com/jessevdk/go-flags v1.4.0 // indirect 24 | github.com/json-iterator/go v1.1.10 25 | github.com/morikuni/aec v1.0.0 // indirect 26 | github.com/opencontainers/go-digest v1.0.0 27 | github.com/opencontainers/image-spec v1.0.1 // indirect 28 | github.com/opencontainers/runc v0.1.1 // indirect 29 | github.com/opencontainers/selinux v1.8.0 // indirect 30 | github.com/pkg/errors v0.9.1 31 | github.com/sirupsen/logrus v1.7.0 32 | github.com/stretchr/testify v1.6.1 33 | github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 // indirect 34 | go.uber.org/atomic v1.7.0 // indirect 35 | go.uber.org/fx v1.13.1 36 | go.uber.org/goleak v1.1.10 // indirect 37 | golang.org/x/net v0.0.0-20201224014010-6772e930b67b 38 | google.golang.org/grpc v1.34.0 39 | gopkg.in/yaml.v2 v2.4.0 40 | k8s.io/api v0.20.1 41 | k8s.io/apimachinery v0.20.1 42 | k8s.io/apiserver v0.20.1 43 | k8s.io/client-go v11.0.0+incompatible 44 | k8s.io/klog v1.0.0 45 | k8s.io/utils v0.0.0-20201110183641-67b214c5f920 46 | sigs.k8s.io/structured-merge-diff/v3 v3.0.0 // indirect 47 | 48 | ) 49 | -------------------------------------------------------------------------------- /dockin-opagent/internal/api/exec/handler_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package exec 16 | 17 | import ( 18 | "fmt" 19 | "net/http" 20 | "testing" 21 | 22 | docker2 "github.com/webankfintech/dockin-opagent/internal/docker" 23 | ) 24 | 25 | func Test_ExecServer(t *testing.T) { 26 | docker := NewDockerHandler(&docker2.DockerService{}) 27 | http.HandleFunc("/dockin/opagent/exec/serverexec", docker.ServerExec) 28 | http.ListenAndServe(fmt.Sprintf(":%d", 8095), nil) 29 | } 30 | -------------------------------------------------------------------------------- /dockin-opagent/internal/api/exec/stream.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package exec 16 | 17 | import ( 18 | dockershim "github.com/webankfintech/dockin-opagent/internal/docker/shim" 19 | "github.com/webankfintech/dockin-opagent/internal/log" 20 | 21 | "github.com/gorilla/websocket" 22 | ) 23 | 24 | type SocketStream struct { 25 | OpserverWsConn *websocket.Conn 26 | TerminalSize chan dockershim.TerminalSize 27 | // buffer from opserver, need to write to docker 28 | BufferWriteToDocker chan []byte 29 | // buffer from docker ,need to write to opagent 30 | BufferWriteToOpagent chan []byte 31 | UID string 32 | } 33 | 34 | func (stream *SocketStream) Read(p []byte) (size int, err error) { 35 | // read will blocking until the data is ready or the connection is closed 36 | buf := <-stream.BufferWriteToDocker 37 | 38 | log.Logger.Infof("read message from opserver %#v, uid=%s", string(buf), stream.UID) 39 | size = len(buf) 40 | copy(p, buf) 41 | log.Logger.Infof("success handle opagent buffer, data=%v, uid=%s", string(buf), stream.UID) 42 | return 43 | } 44 | 45 | func (stream *SocketStream) Write(p []byte) (size int, err error) { 46 | var ( 47 | copyData []byte 48 | ) 49 | copyData = make([]byte, len(p)) 50 | copy(copyData, p) 51 | size = len(p) 52 | 53 | log.Logger.Infof("write data from docker to opagent, data=%v, uid=%s", string(copyData), stream.UID) 54 | stream.BufferWriteToOpagent <- copyData 55 | log.Logger.Infof("write data from docker to opserver, data=%v, uid=%s", string(copyData), stream.UID) 56 | return 57 | } 58 | -------------------------------------------------------------------------------- /dockin-opagent/internal/config/app_home.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package config 16 | 17 | import ( 18 | "fmt" 19 | "os" 20 | "path/filepath" 21 | "runtime" 22 | "strings" 23 | ) 24 | 25 | const EmptyString = "" 26 | 27 | var appHome string 28 | 29 | const AppHomeEnv = "APP_HOME" 30 | 31 | func init() { 32 | appHome = os.Getenv(AppHomeEnv) 33 | if appHome == EmptyString { 34 | curDir := CurrentDir() 35 | index := strings.Index(curDir, "dockin-opagent") 36 | if index == -1 { 37 | panic(fmt.Errorf("try to look src in current path, but failed")) 38 | } 39 | appHome = filepath.Join(curDir[0:index], "dockin-opagent") 40 | } 41 | } 42 | 43 | func GetAppHome() string { 44 | return appHome 45 | } 46 | 47 | func GetConfPath() string { 48 | return filepath.Join(appHome, "configs") 49 | } 50 | 51 | func CurrentDir() string { 52 | _, dir, _, ok := runtime.Caller(1) 53 | if !ok { 54 | panic(fmt.Errorf("can not get current dir")) 55 | } 56 | return dir 57 | } 58 | -------------------------------------------------------------------------------- /dockin-opagent/internal/config/config_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package config 16 | 17 | import ( 18 | "fmt" 19 | "testing" 20 | ) 21 | 22 | func Test_config(t *testing.T) { 23 | fmt.Println(AgentConf.App.Logs.CmdWhiteList) 24 | } 25 | -------------------------------------------------------------------------------- /dockin-opagent/internal/docker/docker_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package docker 16 | 17 | import "testing" 18 | 19 | func Test_ReadFile(t *testing.T) { 20 | var ( 21 | pidList []string 22 | ) 23 | file := "C:\\Users\\Administrator\\Downloads\\cgroup.procs" 24 | readPidsFromCgroupProcs(file, pidList) 25 | } 26 | -------------------------------------------------------------------------------- /dockin-opagent/internal/docker/shim/io_stream.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package dockershim 16 | 17 | import ( 18 | "bytes" 19 | "io" 20 | "io/ioutil" 21 | "os" 22 | ) 23 | 24 | type IOStreams struct { 25 | // In think, os.Stdin 26 | In io.Reader 27 | // Out think, os.Stdout 28 | Out io.Writer 29 | // ErrOut think, os.Stderr 30 | ErrOut io.Writer 31 | } 32 | 33 | func NewStdIOStreams() *IOStreams { 34 | return &IOStreams{ 35 | In: os.Stdin, 36 | Out: os.Stdout, 37 | ErrOut: os.Stderr, 38 | } 39 | } 40 | 41 | func NewBufferIOStreams() (*IOStreams, *bytes.Buffer, *bytes.Buffer, *bytes.Buffer) { 42 | in := &bytes.Buffer{} 43 | out := &bytes.Buffer{} 44 | errOut := &bytes.Buffer{} 45 | 46 | return &IOStreams{ 47 | In: in, 48 | Out: out, 49 | ErrOut: errOut, 50 | }, in, out, errOut 51 | } 52 | 53 | func NewBufferIOStreamsDiscard() *IOStreams { 54 | in := &bytes.Buffer{} 55 | return &IOStreams{ 56 | In: in, 57 | Out: ioutil.Discard, 58 | ErrOut: ioutil.Discard, 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /dockin-opagent/internal/docker/shim/terminal_size.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package dockershim 16 | 17 | type TerminalSize struct { 18 | Width int 19 | Height int 20 | } 21 | -------------------------------------------------------------------------------- /dockin-opagent/internal/model/const.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package model 16 | 17 | const ( 18 | // mount 19 | PodProcessPath = "/systemd/kubepods" 20 | BestEffort = "besteffort" 21 | Burstable = "burstable" 22 | Guaranteed = "guaranteed" 23 | 24 | PodKmemPath = "/memory/kubepods" 25 | KmemFileName = "memory.kmem.usage_in_bytes" 26 | ) 27 | -------------------------------------------------------------------------------- /dockin-opagent/internal/model/req_dto.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package model 16 | 17 | type ProcessReqDTO struct { 18 | PodName string `json:"podName"` 19 | UserName string `json:"userName"` 20 | Include []string `json:"include"` 21 | Exclude []string `json:"exclude"` 22 | UID string `json:"uid"` 23 | } 24 | 25 | type ProcessDTO struct { 26 | ProcessName string `json:"processName"` 27 | Status string `json:"status"` 28 | CPU float64 `json:"cpu"` 29 | Mem float32 `json:"mem"` 30 | Rss uint64 `json:"rss"` 31 | Vms uint64 `json:"vms"` 32 | Fd int32 `json:"fd"` 33 | UserName string `json:"userName"` 34 | CreateTime int64 `json:"createTime"` 35 | } 36 | -------------------------------------------------------------------------------- /dockin-opagent/internal/model/result.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package model 16 | 17 | import ( 18 | "fmt" 19 | 20 | jsoniter "github.com/json-iterator/go" 21 | ) 22 | 23 | const ( 24 | OK = 0 25 | ErrParam = -1 26 | ErrExec = -2 27 | ) 28 | 29 | type AgentResult struct { 30 | Code int `json:"code"` 31 | Message string `json:"message"` 32 | Data interface{} `json:"data"` 33 | } 34 | 35 | func (a *AgentResult) ToString() string { 36 | return fmt.Sprintf("%+v", a) 37 | } 38 | 39 | func (a *AgentResult) ToJSONString() string { 40 | d, _ := jsoniter.MarshalToString(a) 41 | return d 42 | } 43 | 44 | func (a *AgentResult) ToJSONByte() []byte { 45 | d, _ := jsoniter.Marshal(a) 46 | return d 47 | } 48 | 49 | func NewSuccessAgentResult(data interface{}) *AgentResult { 50 | return &AgentResult{ 51 | Code: 0, 52 | Message: "success", 53 | Data: data, 54 | } 55 | } 56 | 57 | func NewErrorAgentResult(err error) *AgentResult { 58 | return &AgentResult{ 59 | Code: -1, 60 | Message: err.Error(), 61 | } 62 | } 63 | 64 | func NewErrorAgentResultWithCode(err error, code int) *AgentResult { 65 | return &AgentResult{ 66 | Code: -1, 67 | Message: err.Error(), 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /dockin-opagent/internal/model/rm_dto.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package model 16 | 17 | type RmResultDto struct { 18 | Code int `json:"code"` 19 | Data []*RmResultData `json:"data"` 20 | Message string `json:"message"` 21 | } 22 | 23 | type OneRmResultDto struct { 24 | Code int `json:"code"` 25 | Data *RmResultData `json:"data"` 26 | Message string `json:"message"` 27 | } 28 | 29 | type RmResultData struct { 30 | PodName string `json:"podName"` 31 | SubSystem string `json:"subSystem"` 32 | Dcn string `json:"dcn"` 33 | PodIP string `json:"podIp"` 34 | Gateway string `json:"gateway"` 35 | SubnetMask string `json:"subnetMask"` 36 | Namespace string `json:"namespace"` 37 | HostIP string `json:"hostIp"` 38 | CPU string `json:"cpu"` 39 | Mem string `json:"mem"` 40 | Type string `json:"type"` 41 | Port int `json:"port"` 42 | State string `json:"state"` 43 | ClusterID string `json:"clusterId"` 44 | } 45 | 46 | type RmClusterData struct { 47 | Code int `json:"code"` 48 | Data struct { 49 | ClusterID string `json:"clusterId"` 50 | } `json:"data"` 51 | } 52 | -------------------------------------------------------------------------------- /dockin-opagent/internal/oom/oom_watcher_linux.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package oom 16 | 17 | import ( 18 | "github.com/webankfintech/dockin-opagent/internal/log" 19 | 20 | "k8s.io/apimachinery/pkg/util/runtime" 21 | ) 22 | 23 | type realWatcher struct { 24 | kmsgPath string 25 | recorder EventRecorder 26 | } 27 | 28 | var _ Watcher = &realWatcher{} 29 | 30 | func NewWatcher(recorder EventRecorder, kmsgPath string) Watcher { 31 | return &realWatcher{ 32 | kmsgPath: kmsgPath, 33 | recorder: recorder, 34 | } 35 | } 36 | 37 | const systemOOMEvent = "SystemOOM" 38 | 39 | func (ow *realWatcher) Start() error { 40 | oomLog, err := Newoomparser(ow.kmsgPath) 41 | if err != nil { 42 | return err 43 | } 44 | outStream := make(chan *OomInstance, 10) 45 | go oomLog.StreamOoms(outStream) 46 | 47 | go func() { 48 | defer runtime.HandleCrash() 49 | 50 | for event := range outStream { 51 | if event.ContainerName == "/" { 52 | log.Logger.Infof("Got sys oom event: %v", event) 53 | ow.recorder.OnOOMEvent(event) 54 | } 55 | } 56 | log.Logger.Errorf("Unexpectedly stopped receiving OOM notifications") 57 | }() 58 | return nil 59 | } 60 | -------------------------------------------------------------------------------- /dockin-opagent/internal/oom/oom_watcher_unsupported.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package oom 16 | 17 | import ( 18 | v1 "k8s.io/api/core/v1" 19 | "k8s.io/client-go/tools/record" 20 | ) 21 | 22 | type oomWatcherUnsupported struct{} 23 | 24 | var _ Watcher = new(oomWatcherUnsupported) 25 | 26 | func NewWatcher(_ record.EventRecorder) Watcher { 27 | return &oomWatcherUnsupported{} 28 | } 29 | 30 | func (ow *oomWatcherUnsupported) Start(_ *v1.ObjectReference) error { 31 | return nil 32 | } 33 | -------------------------------------------------------------------------------- /dockin-opagent/internal/oom/recorder.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package oom 16 | 17 | type EventRecorder interface { 18 | OnOOMEvent(ins *OomInstance) 19 | } 20 | -------------------------------------------------------------------------------- /dockin-opagent/internal/oom/types.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package oom 16 | 17 | type Watcher interface { 18 | Start() error 19 | } 20 | -------------------------------------------------------------------------------- /dockin-opagent/internal/rm/api.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package rm 16 | 17 | import ( 18 | "fmt" 19 | "time" 20 | 21 | "github.com/webankfintech/dockin-opagent/internal/config" 22 | "github.com/webankfintech/dockin-opagent/internal/log" 23 | "github.com/webankfintech/dockin-opagent/internal/model" 24 | "github.com/webankfintech/dockin-opagent/internal/utils/http" 25 | 26 | jsoniter "github.com/json-iterator/go" 27 | "github.com/pkg/errors" 28 | ) 29 | 30 | var ( 31 | EmptyString = "" 32 | HostKey = "app.rm.api" 33 | rmApiUrl = "" 34 | DefaultTimeout = time.Duration(5 * time.Second) 35 | ) 36 | 37 | func init() { 38 | rmApiUrl = config.AgentConf.App.Rm.API 39 | } 40 | 41 | func GetPodInfoByPodIp(podIp string) (*model.OneRmResultDto, error) { 42 | if EmptyString == podIp { 43 | log.Logger.Warnf("pod ip is empty") 44 | return nil, errors.New("invalid host ip") 45 | } 46 | url := fmt.Sprintf("%s/%s?podIp=%s", rmApiUrl, "getPodInfoByPodIp", podIp) 47 | content, err := http.HttpGet(url, DefaultTimeout) 48 | if err != nil { 49 | log.Logger.Warnf("http get GetPodInfoByPodIp error, url=%s", url) 50 | return nil, err 51 | } 52 | 53 | oneresult := &model.OneRmResultDto{} 54 | err = jsoniter.Unmarshal(content, oneresult) 55 | if err != nil { 56 | log.Logger.Warnf("unmarshal error,get pod info by podIp from rm error=%s", err.Error()) 57 | return nil, err 58 | } 59 | if oneresult.Code != 0 { 60 | err = errors.Errorf("code = %d,get pod info by podIp=%s", oneresult.Code, podIp) 61 | log.Logger.Warnf(err.Error()) 62 | return nil, err 63 | } 64 | return oneresult, nil 65 | } 66 | -------------------------------------------------------------------------------- /dockin-opagent/internal/server/remotecommand/BUILD: -------------------------------------------------------------------------------- 1 | package(default_visibility = ["//visibility:public"]) 2 | 3 | load( 4 | "@io_bazel_rules_go//go:def.bzl", 5 | "go_library", 6 | ) 7 | 8 | go_library( 9 | name = "go_default_library", 10 | srcs = [ 11 | "attach.go", 12 | "doc.go", 13 | "exec.go", 14 | "httpstream.go", 15 | "websocket.go", 16 | ], 17 | importpath = "k8s.io/kubernetes/pkg/kubelet/server/remotecommand", 18 | deps = [ 19 | "//pkg/apis/core:go_default_library", 20 | "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", 21 | "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", 22 | "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", 23 | "//staging/src/k8s.io/apimachinery/pkg/util/httpstream:go_default_library", 24 | "//staging/src/k8s.io/apimachinery/pkg/util/httpstream/spdy:go_default_library", 25 | "//staging/src/k8s.io/apimachinery/pkg/util/remotecommand:go_default_library", 26 | "//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library", 27 | "//staging/src/k8s.io/apiserver/pkg/server/httplog:go_default_library", 28 | "//staging/src/k8s.io/apiserver/pkg/util/wsstream:go_default_library", 29 | "//staging/src/k8s.io/client-go/tools/remotecommand:go_default_library", 30 | "//vendor/k8s.io/klog:go_default_library", 31 | "//vendor/k8s.io/utils/exec:go_default_library", 32 | ], 33 | ) 34 | 35 | filegroup( 36 | name = "package-srcs", 37 | srcs = glob(["**"]), 38 | tags = ["automanaged"], 39 | visibility = ["//visibility:private"], 40 | ) 41 | 42 | filegroup( 43 | name = "all-srcs", 44 | srcs = [":package-srcs"], 45 | tags = ["automanaged"], 46 | ) 47 | -------------------------------------------------------------------------------- /dockin-opagent/internal/server/remotecommand/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package remotecommand // import "k8s.io/kubernetes/pkg/kubelet/server/remotecommand" 16 | -------------------------------------------------------------------------------- /dockin-opagent/internal/server/streaming/BUILD: -------------------------------------------------------------------------------- 1 | package(default_visibility = ["//visibility:public"]) 2 | 3 | load( 4 | "@io_bazel_rules_go//go:def.bzl", 5 | "go_library", 6 | "go_test", 7 | ) 8 | 9 | go_library( 10 | name = "go_default_library", 11 | srcs = [ 12 | "errors.go", 13 | "request_cache.go", 14 | "server.go", 15 | ], 16 | importpath = "k8s.io/kubernetes/pkg/kubelet/server/streaming", 17 | deps = [ 18 | "//pkg/kubelet/apis/cri/runtime/v1alpha2:go_default_library", 19 | "//pkg/kubelet/server/portforward:go_default_library", 20 | "//pkg/kubelet/server/remotecommand:go_default_library", 21 | "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", 22 | "//staging/src/k8s.io/apimachinery/pkg/util/clock:go_default_library", 23 | "//staging/src/k8s.io/apimachinery/pkg/util/remotecommand:go_default_library", 24 | "//staging/src/k8s.io/client-go/tools/remotecommand:go_default_library", 25 | "//vendor/github.com/emicklei/go-restful:go_default_library", 26 | "//vendor/google.golang.org/grpc:go_default_library", 27 | "//vendor/google.golang.org/grpc/codes:go_default_library", 28 | "//vendor/google.golang.org/grpc/status:go_default_library", 29 | ], 30 | ) 31 | 32 | go_test( 33 | name = "go_default_test", 34 | srcs = [ 35 | "request_cache_test.go", 36 | "server_test.go", 37 | ], 38 | embed = [":go_default_library"], 39 | deps = [ 40 | "//pkg/apis/core:go_default_library", 41 | "//pkg/kubelet/apis/cri/runtime/v1alpha2:go_default_library", 42 | "//pkg/kubelet/server/portforward:go_default_library", 43 | "//staging/src/k8s.io/apimachinery/pkg/util/clock:go_default_library", 44 | "//staging/src/k8s.io/client-go/rest:go_default_library", 45 | "//staging/src/k8s.io/client-go/tools/remotecommand:go_default_library", 46 | "//staging/src/k8s.io/client-go/transport/spdy:go_default_library", 47 | "//vendor/github.com/stretchr/testify/assert:go_default_library", 48 | "//vendor/github.com/stretchr/testify/require:go_default_library", 49 | ], 50 | ) 51 | 52 | filegroup( 53 | name = "package-srcs", 54 | srcs = glob(["**"]), 55 | tags = ["automanaged"], 56 | visibility = ["//visibility:private"], 57 | ) 58 | 59 | filegroup( 60 | name = "all-srcs", 61 | srcs = [":package-srcs"], 62 | tags = ["automanaged"], 63 | ) 64 | -------------------------------------------------------------------------------- /dockin-opagent/internal/server/streaming/errors.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package streaming 16 | 17 | import ( 18 | "fmt" 19 | "net/http" 20 | "strconv" 21 | 22 | "google.golang.org/grpc" 23 | "google.golang.org/grpc/codes" 24 | "google.golang.org/grpc/status" 25 | ) 26 | 27 | func ErrorStreamingDisabled(method string) error { 28 | return status.Errorf(codes.NotFound, fmt.Sprintf("streaming method %s disabled", method)) 29 | } 30 | 31 | func ErrorTooManyInFlight() error { 32 | return status.Errorf(codes.ResourceExhausted, "maximum number of in-flight requests exceeded") 33 | } 34 | 35 | func WriteError(err error, w http.ResponseWriter) error { 36 | var status int 37 | switch grpc.Code(err) { 38 | case codes.NotFound: 39 | status = http.StatusNotFound 40 | case codes.ResourceExhausted: 41 | // We only expect to hit this if there is a DoS, so we just wait the full TTL. 42 | // If this is ever hit in steady-state operations, consider increasing the MaxInFlight requests, 43 | // or plumbing through the time to next expiration. 44 | w.Header().Set("Retry-After", strconv.Itoa(int(CacheTTL.Seconds()))) 45 | status = http.StatusTooManyRequests 46 | default: 47 | status = http.StatusInternalServerError 48 | } 49 | w.WriteHeader(status) 50 | _, writeErr := w.Write([]byte(err.Error())) 51 | return writeErr 52 | } 53 | -------------------------------------------------------------------------------- /dockin-opagent/internal/utils/aes/aes.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package aes 16 | 17 | import ( 18 | "crypto/aes" 19 | "crypto/cipher" 20 | "crypto/rand" 21 | "encoding/hex" 22 | "errors" 23 | "fmt" 24 | "io" 25 | ) 26 | 27 | type Aes struct { 28 | block cipher.Block 29 | } 30 | 31 | func NewAes(key string) (*Aes, error) { 32 | block, err := aes.NewCipher([]byte(key)) 33 | if err != nil { 34 | return nil, err 35 | } 36 | 37 | return &Aes{ 38 | block:block, 39 | }, nil 40 | } 41 | 42 | func (a *Aes)AesEncrypt(plaintext string) (string, error) { 43 | ciphertext := make([]byte, aes.BlockSize+len(plaintext)) 44 | iv := ciphertext[:aes.BlockSize] 45 | if _, err := io.ReadFull(rand.Reader, iv); err != nil { 46 | return "", err 47 | } 48 | cipher.NewCFBEncrypter(a.block, iv).XORKeyStream(ciphertext[aes.BlockSize:], 49 | []byte(plaintext)) 50 | return hex.EncodeToString(ciphertext), nil 51 | } 52 | 53 | func (a *Aes)AesDecrypt(d string) (string, error) { 54 | ciphertext, err := hex.DecodeString(d) 55 | if err != nil { 56 | return "", err 57 | } 58 | if len(ciphertext) < aes.BlockSize { 59 | return "", errors.New("ciphertext too short") 60 | } 61 | iv := ciphertext[:aes.BlockSize] 62 | ciphertext = ciphertext[aes.BlockSize:] 63 | fmt.Println(len(ciphertext), len(iv)) 64 | cipher.NewCFBDecrypter(a.block, iv).XORKeyStream(ciphertext, ciphertext) 65 | return string(ciphertext), nil 66 | } -------------------------------------------------------------------------------- /dockin-opagent/internal/utils/aes/aes_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package aes 16 | 17 | import ( 18 | "testing" 19 | 20 | "github.com/stretchr/testify/assert" 21 | ) 22 | 23 | func TestAes(t *testing.T) { 24 | key := "doc-opserver8085" 25 | t.Run("encrypt", func(t *testing.T) { 26 | aes, err := NewAes(key) 27 | assert.NoError(t, err) 28 | 29 | out, err := aes.AesEncrypt(`{"code":0,"msg":"OK", "page":{"totalPage":10,"prePage":0,"nextPage":2,"pageNum":1,"pageSize":10}}`) 30 | assert.NoError(t, err) 31 | t.Log(out) 32 | next, err := aes.AesDecrypt(out) 33 | assert.NoError(t, err) 34 | t.Log(next) 35 | }) 36 | } 37 | -------------------------------------------------------------------------------- /dockin-opagent/internal/utils/exec_util.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package utils 16 | 17 | import ( 18 | "bytes" 19 | "context" 20 | "github.com/webankfintech/dockin-opagent/internal/log" 21 | "github.com/pkg/errors" 22 | "os/exec" 23 | "time" 24 | ) 25 | 26 | func ExecCmd(name string, command string, timeOut int64) (string, error) { 27 | var ( 28 | stdout bytes.Buffer 29 | stderr bytes.Buffer 30 | Timeout = time.Duration(timeOut) * time.Millisecond 31 | ) 32 | ctxt, cancel := context.WithTimeout(context.Background(), Timeout) 33 | defer cancel() 34 | 35 | cmd := exec.CommandContext(ctxt, name, "-c", command) 36 | cmd.Stdout = &stdout 37 | cmd.Stderr = &stderr 38 | 39 | if err := cmd.Start(); err != nil { 40 | log.Logger.Warnf("start cmd:%s err:%s", command, err.Error()) 41 | return "", err 42 | } 43 | 44 | if err := cmd.Wait(); err != nil { 45 | log.Logger.Warnf("cmd:{%s} %s,%s", command, err.Error(), stderr.String()) 46 | return "", errors.Errorf("%s,%s", err.Error(), stderr.String()) 47 | } 48 | 49 | return stdout.String(), nil 50 | } 51 | -------------------------------------------------------------------------------- /dockin-opagent/internal/utils/http/encode.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package http 16 | 17 | import "net/url" 18 | 19 | func UrlEncode(input string) string { 20 | return url.PathEscape(input) 21 | } 22 | 23 | func UrlDecode(input string) (string, error) { 24 | return url.PathUnescape(input) 25 | } 26 | -------------------------------------------------------------------------------- /dockin-opagent/internal/utils/http/http.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package http 16 | 17 | import ( 18 | "io/ioutil" 19 | "net/http" 20 | "time" 21 | 22 | "github.com/webankfintech/dockin-opagent/internal/log" 23 | ) 24 | 25 | func HttpGet(url string, timeout time.Duration) ([]byte, error){ 26 | log.Logger.Infof("send http request url=%s", url) 27 | 28 | req, err := http.NewRequest("GET", url, nil) 29 | if err != nil { 30 | return nil, err 31 | } 32 | 33 | req.Header.Set("Cache-Control", "no-cache") 34 | client := &http.Client{Timeout: timeout} 35 | resp , err := client.Do(req) 36 | if err != nil { 37 | return nil, err 38 | } 39 | 40 | defer resp.Body.Close() 41 | body, err := ioutil.ReadAll(resp.Body) 42 | if err != nil { 43 | log.Logger.Warnf("get method return err, url=%s, err=%s", url, err.Error()) 44 | return nil, err 45 | } 46 | 47 | log.Logger.Infof("send http request finished url=%s, response=%s", url, string(body)) 48 | return body, nil 49 | } 50 | 51 | -------------------------------------------------------------------------------- /dockin-opagent/internal/ws/message.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package ws 16 | 17 | type Message struct { 18 | Env []string `json:"env"` 19 | Cmd []string `json:"cmd"` 20 | Container string `json:"container"` 21 | User string `json:"user"` 22 | WorkingDir string `json:"workingDir"` 23 | Tty bool `json:"tty` 24 | TerminalSize TerminalSize `json:"terminalSize"` 25 | } 26 | 27 | type TerminalSize struct { 28 | Width int `json:"width"` 29 | Height int `json:"height"` 30 | } 31 | 32 | type OutputMessage struct { 33 | MessageType int 34 | Data []byte 35 | } 36 | -------------------------------------------------------------------------------- /dockin-opagent/internal/ws/server.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package ws 16 | -------------------------------------------------------------------------------- /dockin-opagent/internal/ws/stream.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package ws 16 | 17 | import "github.com/webankfintech/dockin-opagent/internal/log" 18 | 19 | type SockStream struct { 20 | client *AgentClient 21 | } 22 | 23 | func (stream *SockStream) Read(p []byte) (size int, err error) { 24 | var ( 25 | msg *Message 26 | ) 27 | 28 | if msg, err = stream.client.WsRead(); err != nil { 29 | log.Logger.Warnf("read data from in chan err=%v", err) 30 | return 31 | } 32 | 33 | } 34 | 35 | func (stream *SockStream) Write(p []byte) (size int, err error) { 36 | 37 | } 38 | 39 | func (stream *SockStream) Resize() (size *TerminalSize) { 40 | 41 | } 42 | -------------------------------------------------------------------------------- /dockin-opagent/internal/ws/wsstream/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package wsstream // import "k8s.io/apiserver/pkg/util/wsstream" 16 | -------------------------------------------------------------------------------- /dockin-opagent/scripts/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (C) @2021 Webank Group Holding Limited 4 | #

5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 6 | # in compliance with the License. You may obtain a copy of the License at 7 | #

8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | #

10 | # Unless required by applicable law or agreed to in writing, software distributed under the License 11 | # is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 12 | # or implied. See the License for the specific language governing permissions and limitations under 13 | # the License. 14 | # 15 | 16 | ################################ 17 | # start.sh 18 | ############################### 19 | 20 | set -e; 21 | 22 | function detect_pid_file(){ 23 | for no in $(seq 1 30); do 24 | if [ -f ${APP_BIN}/sys.pid ]; then 25 | return 0; 26 | else 27 | echo "[$no] detect pid file ..." 28 | sleep 1s; 29 | fi 30 | done 31 | echo "detect pid file timeout." 32 | return 1; 33 | } 34 | 35 | function get_pid { 36 | local ppid="" 37 | if [ -f $APP_BIN/sys.pid ]; then 38 | ppid=$(cat $APP_BIN/sys.pid) 39 | fi 40 | echo "$ppid"; 41 | } 42 | 43 | APP_BIN="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 44 | APP_HOME="$(dirname $APP_BIN)"; [ -d "$APP_HOME" ] || { echo "ERROR failed to detect APP_HOME."; exit 1;} 45 | APP_NAME=$(basename "$APP_HOME") 46 | APP_START_OPTION= 47 | if [ -f $APP_BIN/server.env ];then 48 | APP_START_OPTION=`cat $APP_BIN/server.env | grep APP_START_OPTION::: | awk -F ':::' {'print $2'}` 49 | fi 50 | 51 | # set up the logs dir 52 | APP_LOG=$APP_HOME/logs 53 | if [ ! -d ${APP_LOG} ];then 54 | mkdir ${APP_LOG} 55 | fi 56 | 57 | export APP_HOME=${APP_HOME} 58 | cd $APP_HOME 59 | subsystem=`ls apps` 60 | cd $APP_BIN 61 | 62 | pid=$(get_pid) 63 | if [ -n "$pid" ];then 64 | echo -e "ERROR\t the server is already running (pid=$pid), there is no need to execute start.sh again." 65 | exit 9; 66 | fi 67 | 68 | if [[ "$DOCKER" == true ]]; then 69 | $APP_HOME/apps/${subsystem} ${APP_START_OPTION} >> $APP_LOG/${APP_NAME}.out 2>&1 70 | else 71 | $APP_HOME/apps/${subsystem} ${APP_START_OPTION} >> $APP_LOG/${APP_NAME}.out 2>&1 & 72 | fi 73 | 74 | echo $! > sys.pid 75 | 76 | if detect_pid_file; then 77 | ./watchdog.sh --add-crontab 78 | fi 79 | 80 | 81 | -------------------------------------------------------------------------------- /dockin-opagent/scripts/stop.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (C) @2021 Webank Group Holding Limited 4 | #

5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 6 | # in compliance with the License. You may obtain a copy of the License at 7 | #

8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | #

10 | # Unless required by applicable law or agreed to in writing, software distributed under the License 11 | # is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 12 | # or implied. See the License for the specific language governing permissions and limitations under 13 | # the License. 14 | # 15 | 16 | ################################ 17 | # stop.sh 18 | ############################### 19 | 20 | function get_pid { 21 | local ppid="" 22 | if [ -f $APP_BIN/sys.pid ]; then 23 | ppid=$(cat $APP_BIN/sys.pid) 24 | fi 25 | echo "$ppid"; 26 | } 27 | 28 | APP_BIN="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 29 | APP_NAME=$(basename "$APP_HOME") 30 | APP_HOME="$(dirname $APP_BIN)"; [ -d "$APP_HOME" ] || { echo "ERROR! failed to detect APP_HOME."; exit 1;} 31 | 32 | ${APP_BIN}/watchdog.sh --delete-crontab 33 | pid=$(get_pid) 34 | if [ -z "$pid" ];then 35 | echo -e "INFO\t the server does NOT start yet, there is no need to execute stop.sh." 36 | exit 0; 37 | fi 38 | kill -15 $pid; 39 | stop_timeout=30 40 | for no in $(seq 1 $stop_timeout); do 41 | if ps $PS_PARAM -p "$pid" 2>&1 > /dev/null; then 42 | if [ $no -lt $stop_timeout ]; then 43 | echo "[$no] shutdown server ..." 44 | sleep 1 45 | continue 46 | fi 47 | echo "shutdown server timeout, kill process: $pid" 48 | kill -9 $pid; sleep 1; break; 49 | else 50 | echo "shutdown server ok!"; break; 51 | fi 52 | done 53 | if [ -f $APP_BIN/sys.pid ]; then 54 | rm $APP_BIN/sys.pid 55 | fi 56 | -------------------------------------------------------------------------------- /dockin-opsctl/Makefile: -------------------------------------------------------------------------------- 1 | BINARY="dockin-opsctl" 2 | VERSION=0.1.0 3 | BUILD=`date +%FT%T%z` 4 | 5 | PACKAGES=`go list ./... | grep -v /vendor/` 6 | VETPACKAGES=`go list ./... | grep -v /vendor/ | grep -v /examples/` 7 | GOFILES=`find . -name "*.go" -type f -not -path "./vendor/*"` 8 | 9 | OS=linux 10 | ARCH=amd64 11 | 12 | default: 13 | go mod tidy 14 | go mod vendor 15 | mkdir -p build 16 | GOOS=${OS} GOARCH=${ARCH} go build -o ${BINARY} ./cmd 17 | 18 | list: 19 | @echo ${PACKAGES} 20 | @echo ${VETPACKAGES} 21 | @echo ${GOFILES} 22 | 23 | fmt: 24 | @gofmt -s -w ${GOFILES} 25 | 26 | fmt-check: 27 | @diff=?(gofmt -s -d $(GOFILES)); \ 28 | if [ -n "$$diff" ]; then \ 29 | echo "Please run 'make fmt' and commit the result:"; \ 30 | echo "$${diff}"; \ 31 | exit 1; \ 32 | fi; 33 | 34 | vet: 35 | @go vet $(VETPACKAGES) 36 | 37 | clean: 38 | @if [ -f ${BINARY} ] ; then rm ${BINARY} ; fi 39 | 40 | .PHONY: default fmt fmt-check install vet clean 41 | 42 | -------------------------------------------------------------------------------- /dockin-opsctl/cmd/main.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package main 16 | 17 | import ( 18 | "github.com/webankfintech/dockin-opsctl/internal/cmd" 19 | ) 20 | 21 | func main() { 22 | cmd.NewRootCmd().Execute() 23 | } 24 | -------------------------------------------------------------------------------- /dockin-opsctl/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/webankfintech/dockin-opsctl 2 | 3 | go 1.12 4 | 5 | require ( 6 | github.com/chzyer/logex v1.1.10 // indirect 7 | github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e 8 | github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 // indirect 9 | github.com/evanphx/json-patch v4.2.0+incompatible 10 | github.com/fatih/camelcase v1.0.0 11 | github.com/ghodss/yaml v1.0.0 // indirect 12 | github.com/gogo/protobuf v1.2.1 // indirect 13 | github.com/golang/protobuf v1.3.1 // indirect 14 | github.com/google/btree v1.0.0 // indirect 15 | github.com/google/uuid v1.1.1 16 | github.com/gorilla/websocket v1.4.0 17 | github.com/imdario/mergo v0.3.7 // indirect 18 | github.com/json-iterator/go v1.1.6 19 | github.com/klauspost/compress v1.4.0 20 | github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de 21 | github.com/mattn/go-runewidth v0.0.9 22 | github.com/mattn/go-tty v0.0.3 23 | github.com/mitchellh/go-homedir v1.1.0 24 | github.com/mitchellh/mapstructure v1.1.2 25 | github.com/pkg/errors v0.8.1 26 | github.com/pkg/term v0.0.0-20200520122047-c3ffed290a03 27 | github.com/spf13/cobra v0.0.5 28 | github.com/spf13/pflag v1.0.3 29 | github.com/spf13/viper v1.3.2 30 | github.com/stretchr/testify v1.4.0 31 | github.com/valyala/fasthttp v1.4.0 32 | golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8 33 | golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 // indirect 34 | golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect 35 | gopkg.in/yaml.v2 v2.2.8 // indirect 36 | k8s.io/api v0.0.0-20190711103429-37c3b8b1ca65 37 | k8s.io/apimachinery v0.0.0-20190717022731-0bb8574e0887 38 | k8s.io/cli-runtime v0.0.0-20190711111425-61e036b70227 39 | k8s.io/client-go v12.0.0+incompatible 40 | k8s.io/component-base v0.0.0-20190717023551-b4f50308a616 41 | k8s.io/klog v0.3.3 42 | k8s.io/kubectl v0.0.0-20190704051832-70c55756d672 43 | k8s.io/utils v0.0.0-20190607212802-c55fbcfc754a 44 | mvdan.cc/sh/v3 v3.1.1 45 | 46 | ) 47 | -------------------------------------------------------------------------------- /dockin-opsctl/internal/cmd/auth_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package cmd 16 | 17 | import ( 18 | "testing" 19 | ) 20 | 21 | func TestAuth(t *testing.T) { 22 | op := &AuthOption{ 23 | UserName: "bruceliu", 24 | Password: "123456", 25 | } 26 | op.Run() 27 | } 28 | -------------------------------------------------------------------------------- /dockin-opsctl/internal/cmd/list.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package cmd 16 | 17 | import ( 18 | "github.com/spf13/cobra" 19 | "github.com/webankfintech/dockin-opsctl/internal/option" 20 | "github.com/webankfintech/dockin-opsctl/internal/utils" 21 | "k8s.io/cli-runtime/pkg/genericclioptions" 22 | "k8s.io/kubectl/pkg/util/templates" 23 | ) 24 | 25 | var ( 26 | listLong = templates.LongDesc(`get resource info from rm interface`) 27 | listExample = templates.Examples(` 28 | # get all container info from ip 29 | dockin-opsctl list ip "0.0.0.0" -d dcn 30 | `) 31 | ) 32 | 33 | func NewListCmd(configFlags *genericclioptions.ConfigFlags) *cobra.Command { 34 | o := &option.ListOption{ 35 | Command: "list", 36 | } 37 | cmd := &cobra.Command{ 38 | Use: "list resources [subsysName|subsysId|ip] -d [dcn]", 39 | DisableFlagsInUseLine: true, 40 | Short: "get resource info from rm interface", 41 | Long: listLong, 42 | Example: listExample, 43 | Run: func(cmd *cobra.Command, args []string) { 44 | utils.CheckErr(o.Complete(configFlags, cmd, args)) 45 | utils.CheckErr(o.Run()) 46 | }, 47 | } 48 | 49 | cmd.Flags().StringVarP(&o.Condition, "condition", "d", o.Condition, "According dcn to screening") 50 | return cmd 51 | } 52 | -------------------------------------------------------------------------------- /dockin-opsctl/internal/common/const.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package common 16 | 17 | import "time" 18 | 19 | const ResKey = "doc-opserver8085" 20 | 21 | const DefaultTimeout = time.Duration(time.Minute * 15) 22 | -------------------------------------------------------------------------------- /dockin-opsctl/internal/common/printer/get_print.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package printer 16 | 17 | import ( 18 | "bytes" 19 | "fmt" 20 | "text/tabwriter" 21 | 22 | utils2 "github.com/webankfintech/dockin-opsctl/internal/utils" 23 | jsoniter "github.com/json-iterator/go" 24 | metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1" 25 | ) 26 | 27 | func PrintTable(table *metav1beta1.Table) string { 28 | buf := &bytes.Buffer{} 29 | tw := tabwriter.NewWriter(buf, 5, 8, 1, ' ', 0) 30 | printer := NewTablePrinter(PrintOptions{Wide:true}) 31 | err := printer.PrintObj(table, tw) 32 | utils2.CheckErr(err) 33 | tw.Flush() 34 | return buf.String() 35 | } 36 | 37 | 38 | func PrettyPrint(bytes []byte) { 39 | table := &metav1beta1.Table{} 40 | if err := jsoniter.Unmarshal(bytes, table); err != nil { 41 | fmt.Printf("unmarshal result failed, %v\n", err) 42 | } 43 | fmt.Print(PrintTable(table)) 44 | } 45 | -------------------------------------------------------------------------------- /dockin-opsctl/internal/common/printer/interface.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package printer 16 | 17 | import ( 18 | "io" 19 | 20 | "k8s.io/apimachinery/pkg/runtime" 21 | "k8s.io/apimachinery/pkg/runtime/schema" 22 | ) 23 | 24 | type ResourcePrinter interface { 25 | // Print receives a runtime object, formats it and prints it to a writer. 26 | PrintObj(runtime.Object, io.Writer) error 27 | } 28 | 29 | type ResourcePrinterFunc func(runtime.Object, io.Writer) error 30 | 31 | func (fn ResourcePrinterFunc) PrintObj(obj runtime.Object, w io.Writer) error { 32 | return fn(obj, w) 33 | } 34 | 35 | type PrintOptions struct { 36 | NoHeaders bool 37 | WithNamespace bool 38 | WithKind bool 39 | Wide bool 40 | ShowLabels bool 41 | AbsoluteTimestamps bool 42 | Kind schema.GroupKind 43 | ColumnLabels []string 44 | 45 | SortBy string 46 | 47 | // indicates if it is OK to ignore missing keys for rendering an output template. 48 | AllowMissingKeys bool 49 | } 50 | -------------------------------------------------------------------------------- /dockin-opsctl/internal/common/printer/tabwriter.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package printer 16 | 17 | import ( 18 | "io" 19 | 20 | "github.com/liggitt/tabwriter" 21 | ) 22 | 23 | const ( 24 | tabwriterMinWidth = 6 25 | tabwriterWidth = 4 26 | tabwriterPadding = 3 27 | tabwriterPadChar = ' ' 28 | tabwriterFlags = tabwriter.RememberWidths 29 | ) 30 | 31 | func GetNewTabWriter(output io.Writer) *tabwriter.Writer { 32 | return tabwriter.NewWriter(output, tabwriterMinWidth, tabwriterWidth, tabwriterPadding, tabwriterPadChar, tabwriterFlags) 33 | } 34 | -------------------------------------------------------------------------------- /dockin-opsctl/internal/common/protocol/proto.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package protocol 16 | 17 | import "fmt" 18 | 19 | type Proto struct { 20 | Command string `json:"command"` 21 | Resource string `json:"resource"` 22 | Name string `json:"name"` 23 | PrintType string `json:"printType"` 24 | Flags []string `json:"flags"` 25 | Params map[string]interface{} `json:"params"` 26 | UserName string `json:"userName"` 27 | Password string `json:"password"` 28 | AccessToken string `json:"accessToken"` 29 | Env []string `json:"env"` 30 | User string `json:"user"` 31 | WorkDir string `json:"workDir"` 32 | Container string `json:"container"` 33 | } 34 | 35 | func NewProto() *Proto { 36 | proto := &Proto{} 37 | proto.Params = make(map[string]interface{}) 38 | proto.PrintType = "wide" 39 | proto.Flags = nil 40 | return proto 41 | } 42 | 43 | func (p *Proto) String() string { 44 | return fmt.Sprintf("Command:[%s],Resource:[%s], Name[%s], PrintType:[%s],Flags:[%s], Params:[%s]", 45 | p.Command, p.Resource, p.Name, p.PrintType, p.Flags, p.Params) 46 | } 47 | -------------------------------------------------------------------------------- /dockin-opsctl/internal/common/scheme/scheme.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package scheme 16 | 17 | import ( 18 | "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" 19 | "k8s.io/apimachinery/pkg/runtime" 20 | "k8s.io/apimachinery/pkg/runtime/serializer" 21 | ) 22 | 23 | var Scheme = runtime.NewScheme() 24 | 25 | var Codecs = serializer.NewCodecFactory(Scheme) 26 | 27 | var ParameterCodec = runtime.NewParameterCodec(Scheme) 28 | 29 | func DefaultJSONEncoder() runtime.Encoder { 30 | return unstructured.JSONFallbackEncoder{Encoder: Codecs.LegacyCodec(Scheme.PrioritizedVersionsAllGroups()...)} 31 | } 32 | -------------------------------------------------------------------------------- /dockin-opsctl/internal/common/url.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package common 16 | 17 | import ( 18 | "fmt" 19 | ) 20 | 21 | var ( 22 | RemoteHost = "127.0.0.1:8084" 23 | url = fmt.Sprintf("%s/v1/dockin/opserver", RemoteHost) 24 | ) 25 | 26 | func SetRemoteHost(host string) { 27 | RemoteHost = host 28 | url = fmt.Sprintf("%s/v1/dockin/opserver", RemoteHost) 29 | } 30 | 31 | func GetCommonBaseUrl() string { 32 | return url 33 | } 34 | 35 | func GetCommonUrlByCmd(cmd string) string { 36 | fmt.Println(url) 37 | return fmt.Sprintf("http://%s/%s", url, cmd) 38 | } 39 | 40 | func GetInteractiveUrlByCmd(cmd string) string { 41 | return fmt.Sprintf("ws://%s/%s", url, cmd) 42 | } 43 | -------------------------------------------------------------------------------- /dockin-opsctl/internal/log/log.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package log 16 | 17 | import ( 18 | "fmt" 19 | "os" 20 | "path/filepath" 21 | "runtime" 22 | "time" 23 | ) 24 | 25 | var ( 26 | _consoleDebug = "off" 27 | _loggerFile *os.File 28 | _loggerDir = "/tmp" 29 | _enabled = false 30 | ) 31 | 32 | func init() { 33 | _consoleDebug = os.Getenv("ConsoleDebug") 34 | if _consoleDebug == "on" { 35 | EnableLogger() 36 | } 37 | } 38 | 39 | func EnableLogger() { 40 | if _enabled { 41 | return 42 | } 43 | if err := os.MkdirAll(_loggerDir, 0644); err != nil { 44 | Output("failed to mkdir %s", _loggerDir) 45 | return 46 | } 47 | 48 | loggerFile := filepath.Join(_loggerDir, "terminal.log") 49 | fp, err := os.OpenFile(loggerFile, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644) 50 | if err != nil { 51 | Output("failed to open logger file in %s", loggerFile) 52 | return 53 | } 54 | 55 | _loggerFile = fp 56 | _enabled = true 57 | } 58 | 59 | func Debugf(format string, a ...interface{}) { 60 | if _enabled { 61 | funcName, _, line, _ := runtime.Caller(1) 62 | fm := fmt.Sprintf("[%s]-%s:%d %s", 63 | time.Now().Format("2006-01-02 15:04:05"), runtime.FuncForPC(funcName).Name(), line, format) 64 | fmt.Fprintln(_loggerFile, fmt.Sprintf(fm, a...)) 65 | } 66 | } 67 | 68 | func Close() { 69 | Debugf("close file") 70 | _loggerFile.Close() 71 | } 72 | 73 | func Output(format string, a ...interface{}) { 74 | data := fmt.Sprintf(format, a...) 75 | println(data) 76 | } 77 | -------------------------------------------------------------------------------- /dockin-opsctl/internal/option/const.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package option 16 | 17 | const ( 18 | NoTypeOrNameErr = "no resource type or name provided" 19 | NoResourceNameErr = "no resource name provided" 20 | NoCommandErr = "no command provide" 21 | LogsCommandErr = "logs args err" 22 | CommandParamMissing = "some command param missing" 23 | 24 | GetCommandSuggest = "See 'dockin-opsctl get -h' for help and examples." 25 | ListCommandSuggest = "See 'dockin-opsctl list -h' for help and examples." 26 | ScriptCommandSuggest = "See 'dockin-opsctl script -h' for help and examples." 27 | ExecCommandSuggest = "See 'dockin-opsctl exec -h' for help and examples." 28 | DevopsCommandSuggest = "See 'dockin-opsctl devops -h' for help and examples." 29 | JvmCommandSuggest = "See 'dockin-opsctl jvm -h' for help and examples." 30 | FileCommandSuggest = "See 'dockin-opsctl file -h' for help and examples." 31 | LogsCommandSuggest = "See 'dockin-opsctl logs -h for help and examples." 32 | DescCommandSuggest = "See 'dockin-opsctl descript -h' for help and examples." 33 | SSHCommandSuggest = "See 'dockin-opsctl ssh -h' for help and examples." 34 | DebugCommandSuggest = "See 'dockin-opsctl debug -h' for help and examples." 35 | ) 36 | 37 | const ( 38 | UploadFileErr = "upload file failed!" 39 | DownloadFileErr = "download file failed!" 40 | ListErr = "" 41 | GetErr = "" 42 | ExecErr = "" 43 | JvmErr = "" 44 | ScriptErr = "" 45 | ) 46 | -------------------------------------------------------------------------------- /dockin-opsctl/internal/ssh/config.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package ssh 16 | 17 | type DockinExecConfig struct { 18 | UserName string `json:"userName"` 19 | Password string `json:"password"` 20 | AccessToken string `json:"accessToken"` 21 | 22 | Env []string `json:"env"` 23 | 24 | Width int `json:"width"` 25 | 26 | Height int `json:"height"` 27 | 28 | PodName string `json:"podName"` 29 | 30 | ContainerName string `json:"containerName"` 31 | 32 | Rule string `json:"rule"` 33 | 34 | Namespace string `json:"namespace"` 35 | 36 | User string `json:"user"` 37 | 38 | WorkDir string `json:"workDir"` 39 | 40 | Cmd string `json:"cmd"` 41 | 42 | TTY bool `json:"tty"` 43 | } 44 | -------------------------------------------------------------------------------- /dockin-opsctl/internal/ssh/message.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package ssh 16 | 17 | import jsoniter "github.com/json-iterator/go" 18 | 19 | const ( 20 | MsgCmd = "cmd" 21 | MsgResize = "resize" 22 | ) 23 | 24 | type Message struct { 25 | Type string `json:"type"` 26 | 27 | Cmd string `json:"cmd"` 28 | 29 | Cols int `json:"cols"` 30 | 31 | Rows int `json:"rows"` 32 | 33 | CmdLine string `json:"cmdLine"` 34 | } 35 | 36 | func (m *Message) ToByte() []byte { 37 | data, _ := jsoniter.Marshal(m) 38 | return data 39 | } 40 | 41 | func newCmdMessage(body rune) *Message { 42 | return &Message{ 43 | Type: MsgCmd, 44 | Cmd: string(body), 45 | } 46 | } 47 | 48 | func newResizeMessage(width, height int) *Message { 49 | return &Message{ 50 | Type: MsgResize, 51 | Cols: width, 52 | Rows: height, 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /dockin-opsctl/internal/ssh/model.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package ssh 16 | 17 | import "time" 18 | 19 | var DockinAesHeader = "access-token" 20 | 21 | type PodInfo struct { 22 | PodName string `json:"podName"` 23 | ClusterId string `json:"clusterId"` 24 | PodIp string `json:"podIp"` 25 | HostIp string `json:"hostIp"` 26 | } 27 | 28 | type OPServerResult struct { 29 | Code int 30 | Message string 31 | Data interface{} 32 | } 33 | 34 | type UserIdentity struct { 35 | UserName string `json:"userName"` 36 | Password string `json:"password"` 37 | Rule string `json:"rule"` 38 | Expire int64 `json:"expire"` 39 | CreateTime time.Time `json:"createTime"` 40 | AccessToken string `json:"accessToken"` 41 | } 42 | -------------------------------------------------------------------------------- /dockin-opsctl/internal/ssh/param.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package ssh 16 | 17 | type SSHParam struct { 18 | UserName string `json:"userName"` 19 | Password string `json:"password"` 20 | AccessToken string `json:"accessToken"` 21 | HostIp string `json:"hostIp"` 22 | Port int `json:"port"` 23 | Width int `json:"width"` 24 | Height int `json:"height"` 25 | Instance string `json:"instance"` 26 | } 27 | -------------------------------------------------------------------------------- /dockin-opsctl/internal/ssh/parser_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package ssh 16 | 17 | import ( 18 | "testing" 19 | 20 | "github.com/stretchr/testify/assert" 21 | ) 22 | 23 | func Test_parse_cd(t *testing.T) { 24 | t.Run("pure cd", func(t *testing.T) { 25 | list, err := ParseCmdlineToCmdUnitList("cd /data") 26 | assert.NoError(t, err) 27 | t.Logf("%#v", list) 28 | }) 29 | 30 | t.Run("with param", func(t *testing.T) { 31 | list, err := ParseCmdlineToCmdUnitList("cd -a /data") 32 | assert.NoError(t, err) 33 | t.Logf("%#v", list) 34 | }) 35 | 36 | t.Run("with param reverse", func(t *testing.T) { 37 | list, err := ParseCmdlineToCmdUnitList("cd /data -a -l") 38 | assert.NoError(t, err) 39 | t.Logf("%#v", list) 40 | }) 41 | 42 | t.Run("with param reverse combine", func(t *testing.T) { 43 | list, err := ParseCmdlineToCmdUnitList("cd /data -a -l;ls -al /tmp") 44 | assert.NoError(t, err) 45 | t.Logf("%#v", list) 46 | }) 47 | 48 | t.Run("|", func(t *testing.T) { 49 | list, err := ParseCmdlineToCmdUnitList("cd /data -a -l>/tmp") 50 | assert.NoError(t, err) 51 | t.Logf("%#v", list) 52 | }) 53 | } 54 | -------------------------------------------------------------------------------- /dockin-opsctl/internal/ssh/prompt/input_posix_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package prompt 16 | 17 | import ( 18 | "testing" 19 | ) 20 | 21 | func TestPosixParserGetKey(t *testing.T) { 22 | pp := &PosixParser{} 23 | scenarioTable := []struct { 24 | input []byte 25 | expected Key 26 | }{ 27 | { 28 | input: []byte{0x1b}, 29 | expected: Escape, 30 | }, 31 | { 32 | input: []byte{'a'}, 33 | expected: NotDefined, 34 | }, 35 | } 36 | 37 | for _, s := range scenarioTable { 38 | key := pp.GetKey(s.input) 39 | if key != s.expected { 40 | t.Errorf("Should be %s, but got %s", key, s.expected) 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /dockin-opsctl/internal/ssh/prompt/key.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package prompt 16 | 17 | type Key int 18 | 19 | type ASCIICode struct { 20 | Key Key 21 | ASCIICode []byte 22 | } 23 | 24 | const ( 25 | Escape Key = iota 26 | ControlC 27 | ControlR 28 | Right 29 | Left 30 | LeftCursor 31 | Home 32 | End 33 | Delete 34 | Backspace 35 | Tab 36 | Enter 37 | 38 | NotDefined 39 | ) 40 | -------------------------------------------------------------------------------- /dockin-opsctl/internal/ssh/prompt/key_bind.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package prompt 16 | 17 | type KeyBindFunc func(*Buffer) 18 | 19 | type KeyBind struct { 20 | Key Key 21 | Fn KeyBindFunc 22 | } 23 | 24 | type ASCIICodeBind struct { 25 | ASCIICode []byte 26 | Fn KeyBindFunc 27 | } 28 | 29 | type KeyBindMode string 30 | 31 | const ( 32 | // CommonKeyBind is a mode without any keyboard shortcut 33 | CommonKeyBind KeyBindMode = "common" 34 | // EmacsKeyBind is a mode to use emacs-like keyboard shortcut 35 | EmacsKeyBind KeyBindMode = "emacs" 36 | ) 37 | 38 | var CommonKeyBindings = []KeyBind{ 39 | // Go to the End of the line 40 | { 41 | Key: End, 42 | Fn: GoLineEnd, 43 | }, 44 | // Go to the beginning of the line 45 | { 46 | Key: Home, 47 | Fn: GoLineBeginning, 48 | }, 49 | // Delete character under the cursor 50 | { 51 | Key: Delete, 52 | Fn: DeleteChar, 53 | }, 54 | // Backspace 55 | { 56 | Key: Backspace, 57 | Fn: DeleteBeforeChar, 58 | }, 59 | // Right allow: Forward one character 60 | { 61 | Key: Right, 62 | Fn: GoRightChar, 63 | }, 64 | // Left allow: Backward one character 65 | { 66 | Key: Left, 67 | Fn: GoLeftChar, 68 | }, 69 | // delete 70 | { 71 | Key: Delete, 72 | Fn: DeleteBeforeChar, 73 | }, 74 | // remote cursor display 75 | { 76 | Key: LeftCursor, 77 | Fn: Empty, 78 | }, 79 | } 80 | -------------------------------------------------------------------------------- /dockin-opsctl/internal/ssh/prompt/key_bind_func.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package prompt 16 | 17 | func GoLineEnd(buf *Buffer) { 18 | x := []rune(buf.Document().TextAfterCursor()) 19 | buf.CursorRight(len(x)) 20 | } 21 | 22 | func GoLineBeginning(buf *Buffer) { 23 | x := []rune(buf.Document().TextBeforeCursor()) 24 | buf.CursorLeft(len(x)) 25 | } 26 | 27 | func DeleteChar(buf *Buffer) { 28 | buf.Delete(1) 29 | } 30 | 31 | func DeleteWord(buf *Buffer) { 32 | buf.DeleteBeforeCursor(len([]rune(buf.Document().TextBeforeCursor())) - buf.Document().FindStartOfPreviousWordWithSpace()) 33 | } 34 | 35 | func DeleteBeforeChar(buf *Buffer) { 36 | buf.DeleteBeforeCursor(1) 37 | } 38 | 39 | func GoRightChar(buf *Buffer) { 40 | buf.CursorRight(1) 41 | } 42 | 43 | func GoLeftChar(buf *Buffer) { 44 | buf.CursorLeft(1) 45 | } 46 | 47 | func GoRightWord(buf *Buffer) { 48 | buf.CursorRight(buf.Document().FindEndOfCurrentWordWithSpace()) 49 | } 50 | 51 | func GoLeftWord(buf *Buffer) { 52 | buf.CursorLeft(len([]rune(buf.Document().TextBeforeCursor())) - buf.Document().FindStartOfPreviousWordWithSpace()) 53 | } 54 | 55 | func Empty(buf *Buffer) { 56 | 57 | } -------------------------------------------------------------------------------- /dockin-opsctl/internal/ssh/stream.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package ssh 16 | 17 | import ( 18 | "os" 19 | 20 | "github.com/webankfintech/dockin-opsctl/internal/log" 21 | ) 22 | 23 | var ( 24 | Stdin = os.Stdin 25 | Stdout = os.Stdout 26 | Stderr = os.Stderr 27 | appSuffix = "]$ " 28 | rootSuffix = "]# " 29 | ) 30 | 31 | type ReadWriter struct { 32 | } 33 | 34 | func (rw ReadWriter)Write(p []byte) (n int, err error) { 35 | log.Debugf("receive output:%v, byte=%v", string(p), p) 36 | n = len(p) 37 | Stdout.Write(p) 38 | return 39 | } -------------------------------------------------------------------------------- /dockin-opsctl/internal/ssh/terminal.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | // +build linux 15 | package ssh 16 | 17 | import ( 18 | "fmt" 19 | "os" 20 | "os/signal" 21 | "syscall" 22 | 23 | "github.com/webankfintech/dockin-opsctl/internal/log" 24 | 25 | "golang.org/x/crypto/ssh/terminal" 26 | ) 27 | 28 | func UpdateTerminalSize(winSize chan WindowSize, exitChan chan byte) { 29 | go func() { 30 | // SIGWINCH is sent to the process when the window size of the terminal has 31 | // changed. 32 | sigwinchCh := make(chan os.Signal, 1) 33 | signal.Notify(sigwinchCh, syscall.SIGWINCH) 34 | 35 | fd := int(os.Stdout.Fd()) 36 | termWidth, termHeight, err := terminal.GetSize(fd) 37 | if err != nil { 38 | fmt.Println(err) 39 | } 40 | 41 | for { 42 | select { 43 | // The client updated the size of the local PTY. This change needs to occur 44 | // on the server side PTY as well. 45 | case sigwinch := <-sigwinchCh: 46 | if sigwinch == nil { 47 | return 48 | } 49 | currTermWidth, currTermHeight, err := terminal.GetSize(fd) 50 | if err != nil { 51 | log.Debugf("Unable to send window-change reqest: %s.", err) 52 | continue 53 | } 54 | 55 | // Terminal size has not changed, don't do anything. 56 | if currTermHeight == termHeight && currTermWidth == termWidth { 57 | continue 58 | } 59 | 60 | log.Debugf("update window size change, from:%dx%d to %dx%d", termWidth, termHeight, currTermWidth, currTermHeight) 61 | 62 | winSize <- WindowSize{ 63 | Width: currTermWidth, 64 | Height: currTermHeight, 65 | } 66 | termWidth, termHeight = currTermWidth, currTermHeight 67 | case <-exitChan: 68 | log.Debugf("exit the window handle") 69 | return 70 | } 71 | } 72 | }() 73 | 74 | } 75 | -------------------------------------------------------------------------------- /dockin-opsctl/internal/ssh/terminal_windows.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | // +build windows 16 | package ssh 17 | 18 | // on windows just for mock, as no api to catch the terminal size change 19 | // maybe later found it 20 | func UpdateTerminalSize(winSize chan WindowSize, exitChan chan byte) { 21 | } 22 | -------------------------------------------------------------------------------- /dockin-opsctl/internal/ssh/validate.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package ssh 16 | 17 | import ( 18 | "fmt" 19 | "github.com/pkg/errors" 20 | "time" 21 | 22 | "github.com/webankfintech/dockin-opsctl/internal/common" 23 | "github.com/webankfintech/dockin-opsctl/internal/log" 24 | "github.com/webankfintech/dockin-opsctl/internal/utils" 25 | jsoniter "github.com/json-iterator/go" 26 | "github.com/mitchellh/mapstructure" 27 | ) 28 | 29 | 30 | func ValidatePod(rule, podName, userName string) (podInfo *PodInfo, err error) { 31 | baseUrl := common.GetCommonUrlByCmd("ctrl/getPodByName") 32 | reqUrl := fmt.Sprintf("%s?rule=%s&podName=%s&userName=%s", baseUrl, rule, podName, userName) 33 | body, err := utils.HttpGetWithTimeout(reqUrl, time.Second*3) 34 | if err != nil { 35 | log.Debugf("timeout to get pod failed podName=%s, rule=%s", err.Error(), podName, rule) 36 | return nil, errors.Errorf("timeout to get pod info failed,podName=%s,rule=%s", podName, rule) 37 | } 38 | 39 | result := make(map[string]interface{}) 40 | if err := jsoniter.Unmarshal(body, &result); err != nil { 41 | return nil, errors.New("validate pod or account failed") 42 | } 43 | 44 | code := result["Code"].(float64) 45 | if code != 0 { 46 | msg := result["Message"].(string) 47 | return nil, errors.Errorf("get pod from server failed, message=%s", msg) 48 | } 49 | 50 | //将 map 转换为指定的结构体 51 | if err := mapstructure.Decode(result["Data"].(map[string]interface{}), &podInfo); err != nil { 52 | log.Debugf("mapstructure Decode Data map=%v to PodInfo failed", result["Data"]) 53 | return nil, errors.Errorf("parse login response data faild") 54 | } 55 | 56 | return podInfo, nil 57 | 58 | } 59 | 60 | -------------------------------------------------------------------------------- /dockin-opsctl/internal/utils/aes/aes.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package aes 16 | 17 | import ( 18 | "crypto/aes" 19 | "crypto/cipher" 20 | "crypto/rand" 21 | "encoding/hex" 22 | "errors" 23 | "io" 24 | ) 25 | 26 | type Aes struct { 27 | block cipher.Block 28 | } 29 | 30 | func NewAes(key string) (*Aes, error) { 31 | block, err := aes.NewCipher([]byte(key)) 32 | if err != nil { 33 | return nil, err 34 | } 35 | 36 | return &Aes{ 37 | block: block, 38 | }, nil 39 | } 40 | 41 | func (a *Aes) AesEncrypt(plaintext string) (string, error) { 42 | ciphertext := make([]byte, aes.BlockSize+len(plaintext)) 43 | iv := ciphertext[:aes.BlockSize] 44 | if _, err := io.ReadFull(rand.Reader, iv); err != nil { 45 | return "", err 46 | } 47 | cipher.NewCFBEncrypter(a.block, iv).XORKeyStream(ciphertext[aes.BlockSize:], 48 | []byte(plaintext)) 49 | return hex.EncodeToString(ciphertext), nil 50 | } 51 | 52 | func (a *Aes) AesDecrypt(d string) (string, error) { 53 | ciphertext, err := hex.DecodeString(d) 54 | if err != nil { 55 | return "", err 56 | } 57 | if len(ciphertext) < aes.BlockSize { 58 | return "", errors.New("ciphertext too short") 59 | } 60 | iv := ciphertext[:aes.BlockSize] 61 | ciphertext = ciphertext[aes.BlockSize:] 62 | cipher.NewCFBDecrypter(a.block, iv).XORKeyStream(ciphertext, ciphertext) 63 | return string(ciphertext), nil 64 | } 65 | -------------------------------------------------------------------------------- /dockin-opsctl/internal/utils/aes/aes_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package aes 16 | 17 | import ( 18 | "fmt" 19 | "testing" 20 | ) 21 | 22 | func Test_Aes(t *testing.T) { 23 | biz := "doc-opserver8085" 24 | fmt.Println(biz) 25 | aes, _ := NewAes(biz) 26 | str1, _ := aes.AesEncrypt("{\"2\":\"efg\",\"1\":\"abc\"}") 27 | fmt.Println("str1:", str1) 28 | str2, _ := aes.AesDecrypt(str1) 29 | fmt.Println("str2", str2) 30 | 31 | aes1, _ := NewAes(biz) 32 | str3, _ := aes1.AesDecrypt(str1) 33 | fmt.Println("str3", str3) 34 | } 35 | -------------------------------------------------------------------------------- /dockin-opsctl/internal/utils/base/check.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package base 16 | 17 | import ( 18 | "github.com/google/uuid" 19 | "regexp" 20 | "strings" 21 | ) 22 | 23 | func IsIp(input string) bool { 24 | pattern := "[\\d]+\\.[\\d]+\\.[\\d]+\\.[\\d]+" 25 | matched, _ := regexp.MatchString(pattern, input) 26 | return matched 27 | } 28 | 29 | func IsSubsystem(input string) bool { 30 | cnt := strings.Count(input, "-") 31 | return cnt == 1 32 | } 33 | 34 | func IsPodName(input string) bool { 35 | cnt := strings.Count(input, "-") 36 | return cnt > 1 37 | } 38 | 39 | func IsSubSystemId(input string) bool { 40 | pattern := `^[0-9]\d*$` 41 | matched, _ := regexp.MatchString(pattern, input) 42 | return matched 43 | } 44 | 45 | func IsUUid(input string) bool { 46 | if _, err := uuid.Parse(input); err != nil { 47 | return false 48 | } 49 | return true 50 | } 51 | -------------------------------------------------------------------------------- /dockin-opsctl/internal/utils/base/check_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package base 16 | 17 | import ( 18 | "testing" 19 | 20 | "github.com/stretchr/testify/assert" 21 | ) 22 | 23 | func TestIsSubSystemId(t *testing.T) { 24 | t.Run("right system id", func(t *testing.T) { 25 | input := "5250" 26 | assert.True(t, IsSubSystemId(input)) 27 | }) 28 | 29 | t.Run("right system id 0", func(t *testing.T) { 30 | input := "0" 31 | assert.True(t, IsSubSystemId(input)) 32 | }) 33 | 34 | t.Run("with system name", func(t *testing.T) { 35 | input := "525dockin-test" 36 | assert.False(t, IsSubSystemId(input)) 37 | }) 38 | 39 | t.Run("with mixture name", func(t *testing.T) { 40 | input := "dockin-test" 41 | assert.False(t, IsSubSystemId(input)) 42 | }) 43 | } 44 | -------------------------------------------------------------------------------- /dockin-opsctl/internal/utils/execCommand_util.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package utils 16 | 17 | import ( 18 | "bytes" 19 | "context" 20 | "github.com/pkg/errors" 21 | "os/exec" 22 | "time" 23 | ) 24 | 25 | func ExecCmd(name string, command string, timeOut int64) (string, error) { 26 | var ( 27 | stdout bytes.Buffer 28 | stderr bytes.Buffer 29 | Timeout = time.Duration(timeOut) * time.Millisecond 30 | ) 31 | ctxt, cancel := context.WithTimeout(context.Background(), Timeout) 32 | defer cancel() 33 | 34 | cmd := exec.CommandContext(ctxt, name, "-c", command) 35 | cmd.Stdout = &stdout 36 | cmd.Stderr = &stderr 37 | 38 | if err := cmd.Start(); err != nil { 39 | return "", err 40 | } 41 | 42 | if err := cmd.Wait(); err != nil { 43 | return "", errors.Errorf("cmd:{%s} %s,%s", command, err.Error(), stderr.String()) 44 | } 45 | 46 | return stdout.String(), nil 47 | } 48 | -------------------------------------------------------------------------------- /dockin-opsctl/internal/utils/file_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package utils 16 | 17 | import ( 18 | "bufio" 19 | "fmt" 20 | "github.com/stretchr/testify/assert" 21 | "os" 22 | "path/filepath" 23 | "testing" 24 | ) 25 | 26 | func Test_unTar(t *testing.T) { 27 | file := "C:\\MyWork\\securecrt\\rpd_tools.tar" 28 | fw,_ := os.Open(file) 29 | UntarFile(fw,"C:\\MyWork\\securecrt") 30 | } 31 | 32 | func Test_tarFile(t *testing.T) { 33 | if err := tarFile("C:\\MyWork\\MYpython\\app", "C:\\MyWork\\MYpython\\app.tar");err != nil{ 34 | fmt.Println(err.Error()) 35 | } 36 | } 37 | 38 | func Test_tarFileV(t *testing.T) { 39 | t.Run("tar", func(t *testing.T) { 40 | src := filepath.Join("C:\\", "download", "tmp", "hzf") 41 | f, err := os.Create(filepath.Join("C:\\", "download", "tmp", "test.tar")) 42 | assert.NoError(t, err) 43 | bio := bufio.NewWriter(f) 44 | err = MakeTarV2(src, bio) 45 | defer bio.Flush() 46 | assert.NoError(t, err) 47 | }) 48 | } -------------------------------------------------------------------------------- /dockin-opsctl/internal/utils/response_print.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package utils 16 | 17 | import ( 18 | "fmt" 19 | "github.com/json-iterator/go" 20 | ) 21 | 22 | type PrintResponse struct { 23 | Code int 24 | Message string 25 | Data string 26 | } 27 | 28 | func NewPrintResponse() *PrintResponse { 29 | return &PrintResponse{} 30 | } 31 | 32 | func (p *PrintResponse) PrintMsg(code int, message string) { 33 | p.Code = code 34 | p.Message = message 35 | p.Data = "" 36 | 37 | jsonData, _ := jsoniter.MarshalToString(p) 38 | fmt.Println(jsonData) 39 | } 40 | -------------------------------------------------------------------------------- /dockin-opsctl/internal/version/version.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package version 16 | 17 | var( 18 | BuildDate = "1970-01-01T00:00:00Z" // build date in ISO8601 format, output of $(date -u +'%Y-%m-%dT%H:%M:%SZ') 19 | Version = "v2.1" 20 | CommitId = "" 21 | ) 22 | 23 | type VersionInfo struct { 24 | Version string 25 | BuildDate string 26 | ServerIp string 27 | CommitId string 28 | } 29 | -------------------------------------------------------------------------------- /dockin-opserver/Makefile: -------------------------------------------------------------------------------- 1 | BINARY="dockin-opserver" 2 | VERSION=0.1.0 3 | BUILD=`date +%FT%T%z` 4 | 5 | PACKAGES=`go list ./... | grep -v /vendor/` 6 | VETPACKAGES=`go list ./... | grep -v /vendor/ | grep -v /examples/` 7 | GOFILES=`find . -name "*.go" -type f -not -path "./vendor/*"` 8 | 9 | OS=linux 10 | ARCH=amd64 11 | 12 | default: 13 | go mod tidy 14 | go mod vendor 15 | mkdir -p build 16 | cd build && GOOS=${OS} GOARCH=${ARCH} go build -o ${BINARY} ../cmd 17 | 18 | 19 | list: 20 | @echo ${PACKAGES} 21 | @echo ${VETPACKAGES} 22 | @echo ${GOFILES} 23 | 24 | fmt: 25 | @gofmt -s -w ${GOFILES} 26 | 27 | fmt-check: 28 | @diff=?(gofmt -s -d $(GOFILES)); \ 29 | if [ -n "$$diff" ]; then \ 30 | echo "Please run 'make fmt' and commit the result:"; \ 31 | echo "$${diff}"; \ 32 | exit 1; \ 33 | fi; 34 | 35 | vet: 36 | @go vet $(VETPACKAGES) 37 | 38 | clean: 39 | @if [ -f ${BINARY} ] ; then rm ${BINARY} ; fi 40 | 41 | package: default 42 | mkdir -p release/${BINARY} 43 | mkdir -p release/${BINARY}/apps 44 | mkdir -p release/${BINARY}/bin 45 | cp build/${BINARY} release/${BINARY}/apps 46 | cp scripts/* release/${BINARY}/bin 47 | cp -r configs release/${BINARY}/ 48 | chmod +rx release/${BINARY}/* 49 | cd release && tar -czf "${BINARY}_${VERSION}.tar.gz" ./${BINARY} 50 | 51 | .PHONY: default package fmt fmt-check install vet clean 52 | -------------------------------------------------------------------------------- /dockin-opserver/configs/application.yaml: -------------------------------------------------------------------------------- 1 | rm-address: http://127.0.0.1:10002/rmController 2 | batch-timeout: 5000 3 | http-port: 8084 4 | cmd-filter-type: whitelist 5 | while-list-update-time: 60000 6 | limits: 7 | exec-forbidden: 8 | - vi 9 | file-max-size: 1000 10 | upload-file-max-size: 500 11 | download-file-max-size: 4000 12 | vi-file-max-size: 10 13 | k8s-qos: 40 14 | k8s-burst: 60 15 | opagent-port: 8085 16 | redis: 17 | expiration: 120000 18 | accounts: 19 | - account: 20 | user-name: app 21 | passwd: -------------------------------------------------------------------------------- /dockin-opserver/configs/banner.txt: -------------------------------------------------------------------------------- 1 | ██████╗ ██████╗ ██████╗██╗ ██╗██╗███╗ ██╗ ███████╗███████╗██╗ ██╗ ████████╗███████╗██████╗ ███╗ ███╗██╗███╗ ██╗ █████╗ ██╗ 2 | ██╔══██╗██╔═══██╗██╔════╝██║ ██╔╝██║████╗ ██║ ██╔════╝██╔════╝██║ ██║ ╚══██╔══╝██╔════╝██╔══██╗████╗ ████║██║████╗ ██║██╔══██╗██║ 3 | ██║ ██║██║ ██║██║ █████╔╝ ██║██╔██╗ ██║ ███████╗███████╗███████║ ██║ █████╗ ██████╔╝██╔████╔██║██║██╔██╗ ██║███████║██║ 4 | ██║ ██║██║ ██║██║ ██╔═██╗ ██║██║╚██╗██║ ╚════██║╚════██║██╔══██║ ██║ ██╔══╝ ██╔══██╗██║╚██╔╝██║██║██║╚██╗██║██╔══██║██║ 5 | ██████╔╝╚██████╔╝╚██████╗██║ ██╗██║██║ ╚████║ ███████║███████║██║ ██║ ██║ ███████╗██║ ██║██║ ╚═╝ ██║██║██║ ╚████║██║ ██║███████╗ 6 | ╚═════╝ ╚═════╝ ╚═════╝╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝ ╚══════╝╚══════╝╚═╝ ╚═╝ ╚═╝ ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝╚═╝ ╚═╝╚══════╝ -------------------------------------------------------------------------------- /dockin-opserver/configs/log.yaml: -------------------------------------------------------------------------------- 1 | appLogPath: "/data/logs/dockin-opserver/app.log" 2 | commandLogPath: "/data/logs/dockin-opserver/sshcommand.log" 3 | logLevel: info -------------------------------------------------------------------------------- /dockin-opserver/configs/redis_origin.yaml: -------------------------------------------------------------------------------- 1 | server: 127.0.0.1 2 | port: 6379 3 | password: "" 4 | db: 0 5 | -------------------------------------------------------------------------------- /dockin-opserver/configs/server.env: -------------------------------------------------------------------------------- 1 | # add program run arguments -------------------------------------------------------------------------------- /dockin-opserver/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/webankfintech/dockin-opserver 2 | 3 | go 1.12 4 | 5 | require ( 6 | github.com/evanphx/json-patch v4.5.0+incompatible 7 | github.com/fatih/camelcase v1.0.0 8 | github.com/ghodss/yaml v1.0.0 // indirect 9 | github.com/go-redis/redis/v7 v7.2.0 10 | github.com/gogo/protobuf v1.2.1 // indirect 11 | github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef // indirect 12 | github.com/google/btree v1.0.0 // indirect 13 | github.com/google/go-cmp v0.5.1 // indirect 14 | github.com/google/uuid v1.1.1 15 | github.com/gorilla/websocket v1.4.0 16 | github.com/json-iterator/go v1.1.7 17 | github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de 18 | github.com/mattn/go-runewidth v0.0.9 19 | github.com/mattn/go-tty v0.0.3 20 | github.com/panjf2000/ants/v2 v2.1.0 21 | github.com/pkg/errors v0.8.1 22 | github.com/pkg/term v1.1.0 23 | github.com/sirupsen/logrus v1.4.2 24 | github.com/spf13/cobra v0.0.5 25 | github.com/spf13/pflag v1.0.3 26 | github.com/stretchr/testify v1.4.0 27 | github.com/valyala/fasthttp v1.4.0 28 | github.com/wenzhenxi/gorsa v0.0.0-20191231021121-58a13482fb09 29 | go.uber.org/atomic v1.7.0 30 | go.uber.org/dig v1.7.0 // indirect 31 | go.uber.org/fx v1.9.0 32 | go.uber.org/goleak v0.10.0 // indirect 33 | go.uber.org/multierr v1.6.0 // indirect 34 | go.uber.org/zap v1.10.0 35 | golang.org/x/net v0.0.0-20201021035429-f5854403a974 // indirect 36 | golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f 37 | golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect 38 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect 39 | gopkg.in/yaml.v2 v2.3.0 40 | k8s.io/api v0.0.0-20190718062839-c8a0b81cb10e 41 | k8s.io/apimachinery v0.0.0-20190717022731-0bb8574e0887 42 | k8s.io/cli-runtime v0.0.0-20190711111425-61e036b70227 43 | k8s.io/client-go v12.0.0+incompatible 44 | k8s.io/klog v0.4.0 45 | k8s.io/kubectl v0.0.0-20190704051832-70c55756d672 46 | k8s.io/utils v0.0.0-20190607212802-c55fbcfc754a 47 | mvdan.cc/sh/v3 v3.0.2 48 | 49 | ) 50 | -------------------------------------------------------------------------------- /dockin-opserver/internal/api/ctrl/access.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package ctrl 16 | 17 | import ( 18 | "github.com/webankfintech/dockin-opserver/internal/cache/keys" 19 | "github.com/webankfintech/dockin-opserver/internal/cache/redis" 20 | "github.com/webankfintech/dockin-opserver/internal/log" 21 | ) 22 | 23 | type Access struct { 24 | redisClient *redis.RedisClient 25 | } 26 | 27 | func (a *Access) LoadFromCache() map[string][]string { 28 | mem := make(map[string][]string) 29 | ruleList, err := a.redisClient.SMembers(keys.GetRuleRedisKey()) 30 | if err != nil { 31 | log.Logger.Warnf(err.Error()) 32 | return mem 33 | } 34 | 35 | for _, rule := range ruleList { 36 | ruleKey := keys.GetRedisWhiteKeyByRule(rule) 37 | tmp, err := a.redisClient.SMembers(ruleKey) 38 | if err != nil { 39 | log.Logger.Warnf(err.Error()) 40 | continue 41 | } 42 | mem[rule] = tmp 43 | } 44 | return mem 45 | } 46 | 47 | func (a *Access) AddAccess(rule string, ips []string) error { 48 | if err := a.redisClient.SAdd(keys.GetRuleRedisKey(), []string{rule}); err != nil { 49 | log.Logger.Warnf("add access err=%s", err.Error()) 50 | return err 51 | } 52 | 53 | ruleIpKey := keys.GetRedisWhiteKeyByRule(rule) 54 | if err := a.redisClient.SAdd(ruleIpKey, ips); err != nil { 55 | log.Logger.Warnf("failed to add ips=%v, rule=%s", ips, rule) 56 | return err 57 | } 58 | 59 | return nil 60 | } 61 | 62 | func (a *Access) RemoveAccess(rule string, ips []string) error { 63 | ruleIpKey := keys.GetRedisWhiteKeyByRule(rule) 64 | if err := a.redisClient.SRem(ruleIpKey, ips); err != nil { 65 | log.Logger.Warnf("failed to remove ips=%v, rule=%s", ips, rule) 66 | return err 67 | } 68 | 69 | return nil 70 | } 71 | -------------------------------------------------------------------------------- /dockin-opserver/internal/api/ctrl/access_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package ctrl 16 | 17 | import ( 18 | "fmt" 19 | "testing" 20 | 21 | "github.com/webankfintech/dockin-opserver/internal/cache/redis" 22 | "github.com/webankfintech/dockin-opserver/internal/log" 23 | ) 24 | 25 | func TestRulelist(t *testing.T) { 26 | rc, err := redis.NewRedisClient() 27 | if err != nil { 28 | log.Logger.Panicf("failed to init redis") 29 | } 30 | access := &Access{redisClient: rc} 31 | ruleList := access.LoadFromCache() 32 | fmt.Println(ruleList) 33 | } 34 | -------------------------------------------------------------------------------- /dockin-opserver/internal/api/ctrl/account_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package ctrl 16 | 17 | import ( 18 | "fmt" 19 | "testing" 20 | ) 21 | 22 | func TestSha(t *testing.T) { 23 | user := "" 24 | passwd := "" 25 | fmt.Println(sha256_v1(user, passwd)) 26 | } 27 | -------------------------------------------------------------------------------- /dockin-opserver/internal/api/ctrl/allow.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package ctrl 16 | 17 | import ( 18 | "github.com/webankfintech/dockin-opserver/internal/cache/keys" 19 | "github.com/webankfintech/dockin-opserver/internal/cache/redis" 20 | "github.com/webankfintech/dockin-opserver/internal/log" 21 | ) 22 | 23 | type AllowCmd struct { 24 | redisClient *redis.RedisClient 25 | } 26 | 27 | func NewAllowCmd() *AllowCmd { 28 | return &AllowCmd{} 29 | } 30 | 31 | func (b *AllowCmd) LoadFromCache() (raw, common []string) { 32 | raw, err := b.redisClient.SMembers(keys.GetRawCmdRedisKey()) 33 | if err != nil { 34 | log.Logger.Warnf(err.Error()) 35 | } 36 | 37 | common, err = b.redisClient.SMembers(keys.GetCommonCmdRedisKey()) 38 | if err != nil { 39 | log.Logger.Warnf(err.Error()) 40 | } 41 | return raw, common 42 | } 43 | 44 | func (b *AllowCmd) AddRaw(rawCmd []string) error { 45 | if err := b.redisClient.SAdd(keys.GetRawCmdRedisKey(), rawCmd); err != nil { 46 | log.Logger.Warnf(err.Error()) 47 | return err 48 | } 49 | 50 | return nil 51 | } 52 | 53 | func (b *AllowCmd) RemoveRaw(rawCmd []string) error { 54 | if err := b.redisClient.SRem(keys.GetRawCmdRedisKey(), rawCmd); err != nil { 55 | log.Logger.Warnf(err.Error()) 56 | return err 57 | } 58 | 59 | return nil 60 | } 61 | 62 | func (b *AllowCmd) AddCommon(cmd []string) error { 63 | if err := b.redisClient.SAdd(keys.GetCommonCmdRedisKey(), cmd); err != nil { 64 | log.Logger.Warnf(err.Error()) 65 | return err 66 | } 67 | 68 | return nil 69 | } 70 | 71 | func (b *AllowCmd) RemoveCommon(cmd []string) error { 72 | if err := b.redisClient.SRem(keys.GetCommonCmdRedisKey(), cmd); err != nil { 73 | log.Logger.Warnf(err.Error()) 74 | return err 75 | } 76 | 77 | return nil 78 | } 79 | -------------------------------------------------------------------------------- /dockin-opserver/internal/api/ctrl/version.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package ctrl 16 | 17 | import ( 18 | "github.com/webankfintech/dockin-opserver/internal/cache/keys" 19 | "github.com/webankfintech/dockin-opserver/internal/cache/redis" 20 | "github.com/webankfintech/dockin-opserver/internal/log" 21 | ) 22 | 23 | type Version struct { 24 | redisClient *redis.RedisClient 25 | } 26 | 27 | func (v *Version) LoadVersionFromCache() string { 28 | version, err := v.redisClient.Get(keys.GetVersionKey()) 29 | if err != nil { 30 | log.Logger.Warnf("redis get version from key:%s failed,err=%s", keys.GetVersionKey(), err.Error()) 31 | return "" 32 | } 33 | 34 | return version.(string) 35 | } 36 | 37 | func (v *Version) UpdateVersion(version interface{}) error { 38 | return v.redisClient.Set(keys.GetVersionKey(), version, 0) 39 | } 40 | -------------------------------------------------------------------------------- /dockin-opserver/internal/api/echo/echo_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package echo 16 | 17 | import ( 18 | "testing" 19 | 20 | "github.com/webankfintech/dockin-opserver/internal/cache/redis" 21 | "github.com/webankfintech/dockin-opserver/internal/client" 22 | "github.com/webankfintech/dockin-opserver/internal/log" 23 | "github.com/webankfintech/dockin-opserver/internal/model" 24 | "github.com/webankfintech/dockin-opserver/internal/utils/trace" 25 | 26 | "github.com/stretchr/testify/assert" 27 | ) 28 | 29 | var ( 30 | RClient *redis.RedisClient 31 | err error 32 | ) 33 | 34 | func init() { 35 | RClient, err = redis.NewRedisClient() 36 | if err != nil { 37 | log.Logger.Panicf("failed to init redis") 38 | } 39 | } 40 | 41 | func TestGetPods(t *testing.T) { 42 | m := client.NewManager(RClient) 43 | m.Initialize() 44 | echo := &Echo{Cm: m} 45 | 46 | t.Run("func get pod without pod", func(t *testing.T) { 47 | res := echo.batchGetResource("127.0.0.1", &model.OpsOption{ 48 | Resource: "pods", 49 | Rule: "tctp", 50 | PrintType: "wide", 51 | }) 52 | 53 | assert.Equal(t, 0, res.Code) 54 | t.Log(res.ToString()) 55 | }) 56 | 57 | t.Run("func get pod with pod", func(t *testing.T) { 58 | res := echo.getResource("127.0.0.1", &model.OpsOption{ 59 | Resource: "pods", 60 | Name: "bcces-cls-20190828-160144420-0", 61 | Rule: "tctp", 62 | PrintType: "wide", 63 | }, trace.TraceID()) 64 | 65 | assert.Equal(t, 0, res.Code) 66 | t.Log(res.ToString()) 67 | }) 68 | 69 | t.Run("func get pod with pod, with namespace", func(t *testing.T) { 70 | res := echo.getResource("127.0.0.1", &model.OpsOption{ 71 | Resource: "pods", 72 | Name: "bcces-cls-20190828-160144420-0", 73 | Rule: "tctp", 74 | PrintType: "wide", 75 | Namespace: "xxx", 76 | }, trace.TraceID()) 77 | 78 | assert.Equal(t, -1, res.Code) 79 | t.Log(res.ToString()) 80 | }) 81 | 82 | } 83 | -------------------------------------------------------------------------------- /dockin-opserver/internal/api/echo/get.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package echo 16 | 17 | import ( 18 | "fmt" 19 | 20 | "github.com/webankfintech/dockin-opserver/internal/cache/redis" 21 | "github.com/webankfintech/dockin-opserver/internal/client" 22 | "github.com/webankfintech/dockin-opserver/internal/log" 23 | "github.com/webankfintech/dockin-opserver/internal/model" 24 | "github.com/pkg/errors" 25 | metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1" 26 | ) 27 | 28 | var ( 29 | group = metav1beta1.GroupName 30 | version = metav1beta1.SchemeGroupVersion.Version 31 | tabHeader = fmt.Sprintf("application/json;as=Table;v=%s;g=%s, application/json", version, group) 32 | yamlHeader = fmt.Sprintf("application/json;as=Yaml;v=%s;g=%s, application/json", version, group) 33 | ) 34 | 35 | type GetOps struct { 36 | ProxyClient *client.ProxyClient 37 | RedisClient *redis.RedisClient 38 | } 39 | 40 | func (g *GetOps) GetResource(echo *model.OpsOption,traceId string) (*model.OpsResult, error) { 41 | log.Logger.Infof("get k8s resource %#v,traceId=%s", echo,traceId) 42 | var opsResult *model.OpsResult 43 | result, err := g.GetK8sResource(echo,traceId) 44 | if err != nil { 45 | log.Logger.Warnf("get k8s resource err, %#v, err %s,traceId=%s", echo, err.Error(),traceId) 46 | return nil, err 47 | } 48 | 49 | opsResult = model.SuccessOpsResult(result) 50 | return opsResult, nil 51 | } 52 | 53 | func (g *GetOps) GetK8sResource(echo *model.OpsOption,traceId string) (result string, err error) { 54 | switch echo.Resource { 55 | case "node", "nodes", "no": 56 | nodeGetter := NewNodeGetter(echo, g.ProxyClient, g.RedisClient, echo.PrintType) 57 | return nodeGetter.GetNode(traceId) 58 | case "pods", "pod", "po": 59 | podGetter := NewPodGetter(echo, g.ProxyClient, g.RedisClient, echo.PrintType) 60 | return podGetter.GetPod(traceId) 61 | default: 62 | err = errors.Errorf("un support resource %s", echo.Resource) 63 | } 64 | return 65 | } -------------------------------------------------------------------------------- /dockin-opserver/internal/api/rm/rm_ops_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package rm 16 | 17 | import ( 18 | "go/parser" 19 | "testing" 20 | 21 | "github.com/webankfintech/dockin-opserver/internal/dockin" 22 | "github.com/stretchr/testify/assert" 23 | ) 24 | 25 | func Test_GetPodInfo(t *testing.T) { 26 | traceId := parser.Trace 27 | t.Run("get pod info by host", func(t *testing.T) { 28 | data, err := dockin.GetPodInfoByPodIp("192.168.1.1") 29 | assert.NoError(t, err) 30 | t.Log(data) 31 | }) 32 | 33 | t.Run("get pod info by subsystem", func(t *testing.T) { 34 | data, err := dockin.GetPodInfoBySubsystem("dockin-QQ", "", traceId) 35 | assert.NoError(t, err) 36 | t.Log(data) 37 | }) 38 | 39 | t.Run("get pod info by subsystem and dcn", func(t *testing.T) { 40 | data, err := dockin.GetPodInfoBySubsystem("dockin-QQ", "ND1", traceId) 41 | assert.NoError(t, err) 42 | t.Log(data) 43 | }) 44 | } 45 | -------------------------------------------------------------------------------- /dockin-opserver/internal/api/terminal/message.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package terminal 16 | 17 | import ( 18 | "github.com/webankfintech/dockin-opserver/internal/common" 19 | "github.com/webankfintech/dockin-opserver/internal/log" 20 | "github.com/webankfintech/dockin-opserver/internal/utils/aes" 21 | 22 | jsoniter "github.com/json-iterator/go" 23 | "github.com/pkg/errors" 24 | ) 25 | 26 | const ( 27 | LoginType = 1 28 | ResizeType = 2 29 | StartCommandType = 3 30 | EndCommandType = 4 31 | RawInputType = 5 32 | ) 33 | 34 | type Message struct { 35 | MessageType int `json:"messageType"` 36 | Data interface{} `json:"data"` 37 | } 38 | 39 | type LoginMessage struct { 40 | UserName string `json:"userName"` 41 | Password string `json:"password"` 42 | Rule string `json:"rule"` 43 | AccessToken string `json:"accessToken"` 44 | PodName string `json:"podName"` 45 | } 46 | 47 | type ResizeMessage struct { 48 | Width int `json:"width"` 49 | Height int `json:"height"` 50 | } 51 | 52 | type CommandMessage struct { 53 | } 54 | 55 | func ParseAESMessage(content []byte) (*Message, error) { 56 | aes, err := aes.NewAes(common.ResKey) 57 | decoded, err := aes.AesDecrypt(string(content)) 58 | if err != nil { 59 | err = errors.Errorf("decrypt err=%s", err.Error()) 60 | log.Logger.Warnf(err.Error()) 61 | return nil, err 62 | } 63 | msg := &Message{} 64 | err = jsoniter.Unmarshal([]byte(decoded), msg) 65 | if err != nil { 66 | log.Logger.Warnf("unmarshal read data error, check the input data, err=%s", err.Error()) 67 | return nil, err 68 | } 69 | 70 | return msg, nil 71 | } 72 | 73 | func ParseMessage(content []byte) (*Message, error) { 74 | msg := &Message{} 75 | err := jsoniter.Unmarshal(content, msg) 76 | if err != nil { 77 | log.Logger.Warnf("unmarshal read data error, check the input data, err=%s", err.Error()) 78 | return nil, err 79 | } 80 | 81 | return msg, nil 82 | } 83 | -------------------------------------------------------------------------------- /dockin-opserver/internal/client/client.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package client 16 | 17 | import ( 18 | "fmt" 19 | 20 | "github.com/webankfintech/dockin-opserver/internal/log" 21 | 22 | "k8s.io/client-go/kubernetes" 23 | restclient "k8s.io/client-go/rest" 24 | ) 25 | 26 | var ( 27 | ErrLoadKubeConfig = fmt.Errorf("load kube config from KUBECONFIG failed, check env") 28 | ErrCreateClientSet = fmt.Errorf("create kubenetes client set failed") 29 | ErrPropsNotSet = fmt.Errorf("check application yaml master url and kube config path") 30 | 31 | MasterUrlProps = "app.kube.masterurl" 32 | KubeConfigFileProps = "app.kube.KubeConfigFile" 33 | ) 34 | 35 | type ProxyClient struct { 36 | ApiClient *kubernetes.Clientset 37 | RestConfig *restclient.Config 38 | K8sConfig *K8sConfig 39 | } 40 | 41 | func NewProxyClient(rcfg *restclient.Config, k8s *K8sConfig) *ProxyClient { 42 | clientset, err := kubernetes.NewForConfig(rcfg) 43 | if err != nil { 44 | log.Logger.Panic(ErrCreateClientSet.Error()) 45 | } 46 | 47 | return &ProxyClient{ 48 | ApiClient: clientset, 49 | RestConfig:rcfg, 50 | K8sConfig:k8s, 51 | } 52 | } -------------------------------------------------------------------------------- /dockin-opserver/internal/client/k8sconfig.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package client 16 | 17 | import jsoniter "github.com/json-iterator/go" 18 | 19 | type K8sConfig struct { 20 | APIVersion string `yaml:"apiVersion"` 21 | Clusters []struct { 22 | Cluster struct { 23 | InsecureSkipTLSVerify bool `yaml:"insecure-skip-tls-verify"` 24 | Server string `yaml:"server"` 25 | } `yaml:"cluster"` 26 | Name string `yaml:"name"` 27 | } `yaml:"clusters"` 28 | Contexts []struct { 29 | Context struct { 30 | Cluster string `yaml:"cluster"` 31 | Namespace string `yaml:"namespace"` 32 | User string `yaml:"user"` 33 | } `yaml:"context"` 34 | Name string `yaml:"name"` 35 | } `yaml:"contexts"` 36 | CurrentContext string `yaml:"current-context"` 37 | Kind string `yaml:"kind"` 38 | Preferences struct { 39 | } `yaml:"preferences"` 40 | Users []struct { 41 | Name string `yaml:"name"` 42 | User struct { 43 | Password string `yaml:"password"` 44 | Username string `yaml:"username"` 45 | } `yaml:"user"` 46 | } `yaml:"users"` 47 | Dockin struct { 48 | ClusterID string `yaml:"cluster-id"` 49 | Rule string `yaml:"rule"` 50 | } `yaml:"dockin"` 51 | } 52 | 53 | func (k *K8sConfig) ToString() string { 54 | str, _ := jsoniter.MarshalToString(k) 55 | return str 56 | } 57 | -------------------------------------------------------------------------------- /dockin-opserver/internal/common/app_home.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package common 16 | 17 | import ( 18 | "fmt" 19 | "os" 20 | "path/filepath" 21 | "runtime" 22 | "strings" 23 | ) 24 | 25 | const KubeConfigEnvName = "KUBECONFIG" 26 | const AppHome = "APP_HOME" 27 | const EmptyString = "" 28 | 29 | var appHome string 30 | 31 | const AppHomeEnv = "APP_HOME" 32 | 33 | func init() { 34 | appHome = os.Getenv(AppHomeEnv) 35 | if appHome == EmptyString { 36 | curDir := CurrentDir() 37 | index := strings.LastIndex(curDir, "dockin-opserver") 38 | if index == -1 { 39 | panic(fmt.Errorf("try to look src in current path, but failed")) 40 | } 41 | appHome = filepath.Join(curDir[0:index], "dockin-opserver") 42 | } 43 | } 44 | 45 | func GetAppHome() string { 46 | return appHome 47 | } 48 | 49 | func GetConfPath() string { 50 | return filepath.Join(appHome, "configs") 51 | } 52 | 53 | func CurrentDir() string { 54 | _, dir, _, ok := runtime.Caller(1) 55 | if !ok { 56 | panic(fmt.Errorf("can not get current dir")) 57 | } 58 | return dir 59 | } 60 | -------------------------------------------------------------------------------- /dockin-opserver/internal/common/bench/bench_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package main 16 | 17 | import ( 18 | "encoding/json" 19 | "testing" 20 | 21 | "github.com/stretchr/testify/assert" 22 | ) 23 | 24 | func TestLoadConf(t *testing.T) { 25 | content := []byte(`{ 26 | "concurrent": 3, 27 | "number": 300, 28 | "timeout": 300, 29 | "poolSize":3, 30 | "podList": [ 31 | "1", 32 | "2", 33 | "3" 34 | ] 35 | }`) 36 | pa := ¶m{} 37 | err := json.Unmarshal(content, pa) 38 | t.Log(pa.String()) 39 | assert.NoError(t, err) 40 | assert.Equal(t, pa.Concurrent, 3) 41 | assert.Equal(t, pa.Timeout, int64(300)) 42 | } 43 | -------------------------------------------------------------------------------- /dockin-opserver/internal/common/bench/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "concurrent": 3, 3 | "number": 300, 4 | "podList": [ 5 | "1", 6 | "2", 7 | "3" 8 | ] 9 | } -------------------------------------------------------------------------------- /dockin-opserver/internal/common/const.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package common 16 | 17 | const ResKey = "doc-opserver8085" 18 | const UserName = "admin" 19 | -------------------------------------------------------------------------------- /dockin-opserver/internal/common/env/env.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package env 16 | 17 | import ( 18 | "time" 19 | 20 | "github.com/webankfintech/dockin-opserver/internal/config" 21 | ) 22 | 23 | var env string 24 | var timeout time.Duration 25 | 26 | func init() { 27 | env = config.OpsConfig.ENV 28 | ti := config.OpsConfig.BatchTimeout 29 | timeout = time.Millisecond * time.Duration(ti) 30 | } 31 | 32 | 33 | 34 | 35 | func DefaultTimeout() time.Duration { 36 | return timeout 37 | } 38 | -------------------------------------------------------------------------------- /dockin-opserver/internal/common/interface.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package common 16 | 17 | import ( 18 | "fmt" 19 | "k8s.io/apimachinery/pkg/api/meta" 20 | "k8s.io/cli-runtime/pkg/genericclioptions" 21 | ) 22 | 23 | const ( 24 | LoadBalancerWidth = 16 25 | 26 | LabelNodeRolePrefix = "node-role.kubernetes.io/" 27 | 28 | NodeLabelRole = "kubernetes.io/role" 29 | ) 30 | 31 | type DescriberFunc func(restClientGetter genericclioptions.RESTClientGetter, mapping *meta.RESTMapping) (Describer, error) 32 | 33 | type Describer interface { 34 | Describe(namespace, name string, describerSettings DescriberSettings) (output string, err error) 35 | } 36 | 37 | type DescriberSettings struct { 38 | ShowEvents bool 39 | } 40 | 41 | type ObjectDescriber interface { 42 | DescribeObject(object interface{}, extra ...interface{}) (output string, err error) 43 | } 44 | 45 | type ErrNoDescriber struct { 46 | Types []string 47 | } 48 | 49 | func (e ErrNoDescriber) Error() string { 50 | return fmt.Sprintf("no describer has been defined for %v", e.Types) 51 | } 52 | -------------------------------------------------------------------------------- /dockin-opserver/internal/common/option/desc_option.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package option 16 | 17 | import ( 18 | "fmt" 19 | 20 | "github.com/webankfintech/dockin-opserver/internal/common" 21 | utils2 "github.com/webankfintech/dockin-opserver/internal/common/option/utils" 22 | 23 | jsoniter "github.com/json-iterator/go" 24 | "github.com/spf13/cobra" 25 | "k8s.io/cli-runtime/pkg/genericclioptions" 26 | ) 27 | 28 | type DescOption struct { 29 | Name string 30 | Type string 31 | Selector string 32 | Namespace string 33 | AllNamespaces bool 34 | DescriberSettings *common.DescriberSettings 35 | } 36 | 37 | func (o *DescOption) Complete(flags *genericclioptions.ConfigFlags, command *cobra.Command, args []string) error { 38 | if len(args) == 0 { 39 | return fmt.Errorf("no resource type or name provided") 40 | } else if len(args) == 1 { 41 | o.Type = args[0] 42 | } else { 43 | o.Type = args[0] 44 | o.Name = args[1] 45 | } 46 | o.Namespace = *flags.Namespace 47 | //if o.Namespace == "" { 48 | // return fmt.Errorf("no namespace provided") 49 | //} 50 | return nil 51 | } 52 | 53 | func (option *DescOption) getUrl() string { 54 | return fmt.Sprintf("http://%s?command=%s", utils2.CommonUrl, "describe") 55 | } 56 | 57 | func (option *DescOption) Run() error { 58 | body, err := jsoniter.MarshalToString(option) 59 | if err != nil { 60 | fmt.Printf("json encode failed %v", err) 61 | } 62 | resp, err := utils2.HttpPost(option.getUrl(), body) 63 | if err != nil { 64 | return err 65 | } 66 | fmt.Println(string(resp)) 67 | return nil 68 | } 69 | -------------------------------------------------------------------------------- /dockin-opserver/internal/common/option/explain_option.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package option 16 | 17 | import ( 18 | "github.com/spf13/cobra" 19 | "k8s.io/cli-runtime/pkg/genericclioptions" 20 | ) 21 | 22 | type ExplainOption struct { 23 | APIVersion string 24 | Recursive bool 25 | } 26 | 27 | func (option *ExplainOption) Complete(flags *genericclioptions.ConfigFlags, command *cobra.Command) error { 28 | return nil 29 | } 30 | 31 | func (option *ExplainOption) Validate(strings []string) error { 32 | return nil 33 | } 34 | 35 | func (option *ExplainOption) Run(strings []string) error { 36 | return nil 37 | } 38 | 39 | func NewExplainOption() *ExplainOption { 40 | return &ExplainOption{} 41 | } 42 | -------------------------------------------------------------------------------- /dockin-opserver/internal/common/option/utils/http.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package utils 16 | 17 | import ( 18 | "fmt" 19 | "net/http" 20 | 21 | "github.com/webankfintech/dockin-opserver/internal/log" 22 | 23 | "github.com/valyala/fasthttp" 24 | ) 25 | 26 | func HttpPost(url, payload string) ([]byte, error) { 27 | req := &fasthttp.Request{} 28 | req.SetRequestURI(url) 29 | req.SetBody([]byte(payload)) 30 | 31 | req.Header.SetContentType("application/json") 32 | req.Header.SetMethod("POST") 33 | 34 | resp := &fasthttp.Response{} 35 | client := &fasthttp.Client{} 36 | if err := client.Do(req, resp); err != nil { 37 | fmt.Println("send post failed", err.Error()) 38 | return nil, err 39 | } 40 | 41 | return resp.Body(), nil 42 | } 43 | 44 | func HttpGetFile(url string) (*http.Response, error) { 45 | log.Logger.Infof("client2server url:%s", url) 46 | res, err := http.Get(url) 47 | if err != nil { 48 | return nil, err 49 | } 50 | 51 | return res, nil 52 | } 53 | -------------------------------------------------------------------------------- /dockin-opserver/internal/common/option/utils/url.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package utils 16 | 17 | import ( 18 | "fmt" 19 | ) 20 | 21 | const DockinOpServerHost = "localhost:8083" 22 | 23 | var ( 24 | CommonUrl = fmt.Sprintf("%s/common", DockinOpServerHost) 25 | ) 26 | -------------------------------------------------------------------------------- /dockin-opserver/internal/common/printer/get_print.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package printer 16 | 17 | import ( 18 | "bytes" 19 | "fmt" 20 | "text/tabwriter" 21 | 22 | utils2 "github.com/webankfintech/dockin-opserver/internal/common/option/utils" 23 | 24 | jsoniter "github.com/json-iterator/go" 25 | metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1" 26 | ) 27 | 28 | func PrintTable(table *metav1beta1.Table) string { 29 | buf := &bytes.Buffer{} 30 | tw := tabwriter.NewWriter(buf, 5, 8, 1, ' ', 0) 31 | printer := NewTablePrinter(PrintOptions{Wide:true}) 32 | err := printer.PrintObj(table, tw) 33 | utils2.CheckErr(err) 34 | tw.Flush() 35 | return buf.String() 36 | } 37 | 38 | 39 | func PrettyPrint(bytes []byte) { 40 | table := &metav1beta1.Table{} 41 | if err := jsoniter.Unmarshal(bytes, table); err != nil { 42 | fmt.Printf("unmarshal result failed, %v\n", err) 43 | } 44 | fmt.Print(PrintTable(table)) 45 | } 46 | -------------------------------------------------------------------------------- /dockin-opserver/internal/common/printer/interface.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package printer 16 | 17 | import ( 18 | "io" 19 | 20 | "k8s.io/apimachinery/pkg/runtime" 21 | "k8s.io/apimachinery/pkg/runtime/schema" 22 | ) 23 | 24 | type ResourcePrinter interface { 25 | PrintObj(runtime.Object, io.Writer) error 26 | } 27 | 28 | type ResourcePrinterFunc func(runtime.Object, io.Writer) error 29 | 30 | func (fn ResourcePrinterFunc) PrintObj(obj runtime.Object, w io.Writer) error { 31 | return fn(obj, w) 32 | } 33 | 34 | type PrintOptions struct { 35 | NoHeaders bool 36 | WithNamespace bool 37 | WithKind bool 38 | Wide bool 39 | ShowLabels bool 40 | AbsoluteTimestamps bool 41 | Kind schema.GroupKind 42 | ColumnLabels []string 43 | 44 | SortBy string 45 | 46 | AllowMissingKeys bool 47 | } 48 | -------------------------------------------------------------------------------- /dockin-opserver/internal/common/printer/tabwriter.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package printer 16 | 17 | import ( 18 | "io" 19 | 20 | "github.com/liggitt/tabwriter" 21 | ) 22 | 23 | const ( 24 | tabwriterMinWidth = 6 25 | tabwriterWidth = 4 26 | tabwriterPadding = 3 27 | tabwriterPadChar = ' ' 28 | tabwriterFlags = tabwriter.RememberWidths 29 | ) 30 | 31 | func GetNewTabWriter(output io.Writer) *tabwriter.Writer { 32 | return tabwriter.NewWriter(output, tabwriterMinWidth, tabwriterWidth, tabwriterPadding, tabwriterPadChar, tabwriterFlags) 33 | } 34 | -------------------------------------------------------------------------------- /dockin-opserver/internal/common/scheme/scheme.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package scheme 16 | 17 | import ( 18 | "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" 19 | "k8s.io/apimachinery/pkg/runtime" 20 | "k8s.io/apimachinery/pkg/runtime/serializer" 21 | ) 22 | 23 | 24 | var Scheme = runtime.NewScheme() 25 | 26 | var Codecs = serializer.NewCodecFactory(Scheme) 27 | 28 | var ParameterCodec = runtime.NewParameterCodec(Scheme) 29 | 30 | func DefaultJSONEncoder() runtime.Encoder { 31 | return unstructured.JSONFallbackEncoder{Encoder: Codecs.LegacyCodec(Scheme.PrioritizedVersionsAllGroups()...)} 32 | } 33 | -------------------------------------------------------------------------------- /dockin-opserver/internal/common/ws/socketstream.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package ws 16 | 17 | import ( 18 | "encoding/json" 19 | 20 | "github.com/gorilla/websocket" 21 | "k8s.io/client-go/tools/remotecommand" 22 | ) 23 | 24 | type xtermMessage struct { 25 | MsgType string `json:"type"` Content string `json:"input"` Rows uint16 `json:"rows"` Cols uint16 `json:"cols"` } 26 | 27 | type SocketStream struct { 28 | WebsocketConnection *WebsocketConnection 29 | ResizeEvent chan remotecommand.TerminalSize 30 | } 31 | 32 | func (stream *SocketStream) Read(p []byte) (size int, err error) { 33 | var ( 34 | msg *WsMessage 35 | xtermMsg xtermMessage 36 | ) 37 | 38 | if msg, err = stream.WebsocketConnection.WsRead(); err != nil { 39 | return 40 | } 41 | 42 | if err = json.Unmarshal(msg.Data, &xtermMsg); err != nil { 43 | return 44 | } 45 | //web ssh调整了终端大小 46 | if xtermMsg.MsgType == "resize" { 47 | stream.ResizeEvent <- remotecommand.TerminalSize{ 48 | Width: xtermMsg.Cols, 49 | Height: xtermMsg.Rows, 50 | } 51 | } else if xtermMsg.MsgType == "input" { 52 | size = len(xtermMsg.Content) 53 | copy(p, xtermMsg.Content) 54 | } 55 | return 56 | } 57 | 58 | func (stream *SocketStream) Write(p []byte) (size int, err error) { 59 | var ( 60 | copyData []byte 61 | ) 62 | copyData = make([]byte, len(p)) 63 | copy(copyData, p) 64 | size = len(p) 65 | 66 | err = stream.WebsocketConnection.WsWrite(websocket.TextMessage, copyData) 67 | return 68 | } 69 | 70 | func (stream *SocketStream) Next() (size *remotecommand.TerminalSize) { 71 | ret := <-stream.ResizeEvent 72 | size = &ret 73 | 74 | return 75 | } 76 | -------------------------------------------------------------------------------- /dockin-opserver/internal/controller/response.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package controller 16 | 17 | import "github.com/json-iterator/go" 18 | 19 | var ( 20 | Success = 0 21 | RedisFail = -1 22 | ) 23 | 24 | type Response struct { 25 | Code int `json:"code"` 26 | Msg string `json:"msg"` 27 | TaskId string `json:"taskId"` 28 | Data interface{} `json:"data"` 29 | } 30 | 31 | func (r *Response)ToJSONBytes() []byte { 32 | json, _ := jsoniter.Marshal(r) 33 | return json 34 | } -------------------------------------------------------------------------------- /dockin-opserver/internal/informer/event.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package informer 16 | 17 | type EventInformer struct { 18 | 19 | } 20 | 21 | func (e *EventInformer)AddFunc(obj interface{}) { 22 | } 23 | func (e *EventInformer)UpdateFunc(oldObj, newObj interface{}) { 24 | } 25 | func (e *EventInformer)DeleteFunc(obj interface{}) { 26 | } -------------------------------------------------------------------------------- /dockin-opserver/internal/model/access_token.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package model 16 | 17 | import ( 18 | "fmt" 19 | "time" 20 | 21 | "github.com/webankfintech/dockin-opserver/internal/common" 22 | "github.com/webankfintech/dockin-opserver/internal/log" 23 | "github.com/webankfintech/dockin-opserver/internal/utils/aes" 24 | 25 | jsoniter "github.com/json-iterator/go" 26 | "github.com/pkg/errors" 27 | ) 28 | 29 | type UserIdentity struct { 30 | UserName string `json:"userName"` 31 | Password string `json:"password"` 32 | Rule string `json:"rule"` 33 | Expire int64 `json:"expire"` 34 | CreateTime time.Time `json:"createTime"` 35 | AccessToken string `json:"accessToken"` 36 | } 37 | 38 | var ( 39 | expireAt int64 = 3600 40 | ) 41 | 42 | func NewUserIdentity(userName, password, rule string) *UserIdentity { 43 | return &UserIdentity{ 44 | UserName: userName, 45 | Password: password, 46 | Rule: rule, 47 | Expire: expireAt, 48 | CreateTime: time.Now(), 49 | } 50 | } 51 | 52 | func (at *UserIdentity) ToString() (string, error) { 53 | aes, err := aes.NewAes(common.ResKey) 54 | if err != nil { 55 | err = errors.Errorf("create encrypt failed, err=%s", err.Error()) 56 | log.Logger.Warnf(err.Error()) 57 | return "", err 58 | } 59 | 60 | str, err := jsoniter.MarshalToString(at) 61 | if err != nil { 62 | log.Logger.Warnf("failed to unmarshal access token to string, %v, %v", at, err) 63 | return "", fmt.Errorf("failed to unmarshal access token to string") 64 | } 65 | return aes.AesEncrypt(str) 66 | } 67 | 68 | func OpagentAccessToken() string { 69 | expire := 3600 70 | ui := &UserIdentity{ 71 | UserName: "dockin-opagent", 72 | Expire: int64(expire), 73 | CreateTime: time.Now(), 74 | } 75 | token, _ := ui.ToString() 76 | return token 77 | } 78 | -------------------------------------------------------------------------------- /dockin-opserver/internal/model/access_token_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package model 16 | 17 | import ( 18 | "testing" 19 | "time" 20 | 21 | "github.com/webankfintech/dockin-opserver/internal/common" 22 | "github.com/webankfintech/dockin-opserver/internal/utils/aes" 23 | 24 | jsoniter "github.com/json-iterator/go" 25 | "github.com/stretchr/testify/assert" 26 | ) 27 | 28 | func TestNewAccessToken(t *testing.T) { 29 | ac := UserIdentity{ 30 | UserName: "bruceliu", 31 | Password: "123456", 32 | Expire: 3600, 33 | Rule: "default", 34 | CreateTime: time.Now(), 35 | } 36 | acs, err := ac.ToString() 37 | assert.NoError(t, err) 38 | t.Log(acs) 39 | t.Log(ac) 40 | 41 | aes, err := aes.NewAes(common.ResKey) 42 | assert.NoError(t, err) 43 | dout, err := aes.AesDecrypt(acs) 44 | assert.NoError(t, err) 45 | nac := &UserIdentity{} 46 | err = jsoniter.UnmarshalFromString(dout, nac) 47 | assert.NoError(t, err) 48 | assert.Equal(t, ac.UserName, nac.UserName) 49 | t.Logf("%v", nac) 50 | } 51 | -------------------------------------------------------------------------------- /dockin-opserver/internal/model/ctl.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package model 16 | 17 | type ControlDTO struct { 18 | WhiteList []WhiteList 19 | RawCommand []CMD 20 | Command []CMD 21 | Account []Account 22 | Version string 23 | } 24 | 25 | type Account struct { 26 | UserName string 27 | Password string 28 | } 29 | 30 | type WhiteList struct { 31 | Rule string 32 | IPList []IP 33 | } 34 | 35 | type IP struct { 36 | Addr string 37 | } 38 | 39 | type CMD struct { 40 | Cmd string 41 | } 42 | -------------------------------------------------------------------------------- /dockin-opserver/internal/model/param.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package model 16 | 17 | type DockinExecParam struct { 18 | UserName string `json:"userName"` 19 | Password string `json:"password"` 20 | AccessToken string `json:"accessToken"` 21 | Env []string `json:"env"` 22 | Width int `json:"width"` 23 | Height int `json:"height"` 24 | User string `json:"user"` 25 | WorkDir string `json:"workDir"` 26 | TTY bool `json:"tty"` 27 | } 28 | -------------------------------------------------------------------------------- /dockin-opserver/internal/model/result.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package model 16 | 17 | type ListResult struct { 18 | SubSysName string 19 | SubSysId string 20 | SubSysTag string 21 | Dcn string 22 | PodName string 23 | Namespace string 24 | ClusterId string 25 | HostIp string 26 | PodIp string 27 | Version string 28 | LimitMem string 29 | LimitCpu string 30 | State string 31 | } 32 | 33 | type AgentResult struct { 34 | Code int `json:"code"` 35 | Message string `json:"message"` 36 | Data interface{} `json:"data"` 37 | } 38 | -------------------------------------------------------------------------------- /dockin-opserver/internal/model/rm.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package model 16 | 17 | type RmResultDto struct { 18 | Code int `json:"code"` 19 | Data []*RmResultData `json:"data"` 20 | Message string `json:"message"` 21 | } 22 | 23 | type OneRmResultDto struct { 24 | Code int `json:"code"` 25 | Data *RmResultData `json:"data"` 26 | Message string `json:"message"` 27 | } 28 | 29 | type RmResultData struct { 30 | PodName string `json:"podName"` 31 | SubSystem string `json:"subSystem"` 32 | SubSystemId string `json:"subSystemId"` 33 | Dcn string `json:"dcn"` 34 | PodIP string `json:"podIp"` 35 | Gateway string `json:"gateway"` 36 | SubnetMask string `json:"subnetMask"` 37 | Namespace string `json:"namespace"` 38 | HostIP string `json:"hostIp"` 39 | CPU string `json:"cpu"` 40 | Mem string `json:"mem"` 41 | Type string `json:"type"` 42 | Port int `json:"port"` 43 | State string `json:"state"` 44 | ClusterID string `json:"clusterId"` 45 | Status string `json:"status"` 46 | } 47 | 48 | type RmClusterData struct { 49 | Code int `json:"code"` 50 | Data struct { 51 | ClusterID string `json:"clusterId"` 52 | } `json:"data"` 53 | } 54 | -------------------------------------------------------------------------------- /dockin-opserver/internal/remote/banner.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package remote 16 | 17 | import ( 18 | "io/ioutil" 19 | "path/filepath" 20 | 21 | "github.com/webankfintech/dockin-opserver/internal/common" 22 | ) 23 | 24 | var Banner string 25 | 26 | func init() { 27 | bannerPath := filepath.Join(common.GetConfPath(), "banner.txt") 28 | buf, err := ioutil.ReadFile(bannerPath) 29 | if err == nil { 30 | Banner = string(buf) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /dockin-opserver/internal/remote/consts.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package remote 16 | 17 | import "time" 18 | 19 | const ( 20 | writeWait = 10 * time.Second 21 | 22 | pongWait = 60 * time.Second 23 | 24 | pingPeriod = (pongWait * 9) / 10 25 | 26 | maxMessageSize = 1024 27 | ) 28 | 29 | const ( 30 | CharLineStart = 1 31 | CharBackward = 2 32 | CharInterrupt = 3 33 | CharDelete = 4 34 | CharLineEnd = 5 35 | CharForward = 6 36 | CharBell = 7 37 | CharCtrlH = 8 38 | CharTab = 9 39 | CharCtrlJ = 10 40 | CharKill = 11 41 | CharCtrlL = 12 42 | CharEnter = 13 43 | CharNext = 14 44 | CharPrev = 16 45 | CharBckSearch = 18 46 | CharFwdSearch = 19 47 | CharTranspose = 20 48 | CharCtrlU = 21 49 | CharCtrlW = 23 50 | CharCtrlY = 25 51 | CharCtrlZ = 26 52 | CharEsc = 27 53 | CharEscapeEx = 91 54 | CharBackspace = 127 55 | ) 56 | 57 | var ( 58 | PromptPrefix = []rune{27, 93, 48, 59} 59 | AppSuffix = "]$ " 60 | SuffixLen = 3 61 | RootSuffix = "]# " 62 | ) 63 | 64 | type InputMode int 65 | 66 | const ( 67 | CollectMode InputMode = 0 68 | InteractMode InputMode = 1 69 | ) 70 | 71 | const ( 72 | BlacklistMode string = "blacklist" 73 | WhitelistMode string = "whitelist" 74 | ) 75 | 76 | type MachineType int 77 | 78 | const ( 79 | VirtualMachine MachineType = 0 80 | DockerMachine MachineType = 1 81 | ) 82 | 83 | type ExecMode int 84 | 85 | const ( 86 | InteractExecMode ExecMode = 0 87 | SSHExecMode ExecMode = 1 88 | CommonExecMode ExecMode = 2 89 | ) 90 | -------------------------------------------------------------------------------- /dockin-opserver/internal/remote/context_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package remote 16 | 17 | import ( 18 | "github.com/stretchr/testify/assert" 19 | "testing" 20 | ) 21 | 22 | func Test_ParserShellPrompt(t *testing.T) { 23 | t.Run("test app", func(t *testing.T) { 24 | ps, err := ParserShellPrompt("[app@sls-service-20201020-112040385-0 ~]$ ") 25 | assert.NoError(t, err) 26 | assert.Equal(t, ps.user, "app") 27 | assert.Equal(t, ps.instance, "sls-service-20201020-112040385-0") 28 | assert.Equal(t, ps.dir, "~") 29 | }) 30 | 31 | t.Run("test root", func(t *testing.T) { 32 | ps, err := ParserShellPrompt("[root@sls-service-20201020-112040385-0 app]# ") 33 | assert.NoError(t, err) 34 | assert.Equal(t, ps.user, "root") 35 | assert.Equal(t, ps.instance, "sls-service-20201020-112040385-0") 36 | assert.Equal(t, ps.dir, "app") 37 | }) 38 | 39 | t.Run("test for root path", func(t *testing.T) { 40 | ps, err := ParserShellPrompt("[app@dockin-wx-20191012-180011777-0 /]$ ") 41 | assert.NoError(t, err) 42 | assert.Equal(t, ps.user, "app") 43 | assert.Equal(t, ps.instance, "dockin-wx-20191012-180011777-0") 44 | assert.Equal(t, ps.dir, "/") 45 | }) 46 | 47 | t.Run("test appsystem", func(t *testing.T) { 48 | ps, err := ParserShellPrompt("[app@dockin-wx-20191012-180011777-0 appsystems]$ ") 49 | assert.NoError(t, err) 50 | assert.Equal(t, ps.user, "app") 51 | assert.Equal(t, ps.instance, "dockin-wx-20191012-180011777-0") 52 | assert.Equal(t, ps.dir, "appsystems") 53 | }) 54 | 55 | t.Run("test appsystem extra output", func(t *testing.T) { 56 | ps, err := ParserShellPrompt("[app@dockin-wx-20191012-180011777-0 appsystems]$ xxxxx") 57 | assert.NoError(t, err) 58 | assert.Equal(t, ps.user, "app") 59 | assert.Equal(t, ps.instance, "dockin-wx-20191012-180011777-0") 60 | assert.Equal(t, ps.dir, "appsystems") 61 | }) 62 | } 63 | -------------------------------------------------------------------------------- /dockin-opserver/internal/remote/executor.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package remote 16 | 17 | import "context" 18 | 19 | type Executor interface { 20 | Exec(execParam *DockinExecParam, streams *IOStreams) error 21 | 22 | ExecInteractive(execParam *DockinExecParam, cmdStream *InteractStream) error 23 | 24 | Resize(width, height int) error 25 | 26 | Shell(ctx context.Context, execParam *DockinExecParam, interStream *InteractStream) error 27 | 28 | DebugShell(ctx context.Context, execParam *DockinExecParam, interStream *InteractStream) error 29 | } 30 | -------------------------------------------------------------------------------- /dockin-opserver/internal/remote/filter_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package remote 16 | 17 | import ( 18 | "testing" 19 | 20 | "github.com/stretchr/testify/assert" 21 | ) 22 | 23 | func Test_Whitelist(t *testing.T) { 24 | wlf := NewWhitelistFilter(func() []string { 25 | return []string{"ls", "pwd"} 26 | }) 27 | 28 | t.Run("in the list", func(t *testing.T) { 29 | cu, err := ParseCmdlineToCmdUnitList("ls -al") 30 | assert.NoError(t, err) 31 | err = wlf.Do(cu) 32 | assert.NoError(t, err) 33 | }) 34 | 35 | t.Run("not in the list", func(t *testing.T) { 36 | cu, err := ParseCmdlineToCmdUnitList("top -p 1") 37 | assert.NoError(t, err) 38 | err = wlf.Do(cu) 39 | assert.Error(t, err) 40 | }) 41 | } 42 | 43 | func Test_Blacklist(t *testing.T) { 44 | blf := NewBlacklistFilter(func() []string { 45 | return []string{"ls", "pwd"} 46 | }) 47 | 48 | t.Run("in the list", func(t *testing.T) { 49 | cu, err := ParseCmdlineToCmdUnitList("ls -al") 50 | assert.NoError(t, err) 51 | err = blf.Do(cu) 52 | assert.Error(t, err) 53 | }) 54 | 55 | t.Run("not in the list", func(t *testing.T) { 56 | cu, err := ParseCmdlineToCmdUnitList("top -p 1") 57 | assert.NoError(t, err) 58 | err = blf.Do(cu) 59 | assert.NoError(t, err) 60 | }) 61 | } 62 | -------------------------------------------------------------------------------- /dockin-opserver/internal/remote/helpers.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package remote 16 | 17 | import ( 18 | "time" 19 | 20 | "github.com/webankfintech/dockin-opserver/internal/log" 21 | 22 | "github.com/gorilla/websocket" 23 | ) 24 | 25 | var ( 26 | CommandParseErrTemplate = "command format is invalid, please check the input command: %s" 27 | ) 28 | 29 | func HandleWSError(ws *websocket.Conn, err error) bool { 30 | if err != nil { 31 | log.Logger.Warnf("handler ws err:%v", err) 32 | dt := time.Now().Add(time.Second) 33 | if err := ws.WriteMessage(websocket.TextMessage, []byte(err.Error())); err != nil { 34 | //if err := ws.WriteControl(websocket.CloseMessage, []byte(err.Error()), dt); err != nil { 35 | log.Logger.Warnf("websocket writes control message failed:") 36 | } 37 | ws.WriteControl(websocket.CloseMessage, []byte(err.Error()), dt) 38 | return true 39 | } 40 | return false 41 | } 42 | -------------------------------------------------------------------------------- /dockin-opserver/internal/remote/io_manager_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package remote 16 | 17 | import "testing" 18 | 19 | func Test_bytes_rune(t *testing.T) { 20 | t.Run("up arraw", func(t *testing.T) { 21 | upBytes := []byte{91, 67, 27, 91, 67, 27, 91, 67, 97, 105, 110, 32} 22 | t.Log(string(upBytes)) 23 | 24 | t.Log([]rune(string(upBytes))) 25 | }) 26 | } 27 | -------------------------------------------------------------------------------- /dockin-opserver/internal/remote/message.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package remote 16 | 17 | import jsoniter "github.com/json-iterator/go" 18 | 19 | const ( 20 | MsgCmd = "cmd" 21 | MsgResize = "resize" 22 | ) 23 | 24 | type Message struct { 25 | Type string `json:"type"` 26 | Cmd string `json:"cmd"` 27 | Cols int `json:"Cols"` 28 | Rows int `json:"Rows"` 29 | CmdLine string `json:"cmdLine"` 30 | } 31 | 32 | func ParserToMessage(data []byte) (*Message, error) { 33 | msg := &Message{} 34 | if err := jsoniter.Unmarshal(data, msg); err != nil { 35 | return nil, err 36 | } 37 | return msg, nil 38 | } 39 | -------------------------------------------------------------------------------- /dockin-opserver/internal/remote/parser_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package remote 16 | 17 | import ( 18 | "testing" 19 | 20 | "github.com/stretchr/testify/assert" 21 | ) 22 | 23 | func Test_parse_cd(t *testing.T) { 24 | t.Run("pure cd", func(t *testing.T) { 25 | list, err := ParseCmdlineToCmdUnitList("cd /data") 26 | assert.NoError(t, err) 27 | t.Logf("%#v", list) 28 | }) 29 | 30 | t.Run("with param", func(t *testing.T) { 31 | list, err := ParseCmdlineToCmdUnitList("cd -a /data") 32 | assert.NoError(t, err) 33 | t.Logf("%#v", list) 34 | }) 35 | 36 | t.Run("with param reverse", func(t *testing.T) { 37 | list, err := ParseCmdlineToCmdUnitList("cd /data -a -l") 38 | assert.NoError(t, err) 39 | t.Logf("%#v", list) 40 | }) 41 | 42 | t.Run("with param reverse combine", func(t *testing.T) { 43 | list, err := ParseCmdlineToCmdUnitList("cd /data -a -l;ls -al /tmp") 44 | assert.NoError(t, err) 45 | t.Logf("%#v", list) 46 | }) 47 | 48 | t.Run("|", func(t *testing.T) { 49 | list, err := ParseCmdlineToCmdUnitList("cd /data -a -l>/tmp") 50 | assert.NoError(t, err) 51 | t.Logf("%#v", list) 52 | }) 53 | 54 | t.Run("netstat -apn", func(t *testing.T) { 55 | list, err := ParseCmdlineToCmdUnitList("netstat -apn") 56 | assert.NoError(t, err) 57 | t.Logf("%#v", list) 58 | }) 59 | } 60 | -------------------------------------------------------------------------------- /dockin-opserver/internal/remote/prompt/input_posix_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | // +build !windows 16 | 17 | package prompt 18 | 19 | import ( 20 | "testing" 21 | ) 22 | 23 | func TestPosixParserGetKey(t *testing.T) { 24 | pp := &PosixParser{} 25 | scenarioTable := []struct { 26 | input []byte 27 | expected Key 28 | }{ 29 | { 30 | input: []byte{0x1b}, 31 | expected: Escape, 32 | }, 33 | { 34 | input: []byte{'a'}, 35 | expected: NotDefined, 36 | }, 37 | } 38 | 39 | for _, s := range scenarioTable { 40 | key := pp.GetKey(s.input) 41 | if key != s.expected { 42 | t.Errorf("Should be %s, but got %s", key, s.expected) 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /dockin-opserver/internal/remote/prompt/key.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package prompt 16 | 17 | // Key is the type express the key inserted from user. 18 | type Key int 19 | 20 | // ASCIICode is the type contains Key and it's ascii byte array. 21 | type ASCIICode struct { 22 | Key Key 23 | ASCIICode []byte 24 | } 25 | 26 | const ( 27 | Escape Key = iota 28 | ControlC 29 | ControlR 30 | Right 31 | Left 32 | LeftCursor 33 | Home 34 | End 35 | Delete 36 | Backspace 37 | Tab 38 | Enter 39 | ControlJ 40 | NotDefined 41 | ) 42 | -------------------------------------------------------------------------------- /dockin-opserver/internal/remote/prompt/key_bind.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package prompt 16 | 17 | // KeyBindFunc receives buffer and processed it. 18 | type KeyBindFunc func(*Buffer) 19 | 20 | // KeyBind represents which key should do what operation. 21 | type KeyBind struct { 22 | Key Key 23 | Fn KeyBindFunc 24 | } 25 | 26 | // ASCIICodeBind represents which []byte should do what operation 27 | type ASCIICodeBind struct { 28 | ASCIICode []byte 29 | Fn KeyBindFunc 30 | } 31 | 32 | // KeyBindMode to switch a key binding flexibly. 33 | type KeyBindMode string 34 | 35 | const ( 36 | // CommonKeyBind is a mode without any keyboard shortcut 37 | CommonKeyBind KeyBindMode = "common" 38 | // EmacsKeyBind is a mode to use emacs-like keyboard shortcut 39 | EmacsKeyBind KeyBindMode = "emacs" 40 | ) 41 | 42 | var CommonKeyBindings = []KeyBind{ 43 | // Go to the End of the line 44 | { 45 | Key: End, 46 | Fn: GoLineEnd, 47 | }, 48 | // Go to the beginning of the line 49 | { 50 | Key: Home, 51 | Fn: GoLineBeginning, 52 | }, 53 | // Delete character under the cursor 54 | { 55 | Key: Delete, 56 | Fn: DeleteChar, 57 | }, 58 | // Backspace 59 | { 60 | Key: Backspace, 61 | Fn: DeleteBeforeChar, 62 | }, 63 | // Right allow: Forward one character 64 | { 65 | Key: Right, 66 | Fn: GoRightChar, 67 | }, 68 | // Left allow: Backward one character 69 | { 70 | Key: Left, 71 | Fn: GoLeftChar, 72 | }, 73 | // delete 74 | { 75 | Key: Delete, 76 | Fn: DeleteBeforeChar, 77 | }, 78 | // remote cursor display 79 | { 80 | Key: LeftCursor, 81 | Fn: Empty, 82 | }, 83 | } 84 | -------------------------------------------------------------------------------- /dockin-opserver/internal/remote/prompt/key_bind_func.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package prompt 16 | 17 | // GoLineEnd Go to the End of the line 18 | func GoLineEnd(buf *Buffer) { 19 | x := []rune(buf.Document().TextAfterCursor()) 20 | buf.CursorRight(len(x)) 21 | } 22 | 23 | // GoLineBeginning Go to the beginning of the line 24 | func GoLineBeginning(buf *Buffer) { 25 | x := []rune(buf.Document().TextBeforeCursor()) 26 | buf.CursorLeft(len(x)) 27 | } 28 | 29 | // DeleteChar Delete character under the cursor 30 | func DeleteChar(buf *Buffer) { 31 | buf.Delete(1) 32 | } 33 | 34 | // DeleteWord Delete word before the cursor 35 | func DeleteWord(buf *Buffer) { 36 | buf.DeleteBeforeCursor(len([]rune(buf.Document().TextBeforeCursor())) - buf.Document().FindStartOfPreviousWordWithSpace()) 37 | } 38 | 39 | // DeleteBeforeChar Go to Backspace 40 | func DeleteBeforeChar(buf *Buffer) { 41 | buf.DeleteBeforeCursor(1) 42 | } 43 | 44 | // GoRightChar Forward one character 45 | func GoRightChar(buf *Buffer) { 46 | buf.CursorRight(1) 47 | } 48 | 49 | // GoLeftChar Backward one character 50 | func GoLeftChar(buf *Buffer) { 51 | buf.CursorLeft(1) 52 | } 53 | 54 | // GoRightWord Forward one word 55 | func GoRightWord(buf *Buffer) { 56 | buf.CursorRight(buf.Document().FindEndOfCurrentWordWithSpace()) 57 | } 58 | 59 | // GoLeftWord Backward one word 60 | func GoLeftWord(buf *Buffer) { 61 | buf.CursorLeft(len([]rune(buf.Document().TextBeforeCursor())) - buf.Document().FindStartOfPreviousWordWithSpace()) 62 | } 63 | 64 | // Empty, empty operation 65 | func Empty(buf *Buffer) { 66 | 67 | } -------------------------------------------------------------------------------- /dockin-opserver/internal/remote/stream.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package remote 16 | 17 | import ( 18 | "bytes" 19 | "context" 20 | "fmt" 21 | "io" 22 | "io/ioutil" 23 | 24 | "github.com/webankfintech/dockin-opserver/internal/log" 25 | ) 26 | 27 | type IOStreams struct { 28 | In io.Reader 29 | Out io.Writer 30 | ErrOut io.Writer 31 | } 32 | 33 | func NewIOStreams() (*IOStreams, *bytes.Buffer, *bytes.Buffer, *bytes.Buffer) { 34 | in := &bytes.Buffer{} 35 | out := &bytes.Buffer{} 36 | errOut := &bytes.Buffer{} 37 | 38 | return &IOStreams{ 39 | In: in, 40 | Out: out, 41 | ErrOut: errOut, 42 | }, in, out, errOut 43 | } 44 | 45 | func NewTestIOStreamsDiscard() IOStreams { 46 | in := &bytes.Buffer{} 47 | return IOStreams{ 48 | In: in, 49 | Out: ioutil.Discard, 50 | ErrOut: ioutil.Discard, 51 | } 52 | } 53 | 54 | type InteractStream struct { 55 | outBuffer chan string 56 | ctx context.Context 57 | inputBuffer chan []byte 58 | } 59 | 60 | func (is *InteractStream) Read(p []byte) (n int, err error) { 61 | select { 62 | case <-is.ctx.Done(): 63 | n = -1 64 | err = fmt.Errorf("interactStream close as run finished") 65 | return 66 | case data, ok := <-is.inputBuffer: 67 | if !ok { 68 | log.Logger.Infof("InteractStream read chan close") 69 | return 70 | } 71 | n = len(data) 72 | copy(p, data) 73 | } 74 | return 75 | } 76 | 77 | func (is *InteractStream) Write(p []byte) (n int, err error) { 78 | n = len(p) 79 | log.Logger.Debugf("write data to client, in string=%s", string(p)) 80 | is.outBuffer <- string(p) 81 | return 82 | } 83 | 84 | func (is *InteractStream) Close() error { 85 | close(is.outBuffer) 86 | close(is.inputBuffer) 87 | return nil 88 | } 89 | -------------------------------------------------------------------------------- /dockin-opserver/internal/utils/aes/aes.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package aes 16 | 17 | import ( 18 | "crypto/aes" 19 | "crypto/cipher" 20 | "crypto/rand" 21 | "encoding/hex" 22 | "errors" 23 | "io" 24 | ) 25 | 26 | type Aes struct { 27 | block cipher.Block 28 | } 29 | 30 | func NewAes(key string) (*Aes, error) { 31 | block, err := aes.NewCipher([]byte(key)) 32 | if err != nil { 33 | return nil, err 34 | } 35 | 36 | return &Aes{ 37 | block: block, 38 | }, nil 39 | } 40 | 41 | func (a *Aes) AesEncrypt(plaintext string) (string, error) { 42 | ciphertext := make([]byte, aes.BlockSize+len(plaintext)) 43 | iv := ciphertext[:aes.BlockSize] 44 | if _, err := io.ReadFull(rand.Reader, iv); err != nil { 45 | return "", err 46 | } 47 | cipher.NewCFBEncrypter(a.block, iv).XORKeyStream(ciphertext[aes.BlockSize:], 48 | []byte(plaintext)) 49 | return hex.EncodeToString(ciphertext), nil 50 | } 51 | 52 | func (a *Aes) AesDecrypt(d string) (string, error) { 53 | ciphertext, err := hex.DecodeString(d) 54 | if err != nil { 55 | return "", err 56 | } 57 | if len(ciphertext) < aes.BlockSize { 58 | return "", errors.New("ciphertext too short") 59 | } 60 | iv := ciphertext[:aes.BlockSize] 61 | ciphertext = ciphertext[aes.BlockSize:] 62 | cipher.NewCFBDecrypter(a.block, iv).XORKeyStream(ciphertext, ciphertext) 63 | return string(ciphertext), nil 64 | } 65 | -------------------------------------------------------------------------------- /dockin-opserver/internal/utils/aes/aes_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package aes 16 | 17 | import ( 18 | "crypto/sha256" 19 | "fmt" 20 | "testing" 21 | ) 22 | 23 | func Test_Aes(t *testing.T) { 24 | biz := "dockin-opserver8085" 25 | fmt.Println(biz) 26 | aes, _ := NewAes(biz) 27 | str1, _ := aes.AesEncrypt("{\"2\":\"efg\",\"1\":\"abc\"}") 28 | fmt.Println("str1:", str1) 29 | str2, _ := aes.AesDecrypt(str1) 30 | fmt.Println("str2", str2) 31 | 32 | aes1, _ := NewAes(biz) 33 | str3, _ := aes1.AesDecrypt(str1) 34 | fmt.Println("str3", str3) 35 | } 36 | 37 | func Test_Sha256(t *testing.T) { 38 | user := "test" 39 | passwd := "123456" 40 | h := sha256.New() 41 | h.Write([]byte(passwd)) 42 | fmt.Printf("%x\n", h.Sum(nil)) 43 | h.Write([]byte(user)) 44 | fmt.Printf("%x\n", h.Sum(nil)) 45 | 46 | } 47 | -------------------------------------------------------------------------------- /dockin-opserver/internal/utils/base/check.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package base 16 | 17 | import ( 18 | "regexp" 19 | "strconv" 20 | "strings" 21 | 22 | "github.com/google/uuid" 23 | ) 24 | 25 | func IsIp(input string) bool { 26 | pattern := "[\\d]+\\.[\\d]+\\.[\\d]+\\.[\\d]+" 27 | matched, _ := regexp.MatchString(pattern, input) 28 | return matched 29 | } 30 | 31 | func IsSubsystem(input string) bool { 32 | cnt := strings.Count(input, "-") 33 | return cnt == 1 34 | } 35 | 36 | func IsPodName(input string) bool { 37 | cnt := strings.Count(input, "-") 38 | return cnt > 2 39 | } 40 | 41 | func IsSubSystemId(input string) bool { 42 | pattern := `^[0-9]\d*$` 43 | matched, _ := regexp.MatchString(pattern, input) 44 | return matched 45 | } 46 | 47 | func IsUUid(input string) bool { 48 | if _, err := uuid.Parse(input); err != nil { 49 | return false 50 | } 51 | return true 52 | } 53 | 54 | func IsPodSet(input string) bool { 55 | sps := strings.Split(input, "-") 56 | cnt := len(sps) 57 | if cnt == 2 { 58 | _, err := strconv.ParseInt(sps[0], 10, 32) 59 | return err == nil 60 | } 61 | if cnt == 3 { 62 | return true 63 | } 64 | return false 65 | } -------------------------------------------------------------------------------- /dockin-opserver/internal/utils/base/check_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package base 16 | 17 | import ( 18 | "testing" 19 | 20 | "github.com/stretchr/testify/assert" 21 | ) 22 | 23 | func TestIsSubSystemId(t *testing.T) { 24 | t.Run("right system id", func(t *testing.T) { 25 | input := "0000" 26 | assert.True(t, IsSubSystemId(input)) 27 | }) 28 | 29 | t.Run("right system id 0", func(t *testing.T) { 30 | input := "0" 31 | assert.True(t, IsSubSystemId(input)) 32 | }) 33 | 34 | t.Run("with system name", func(t *testing.T) { 35 | input := "525dockin-wx" 36 | assert.False(t, IsSubSystemId(input)) 37 | }) 38 | 39 | t.Run("with mixture name", func(t *testing.T) { 40 | input := "dockin-wx" 41 | assert.False(t, IsSubSystemId(input)) 42 | }) 43 | } 44 | 45 | func TestIsPodSet(t *testing.T) { 46 | t.Run("given podName", func(t *testing.T) { 47 | assert.False(t, IsPodSet("xxx")) 48 | }) 49 | t.Run("test pod set name", func(t *testing.T) { 50 | assert.True(t, IsPodSet("xxx")) 51 | }) 52 | } 53 | 54 | func TestIsPodName(t *testing.T) { 55 | t.Run("given podName", func(t *testing.T) { 56 | assert.True(t, IsPodName("xxx")) 57 | }) 58 | t.Run("test pod set name", func(t *testing.T) { 59 | assert.False(t, IsPodName("xxx")) 60 | }) 61 | t.Run("test pod set name", func(t *testing.T) { 62 | assert.False(t, IsPodName("xxx")) 63 | }) 64 | } 65 | -------------------------------------------------------------------------------- /dockin-opserver/internal/utils/batch/batch.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package batch 16 | 17 | import ( 18 | "sync" 19 | "time" 20 | 21 | "github.com/pkg/errors" 22 | ) 23 | 24 | type Future func() 25 | 26 | type BatchTask struct { 27 | task []Future 28 | Wg *sync.WaitGroup 29 | Timeout time.Duration 30 | } 31 | 32 | func (b *BatchTask) Submit(fn Future) { 33 | b.task = append(b.task, fn) 34 | } 35 | 36 | func (b *BatchTask) WaitTimeout() error { 37 | b.Wg.Add(len(b.task)) 38 | b.run() 39 | 40 | c := make(chan struct{}) 41 | go func() { 42 | defer close(c) 43 | b.Wg.Wait() 44 | }() 45 | select { 46 | case <-c: 47 | return nil 48 | case <-time.After(b.Timeout): 49 | return errors.Errorf("canceled as timeout task") 50 | } 51 | } 52 | 53 | func (b *BatchTask) run() { 54 | for _, fn := range b.task { 55 | go func() { 56 | defer b.Wg.Done() 57 | fn() 58 | }() 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /dockin-opserver/internal/utils/batch/batch_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package batch 16 | 17 | import ( 18 | "sync" 19 | "testing" 20 | "time" 21 | ) 22 | 23 | type foo struct { 24 | Name string 25 | Status int 26 | } 27 | 28 | func Test_Batch(t *testing.T) { 29 | b := BatchTask{ 30 | Wg: new(sync.WaitGroup), 31 | Timeout: time.Duration(time.Second * 3), 32 | } 33 | 34 | foolist := []*foo{&foo{"first", 1}, &foo{"second", 1}, &foo{"third", 3}} 35 | 36 | var newfoolist []*foo 37 | setfooname := func(f *foo) { 38 | f.Name = "zero" 39 | newfoolist = append(newfoolist, f) 40 | } 41 | 42 | for _, x := range foolist { 43 | index := *x 44 | b.Submit(func() { 45 | setfooname(&index) 46 | }) 47 | } 48 | 49 | b.WaitTimeout() 50 | for _, fo := range newfoolist { 51 | t.Logf("%#v", fo) 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /dockin-opserver/internal/utils/cmd/parser.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package cmd 16 | 17 | import ( 18 | "strings" 19 | 20 | "mvdan.cc/sh/v3/syntax" 21 | ) 22 | 23 | func GetCommandList(cmd string) ([]string, error) { 24 | cmdReader := strings.NewReader(cmd) 25 | prog, err := syntax.NewParser().Parse(cmdReader, "") 26 | if err != nil { 27 | return nil, err 28 | } 29 | var cmdList []string 30 | syntax.Walk(prog, func(node syntax.Node) bool { 31 | switch node.(type) { 32 | case *syntax.CallExpr: 33 | callExpr := node.(*syntax.CallExpr) 34 | for _, args := range callExpr.Args { 35 | cmdList = append(cmdList, args.Lit()) 36 | } 37 | case *syntax.DblQuoted: 38 | dbl := node.(*syntax.DblQuoted) 39 | for _, args := range dbl.Parts { 40 | cmdList = append(cmdList, args.(*syntax.Lit).Value) 41 | } 42 | } 43 | return true 44 | }) 45 | 46 | return cmdList, nil 47 | } 48 | -------------------------------------------------------------------------------- /dockin-opserver/internal/utils/cmd/parser_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package cmd 16 | 17 | import ( 18 | "testing" 19 | 20 | "github.com/stretchr/testify/assert" 21 | ) 22 | 23 | func TestGetCmdList(t *testing.T) { 24 | t.Run("long cmd", func(t *testing.T) { 25 | cmd := "ls -a -l|grep w|grep -v;/bin/sh -c \"cd /data/logs/vie.log\"" 26 | cmdList, err := GetCommandList(cmd) 27 | assert.NoError(t, err) 28 | t.Log(cmdList) 29 | }) 30 | 31 | t.Run("simple", func(t *testing.T) { 32 | cmd := "ls -a -l" 33 | cmdList, err := GetCommandList(cmd) 34 | assert.NoError(t, err) 35 | t.Log(cmdList) 36 | }) 37 | 38 | t.Run("bach -c", func(t *testing.T) { 39 | cmd := `bash -c "cd /data/bin;sh run.sh"` 40 | cmdList, err := GetCommandList(cmd) 41 | assert.NoError(t, err) 42 | t.Log(cmdList) 43 | }) 44 | 45 | t.Run("ps -ef|grep rm", func(t *testing.T) { 46 | cmd := `ps -ef|grep rm` 47 | cmdList, err := GetCommandList(cmd) 48 | assert.NoError(t, err) 49 | t.Log(cmdList) 50 | }) 51 | } 52 | -------------------------------------------------------------------------------- /dockin-opserver/internal/utils/file/file_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package file 16 | 17 | import ( 18 | "os" 19 | "testing" 20 | 21 | "github.com/stretchr/testify/assert" 22 | ) 23 | 24 | func Test_extractFileSpec(t *testing.T) { 25 | path := `tctp/dockin-test:/tmp/foo` 26 | spec, err := extractFileSpec(path) 27 | assert.NoError(t, err) 28 | t.Log(spec) 29 | } 30 | 31 | func Test_Untar(t *testing.T) { 32 | file := "C:\\download\\tmp\\hzfllz\\wcsctl.tar" 33 | fr, err := os.Open(file) 34 | if err != nil { 35 | panic(err) 36 | } 37 | defer fr.Close() 38 | UntarFile(fr, "C:\\download\\tmp\\hzfllz") 39 | } 40 | -------------------------------------------------------------------------------- /dockin-opserver/internal/utils/ip/ip.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package ip 16 | 17 | import ( 18 | "net" 19 | "net/http" 20 | 21 | "github.com/webankfintech/dockin-opserver/internal/log" 22 | ) 23 | 24 | func GetIp(req *http.Request) string { 25 | realIp := req.Header.Get("X-Real-IP") 26 | if realIp != "" { 27 | log.Logger.Infof("parse remote ip from X-Real-IP=%s", realIp) 28 | return realIp 29 | } 30 | 31 | reqIp, _, _ := net.SplitHostPort(req.RemoteAddr) 32 | log.Logger.Infof("parse remote ip from request.RemoteAddr=%s", reqIp) 33 | return reqIp 34 | } 35 | -------------------------------------------------------------------------------- /dockin-opserver/internal/utils/rest/rest.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package rest 16 | 17 | import ( 18 | "fmt" 19 | "net/http" 20 | "time" 21 | 22 | "github.com/webankfintech/dockin-opserver/internal/log" 23 | 24 | "github.com/valyala/fasthttp" 25 | ) 26 | 27 | func HttpGet(url string, timeout time.Duration) ([]byte, error) { 28 | log.Logger.Infof("send http request url=%s", url) 29 | 30 | code, body, err := fasthttp.GetTimeout(nil, url, timeout) 31 | if err != nil { 32 | log.Logger.Warnf("get method return err, url=%s, err=%s", url, err.Error()) 33 | return nil, err 34 | } 35 | if code != http.StatusOK { 36 | reqErr := fmt.Errorf("get method return not 200/OK, url=%s, status Code=%s", url, code) 37 | log.Logger.Warnf(reqErr.Error()) 38 | return nil, err 39 | } 40 | 41 | log.Logger.Infof("send http request finished url=%s, response=%s", url, string(body)) 42 | return body, nil 43 | } 44 | 45 | func HttpPost(url string, payload []byte) ([]byte, error) { 46 | req := &fasthttp.Request{} 47 | req.SetRequestURI(url) 48 | req.SetBody(payload) 49 | req.Header.SetContentType("application/json") 50 | req.Header.SetMethod("POST") 51 | resp := &fasthttp.Response{} 52 | client := &fasthttp.Client{} 53 | if err := client.Do(req, resp); err != nil { 54 | return nil, err 55 | } 56 | 57 | return resp.Body(), nil 58 | } 59 | -------------------------------------------------------------------------------- /dockin-opserver/internal/utils/str/strings.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package str 16 | 17 | func Compare(src, dest string) bool { 18 | if src == "" && dest == "" { 19 | return true 20 | } 21 | 22 | return src == dest 23 | } 24 | -------------------------------------------------------------------------------- /dockin-opserver/internal/utils/trace/seq.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package trace 16 | 17 | import ( 18 | "strings" 19 | 20 | "github.com/google/uuid" 21 | ) 22 | 23 | func TraceID() string { 24 | uid := uuid.New().String() 25 | return strings.ReplaceAll(uid, "-", "") 26 | } -------------------------------------------------------------------------------- /dockin-opserver/internal/utils/url/codec.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package url 16 | 17 | import "net/url" 18 | 19 | func UrlEncode(input string) string { 20 | return url.PathEscape(input) 21 | } 22 | 23 | func UrlDecode(input string) (string, error) { 24 | return url.PathUnescape(input) 25 | } 26 | -------------------------------------------------------------------------------- /dockin-opserver/internal/utils/url/codec_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) @2021 Webank Group Holding Limited 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package url 16 | 17 | import ( 18 | "testing" 19 | 20 | "github.com/stretchr/testify/assert" 21 | ) 22 | 23 | func TestUrlDecode(t *testing.T) { 24 | content := `{"data":1}` 25 | encode := UrlEncode(content) 26 | t.Log(encode) 27 | decode, err := UrlDecode(encode) 28 | assert.NoError(t, err) 29 | t.Log(decode) 30 | assert.Equal(t, content, decode) 31 | } 32 | -------------------------------------------------------------------------------- /dockin-opserver/scripts/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (C) @2021 Webank Group Holding Limited 4 | #

5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 6 | # in compliance with the License. You may obtain a copy of the License at 7 | #

8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | #

10 | # Unless required by applicable law or agreed to in writing, software distributed under the License 11 | # is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 12 | # or implied. See the License for the specific language governing permissions and limitations under 13 | # the License. 14 | # 15 | 16 | ################################ 17 | # start.sh 18 | ############################### 19 | 20 | set -e; 21 | 22 | function detect_pid_file(){ 23 | for no in $(seq 1 30); do 24 | if [ -f ${APP_BIN}/sys.pid ]; then 25 | return 0; 26 | else 27 | echo "[$no] detect pid file ..." 28 | sleep 1s; 29 | fi 30 | done 31 | echo "detect pid file timeout." 32 | return 1; 33 | } 34 | 35 | function get_pid { 36 | local ppid="" 37 | if [ -f $APP_BIN/sys.pid ]; then 38 | ppid=$(cat $APP_BIN/sys.pid) 39 | fi 40 | echo "$ppid"; 41 | } 42 | 43 | APP_BIN="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 44 | APP_HOME="$(dirname $APP_BIN)"; [ -d "$APP_HOME" ] || { echo "ERROR failed to detect APP_HOME."; exit 1;} 45 | APP_NAME=$(basename "$APP_HOME") 46 | APP_START_OPTION= 47 | if [ -f $APP_BIN/server.env ];then 48 | APP_START_OPTION=`cat $APP_BIN/server.env | grep APP_START_OPTION::: | awk -F ':::' {'print $2'}` 49 | fi 50 | 51 | # set up the logs dir 52 | APP_LOG=$APP_HOME/logs 53 | if [ ! -d ${APP_LOG} ];then 54 | mkdir ${APP_LOG} 55 | fi 56 | 57 | export APP_HOME=${APP_HOME} 58 | cd $APP_HOME 59 | subsystem=`ls apps` 60 | cd $APP_BIN 61 | 62 | pid=$(get_pid) 63 | if [ -n "$pid" ];then 64 | echo -e "ERROR\t the server is already running (pid=$pid), there is no need to execute start.sh again." 65 | exit 9; 66 | fi 67 | 68 | if [[ "$DOCKER" == true ]]; then 69 | $APP_HOME/apps/${subsystem} ${APP_START_OPTION} >> $APP_LOG/${APP_NAME}.out 2>&1 70 | else 71 | $APP_HOME/apps/${subsystem} ${APP_START_OPTION} >> $APP_LOG/${APP_NAME}.out 2>&1 & 72 | fi 73 | 74 | echo $! > sys.pid 75 | 76 | if detect_pid_file; then 77 | ./watchdog.sh --add-crontab 78 | fi 79 | -------------------------------------------------------------------------------- /dockin-opserver/scripts/stop.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (C) @2021 Webank Group Holding Limited 4 | #

5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 6 | # in compliance with the License. You may obtain a copy of the License at 7 | #

8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | #

10 | # Unless required by applicable law or agreed to in writing, software distributed under the License 11 | # is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 12 | # or implied. See the License for the specific language governing permissions and limitations under 13 | # the License. 14 | # 15 | 16 | ################################ 17 | # stop.sh 18 | ############################### 19 | 20 | function get_pid { 21 | local ppid="" 22 | if [ -f $APP_BIN/sys.pid ]; then 23 | ppid=$(cat $APP_BIN/sys.pid) 24 | fi 25 | echo "$ppid"; 26 | } 27 | 28 | APP_BIN="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 29 | APP_NAME=$(basename "$APP_HOME") 30 | APP_HOME="$(dirname $APP_BIN)"; [ -d "$APP_HOME" ] || { echo "ERROR! failed to detect APP_HOME."; exit 1;} 31 | 32 | ${APP_BIN}/watchdog.sh --delete-crontab 33 | pid=$(get_pid) 34 | if [ -z "$pid" ];then 35 | echo -e "INFO\t the server does NOT start yet, there is no need to execute stop.sh." 36 | exit 0; 37 | fi 38 | kill -15 $pid; 39 | stop_timeout=30 40 | for no in $(seq 1 $stop_timeout); do 41 | if ps $PS_PARAM -p "$pid" 2>&1 > /dev/null; then 42 | if [ $no -lt $stop_timeout ]; then 43 | echo "[$no] shutdown server ..." 44 | sleep 1 45 | continue 46 | fi 47 | echo "shutdown server timeout, kill process: $pid" 48 | kill -9 $pid; sleep 1; break; 49 | else 50 | echo "shutdown server ok!"; break; 51 | fi 52 | done 53 | if [ -f $APP_BIN/sys.pid ]; then 54 | rm $APP_BIN/sys.pid 55 | fi 56 | -------------------------------------------------------------------------------- /dockin.code-workspace: -------------------------------------------------------------------------------- 1 | { 2 | "folders": [ 3 | { 4 | "path": "dockin-opsctl" 5 | }, 6 | { 7 | "path": "dockin-opagent" 8 | }, 9 | { 10 | "path": "dockin-opserver" 11 | }, 12 | { 13 | "path": "docs" 14 | }, 15 | { 16 | "path":"dockctl" 17 | } 18 | ], 19 | "settings": {} 20 | } -------------------------------------------------------------------------------- /docs/images/dockin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankFinTech/Dockin-Ops/69cd2af1d7c2841dbaee130807e5aabde4bd295a/docs/images/dockin.png --------------------------------------------------------------------------------