| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- // 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 compute
- import (
- "fmt"
- "os"
- "path"
- "strings"
- "yunion.io/x/jsonutils"
- "yunion.io/x/pkg/errors"
- "yunion.io/x/onecloud/pkg/mcclient"
- modules "yunion.io/x/onecloud/pkg/mcclient/modules/compute"
- "yunion.io/x/onecloud/pkg/util/procutils"
- )
- func init() {
- type SshkeypairQueryOptions struct {
- Project string `help:"get keypair for specific project"`
- Admin bool `help:"get admin keypair, sysadmin ONLY option"`
- }
- getSshKeypair := func(s *mcclient.ClientSession, args *SshkeypairQueryOptions) (string, string, error) {
- query := jsonutils.NewDict()
- if args.Admin {
- query.Add(jsonutils.JSONTrue, "admin")
- }
- var keys jsonutils.JSONObject
- if len(args.Project) == 0 {
- listResult, err := modules.Sshkeypairs.List(s, query)
- if err != nil {
- return "", "", err
- }
- keys = listResult.Data[0]
- } else {
- result, err := modules.Sshkeypairs.GetById(s, args.Project, query)
- if err != nil {
- return "", "", err
- }
- keys = result
- }
- privKey, _ := keys.GetString("private_key")
- pubKey, _ := keys.GetString("public_key")
- return privKey, pubKey, nil
- }
- R(&SshkeypairQueryOptions{}, "sshkeypair-show", "Get ssh keypairs", func(s *mcclient.ClientSession, args *SshkeypairQueryOptions) error {
- privKey, pubKey, err := getSshKeypair(s, args)
- if err != nil {
- return err
- }
- fmt.Print(privKey)
- fmt.Print(pubKey)
- return nil
- })
- type SshkeypairInjectOptions struct {
- SshkeypairQueryOptions
- TargetDir string `help:"Target directory to save cloud ssh keypair"`
- }
- R(&SshkeypairInjectOptions{}, "sshkeypair-inject", "Inject ssh keypairs to local path", func(s *mcclient.ClientSession, args *SshkeypairInjectOptions) error {
- _, pubKey, err := getSshKeypair(s, &args.SshkeypairQueryOptions)
- if err != nil {
- return err
- }
- targetDir := args.TargetDir
- if targetDir == "" {
- homeDir, err := os.UserHomeDir()
- if err != nil {
- return errors.Wrap(err, "get current user's home dir")
- }
- targetDir = homeDir
- }
- sshDir := path.Join(targetDir, ".ssh")
- // MkdirAll anyways
- os.MkdirAll(sshDir, 0700)
- authFile := path.Join(sshDir, "authorized_keys")
- var oldKeys string
- if procutils.NewCommand("test", "-f", authFile).Run() == nil {
- output, err := procutils.NewCommand("cat", authFile).Output()
- if err != nil {
- return errors.Wrapf(err, "cat: %s", output)
- }
- oldKeys = string(output)
- }
- var MergeAuthorizedKeys = func(oldKeys string, pubKey string) string {
- const sshKeySignature = "@yunioncloudpods"
- var allkeys = make(map[string]string)
- if len(oldKeys) > 0 {
- for _, line := range strings.Split(oldKeys, "\n") {
- line = strings.TrimSpace(line)
- dat := strings.Split(line, " ")
- if len(dat) > 1 {
- if len(dat) > 2 && dat[2] == sshKeySignature {
- // skip ssh keys with signature
- continue
- }
- if _, ok := allkeys[dat[1]]; !ok {
- allkeys[dat[1]] = line
- }
- }
- }
- }
- candiateKeys := []string{pubKey}
- for _, k := range candiateKeys {
- if len(k) > 0 {
- k = strings.TrimSpace(k)
- dat := strings.Split(k, " ")
- if len(dat) > 1 {
- if _, ok := allkeys[dat[1]]; !ok {
- allkeys[dat[1]] = strings.Join([]string{dat[0], dat[1], sshKeySignature}, " ")
- }
- }
- }
- }
- var keys = make([]string, 0)
- for _, val := range allkeys {
- keys = append(keys, val)
- }
- return strings.Join(keys, "\n") + "\n"
- }
- newKeys := MergeAuthorizedKeys(oldKeys, pubKey)
- if output, err := procutils.NewCommand(
- "sh", "-c", fmt.Sprintf("echo '%s' > %s", newKeys, authFile)).Output(); err != nil {
- return errors.Wrapf(err, "write public keys: %s", output)
- }
- if output, err := procutils.NewCommand(
- "chmod", "0644", authFile).Output(); err != nil {
- return errors.Wrapf(err, "chmod failed %s", output)
- }
- return nil
- })
- }
|