mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-24 16:03:43 +08:00
Merge pull request #11017 from swordqiu/automated-cherry-pick-of-#11016-upstream-release-3.7
Automated cherry pick of #11016: fix: init cloud shell by apigateway
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
echo "Welcome to Cloud Shell :-) You may execute climc and other command tools in this shell."
|
||||
echo "Please exec 'climc' to get started"
|
||||
echo ""
|
||||
@@ -1,5 +1,7 @@
|
||||
FROM registry.cn-beijing.aliyuncs.com/yunionio/climc-base:20200820
|
||||
FROM registry.cn-beijing.aliyuncs.com/yunionio/climc-base:20210508
|
||||
|
||||
ADD ./build/climc/root/opt /opt
|
||||
|
||||
ADD ./build/climc/root/root /root
|
||||
|
||||
ADD ./_output/alpine-build/bin/climc ./_output/alpine-build/bin/*cli /opt/yunion/bin/
|
||||
|
||||
@@ -6,7 +6,9 @@ ENV TZ Asia/Shanghai
|
||||
|
||||
RUN mkdir -p /opt/yunion/bin
|
||||
|
||||
RUN apk add --no-cache bash bash-completion tzdata ca-certificates vim && \
|
||||
RUN echo http://dl-cdn.alpinelinux.org/alpine/edge/testing >>/etc/apk/repositories
|
||||
|
||||
RUN apk add --no-cache bash bash-completion tzdata ca-certificates vim ipmitool kubectl && \
|
||||
rm -rf /var/cache/apk/*
|
||||
|
||||
RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
debian10-base:
|
||||
docker buildx build --platform linux/arm64,linux/amd64 --push \
|
||||
-t registry.cn-beijing.aliyuncs.com/yunionio/debian10-base:1.0 -f ./Dockerfile.debian-base .
|
||||
|
||||
climc-base:
|
||||
docker buildx build --platform linux/arm64,linux/amd64 --push \
|
||||
-t registry.cn-beijing.aliyuncs.com/yunionio/climc-base:$(VERSION) -f ./Dockerfile.climc-base .
|
||||
|
||||
@@ -24,7 +24,7 @@ import (
|
||||
|
||||
webconsole_api "yunion.io/x/onecloud/pkg/apis/webconsole"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules/webconsole"
|
||||
o "yunion.io/x/onecloud/pkg/mcclient/options"
|
||||
"yunion.io/x/onecloud/pkg/webconsole/command"
|
||||
)
|
||||
@@ -70,7 +70,7 @@ func init() {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ret, err := modules.WebConsole.DoK8sShellConnect(s, args.NAME, params)
|
||||
ret, err := webconsole.WebConsole.DoK8sShellConnect(s, args.NAME, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -83,7 +83,7 @@ func init() {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ret, err := modules.WebConsole.DoK8sLogConnect(s, args.NAME, params)
|
||||
ret, err := webconsole.WebConsole.DoK8sLogConnect(s, args.NAME, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -92,7 +92,7 @@ func init() {
|
||||
})
|
||||
|
||||
R(&o.WebConsoleBaremetalOptions{}, "webconsole-baremetal", "Connect baremetal host webconsole", func(s *mcclient.ClientSession, args *o.WebConsoleBaremetalOptions) error {
|
||||
ret, err := modules.WebConsole.DoBaremetalConnect(s, args.ID, nil)
|
||||
ret, err := webconsole.WebConsole.DoBaremetalConnect(s, args.ID, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -105,7 +105,7 @@ func init() {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ret, err := modules.WebConsole.DoSshConnect(s, args.IP, params)
|
||||
ret, err := webconsole.WebConsole.DoSshConnect(s, args.IP, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -114,7 +114,7 @@ func init() {
|
||||
})
|
||||
|
||||
R(&o.WebConsoleServerOptions{}, "webconsole-server", "Connect server remote graphic console", func(s *mcclient.ClientSession, args *o.WebConsoleServerOptions) error {
|
||||
ret, err := modules.WebConsole.DoServerConnect(s, args.ID, nil)
|
||||
ret, err := webconsole.WebConsole.DoServerConnect(s, args.ID, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules/k8s"
|
||||
_ "yunion.io/x/onecloud/pkg/mcclient/modules/monitor"
|
||||
_ "yunion.io/x/onecloud/pkg/mcclient/modules/notify"
|
||||
_ "yunion.io/x/onecloud/pkg/mcclient/modules/webconsole"
|
||||
_ "yunion.io/x/onecloud/pkg/mcclient/modules/yunionconf"
|
||||
)
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package webconsole
|
||||
|
||||
type SK8sRequest struct {
|
||||
Cluster string `json:"cluster"`
|
||||
Namespace string `json:"namespace"`
|
||||
Container string `json:"container"`
|
||||
}
|
||||
|
||||
type SK8sShellRequest struct {
|
||||
SK8sRequest
|
||||
|
||||
Command string `json:"command"`
|
||||
Env map[string]string `json:"env"`
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
package webconsole // import "yunion.io/x/onecloud/pkg/mcclient/modules/webconsole"
|
||||
+65
-2
@@ -12,15 +12,20 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package modules
|
||||
package webconsole
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
webconsole_api "yunion.io/x/onecloud/pkg/apis/webconsole"
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/auth"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modulebase"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules/k8s"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -30,7 +35,7 @@ var (
|
||||
func init() {
|
||||
WebConsole = WebConsoleManager{NewWebConsoleManager()}
|
||||
|
||||
register(&WebConsole)
|
||||
modulebase.Register("v1", &WebConsole)
|
||||
}
|
||||
|
||||
type WebConsoleManager struct {
|
||||
@@ -64,6 +69,64 @@ func (m WebConsoleManager) DoK8sShellConnect(s *mcclient.ClientSession, id strin
|
||||
return m.DoK8sConnect(s, id, "shell", params)
|
||||
}
|
||||
|
||||
func (m WebConsoleManager) DoCloudShell(s *mcclient.ClientSession, _ jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
adminSession := auth.GetAdminSession(s.GetContext(), s.GetRegion(), "")
|
||||
|
||||
query := jsonutils.NewDict()
|
||||
query.Add(jsonutils.JSONTrue, "system")
|
||||
query.Add(jsonutils.NewString("system"), "scope")
|
||||
query.Add(jsonutils.NewString("system-default"), "name")
|
||||
clusters, err := k8s.KubeClusters.List(adminSession, query)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "KubeClusters")
|
||||
}
|
||||
if len(clusters.Data) == 0 {
|
||||
return nil, httperrors.NewNotFoundError("cluster system-default not found")
|
||||
}
|
||||
clusterId, _ := clusters.Data[0].GetString("id")
|
||||
if len(clusterId) == 0 {
|
||||
return nil, httperrors.NewNotFoundError("cluster system-default no id")
|
||||
}
|
||||
|
||||
query = jsonutils.NewDict()
|
||||
query.Add(jsonutils.NewString(clusterId), "cluster")
|
||||
query.Add(jsonutils.NewString("onecloud"), "namespace")
|
||||
query.Add(jsonutils.NewString("climc"), "search")
|
||||
pods, err := k8s.Pods.List(adminSession, query)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Pods")
|
||||
}
|
||||
if len(pods.Data) == 0 {
|
||||
return nil, httperrors.NewNotFoundError("pod climc not found")
|
||||
}
|
||||
podName, _ := pods.Data[0].GetString("name")
|
||||
if len(podName) == 0 {
|
||||
return nil, httperrors.NewNotFoundError("pod climc no name")
|
||||
}
|
||||
|
||||
req := webconsole_api.SK8sShellRequest{}
|
||||
req.Cluster = clusterId
|
||||
req.Namespace = "onecloud"
|
||||
req.Container = "climc"
|
||||
req.Command = "/bin/bash"
|
||||
req.Env = map[string]string{
|
||||
"OS_AUTH_TOKEN": s.GetToken().GetTokenString(),
|
||||
"OS_PROJECT_NAME": s.GetProjectName(),
|
||||
"OS_PROJECT_DOMAIN": s.GetProjectDomain(),
|
||||
"OS_AUTH_URL": "https://default-keystone:30500/v3",
|
||||
"OS_ENDPOINT_TYPE": "internal",
|
||||
"YUNION_USE_CACHED_TOKEN": "false",
|
||||
"YUNION_INSECURE": "true",
|
||||
"OS_USERNAME": "",
|
||||
"OS_PASSWORD": "",
|
||||
"OS_DOMAIN_NAME": "",
|
||||
"OS_ACCESS_KEY": "",
|
||||
"OS_SECRET_KEY": "",
|
||||
"OS_TRY_TERM_WIDTH": "false",
|
||||
}
|
||||
return m.DoK8sConnect(s, podName, "shell", jsonutils.Marshal(req))
|
||||
}
|
||||
|
||||
func (m WebConsoleManager) DoK8sLogConnect(s *mcclient.ClientSession, id string, params jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
return m.DoK8sConnect(s, id, "log", params)
|
||||
}
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
|
||||
webconsole_api "yunion.io/x/onecloud/pkg/apis/webconsole"
|
||||
o "yunion.io/x/onecloud/pkg/webconsole/options"
|
||||
)
|
||||
|
||||
@@ -114,12 +115,29 @@ func (c *KubectlExec) Command(cmd string, args ...string) *KubectlExec {
|
||||
}
|
||||
|
||||
func NewPodBashCommand(env *K8sEnv) ICommand {
|
||||
shellRequest := webconsole_api.SK8sShellRequest{}
|
||||
err := env.Data.Unmarshal(&shellRequest)
|
||||
if err != nil {
|
||||
log.Errorf("env.Data.Unmarshal SK8sShellRequest: %s", err)
|
||||
}
|
||||
if shellRequest.Command == "" {
|
||||
shellRequest.Command = "sh"
|
||||
}
|
||||
args := make([]string, 0)
|
||||
if len(shellRequest.Env) > 0 {
|
||||
for k, v := range shellRequest.Env {
|
||||
args = append(args, fmt.Sprintf("%s=%s", k, v))
|
||||
}
|
||||
args = append(args, shellRequest.Command)
|
||||
shellRequest.Command = "env"
|
||||
}
|
||||
|
||||
return NewKubectlCommand(env.Kubeconfig, env.Namespace).Exec().
|
||||
Stdin().
|
||||
TTY().
|
||||
Pod(env.Pod).
|
||||
Container(env.Container).
|
||||
Command("sh")
|
||||
Command(shellRequest.Command, args...)
|
||||
}
|
||||
|
||||
type KubectlLog struct {
|
||||
|
||||
+19
-14
@@ -23,6 +23,7 @@ import (
|
||||
"net/url"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
webconsole_api "yunion.io/x/onecloud/pkg/apis/webconsole"
|
||||
"yunion.io/x/onecloud/pkg/appsrv"
|
||||
@@ -54,21 +55,25 @@ func InitHandlers(app *appsrv.Application) {
|
||||
|
||||
func fetchK8sEnv(ctx context.Context, w http.ResponseWriter, r *http.Request) (*command.K8sEnv, error) {
|
||||
params, _, body := appsrv.FetchEnv(ctx, w, r)
|
||||
cluster, _ := body.GetString("cluster")
|
||||
if cluster == "" {
|
||||
cluster = "default"
|
||||
|
||||
k8sReq := webconsole_api.SK8sRequest{}
|
||||
err := body.Unmarshal(&k8sReq)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "body.Unmarshal SK8sRequest")
|
||||
}
|
||||
namespace, _ := body.GetString("namespace")
|
||||
if namespace == "" {
|
||||
namespace = "default"
|
||||
|
||||
if k8sReq.Cluster == "" {
|
||||
k8sReq.Cluster = "default"
|
||||
}
|
||||
if k8sReq.Namespace == "" {
|
||||
k8sReq.Namespace = "default"
|
||||
}
|
||||
podName := params["<podName>"]
|
||||
container, _ := body.GetString("container")
|
||||
adminSession := auth.GetAdminSession(ctx, o.Options.Region, "")
|
||||
|
||||
query := jsonutils.NewDict()
|
||||
query.Add(jsonutils.NewString(namespace), "namespace")
|
||||
query.Add(jsonutils.NewString(cluster), "cluster")
|
||||
query.Add(jsonutils.NewString(k8sReq.Namespace), "namespace")
|
||||
query.Add(jsonutils.NewString(k8sReq.Cluster), "cluster")
|
||||
obj, err := k8s.Pods.Get(adminSession, podName, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -78,13 +83,13 @@ func fetchK8sEnv(ctx context.Context, w http.ResponseWriter, r *http.Request) (*
|
||||
}
|
||||
|
||||
data := jsonutils.NewDict()
|
||||
ret, err := k8s.KubeClusters.GetSpecific(adminSession, cluster, "kubeconfig", data)
|
||||
ret, err := k8s.KubeClusters.GetSpecific(adminSession, k8sReq.Cluster, "kubeconfig", data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
conf, err := ret.GetString("kubeconfig")
|
||||
if err != nil {
|
||||
return nil, httperrors.NewNotFoundError("Not found cluster %q kubeconfig", cluster)
|
||||
return nil, httperrors.NewNotFoundError("Not found cluster %q kubeconfig", k8sReq.Cluster)
|
||||
}
|
||||
f, err := ioutil.TempFile("", "kubeconfig-")
|
||||
if err != nil {
|
||||
@@ -94,10 +99,10 @@ func fetchK8sEnv(ctx context.Context, w http.ResponseWriter, r *http.Request) (*
|
||||
f.WriteString(conf)
|
||||
|
||||
return &command.K8sEnv{
|
||||
Cluster: cluster,
|
||||
Namespace: namespace,
|
||||
Cluster: k8sReq.Cluster,
|
||||
Namespace: k8sReq.Namespace,
|
||||
Pod: podName,
|
||||
Container: container,
|
||||
Container: k8sReq.Container,
|
||||
Kubeconfig: f.Name(),
|
||||
Data: body,
|
||||
}, nil
|
||||
|
||||
Reference in New Issue
Block a user