ansible.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // 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
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package ansible
  15. import (
  16. "fmt"
  17. "strings"
  18. "yunion.io/x/jsonutils"
  19. "yunion.io/x/onecloud/pkg/mcclient"
  20. compute "yunion.io/x/onecloud/pkg/mcclient/modules/compute"
  21. )
  22. type AnsibleHostsOptions struct {
  23. List bool `help:"List all ansible inventory"`
  24. Host string `help:"List of a host"`
  25. PrivateKey string `help:"path to private key to use for ansible"`
  26. Port int `help:"optional port, if port is not 22"`
  27. User string `help:"username to try"`
  28. UserBecome string `help:"username to sudo"`
  29. }
  30. func serverGetNameIP(srv jsonutils.JSONObject) (string, string, error) {
  31. host, _ := srv.GetString("name")
  32. if len(host) == 0 {
  33. return "", "", fmt.Errorf("No name for server")
  34. }
  35. ips, _ := srv.GetString("ips")
  36. if len(ips) == 0 {
  37. return "", "", fmt.Errorf("no ips for server %s", host)
  38. }
  39. ipList := strings.Split(ips, ",")
  40. if len(ipList) == 0 {
  41. return "", "", fmt.Errorf("no valid ips for server %s", host)
  42. }
  43. return host, ipList[0], nil
  44. }
  45. func doList(s *mcclient.ClientSession, args *AnsibleHostsOptions) error {
  46. hostVars := jsonutils.NewDict()
  47. hosts := jsonutils.NewArray()
  48. limit := 2048
  49. total := 1
  50. for hosts.Size() < total {
  51. params := jsonutils.NewDict()
  52. params.Add(jsonutils.NewInt(int64(limit)), "limit")
  53. params.Add(jsonutils.NewInt(int64(hosts.Size())), "offset")
  54. params.Add(jsonutils.JSONTrue, "details")
  55. retList, err := compute.Servers.List(s, params)
  56. if err != nil {
  57. return err
  58. }
  59. if len(retList.Data) > 0 {
  60. for i := 0; i < len(retList.Data); i += 1 {
  61. host, ip, err := serverGetNameIP(retList.Data[i])
  62. if err == nil {
  63. hosts.Add(jsonutils.NewString(host))
  64. hostVars.Add(jsonutils.NewString(ip), host, "ansible_host")
  65. if args.Port > 0 {
  66. hostVars.Add(jsonutils.NewInt(int64(args.Port)), host, "ansible_port")
  67. }
  68. if len(args.PrivateKey) > 0 {
  69. hostVars.Add(jsonutils.NewString(args.PrivateKey), host, "ansible_ssh_private_key_file")
  70. }
  71. if len(args.User) > 0 {
  72. hostVars.Add(jsonutils.NewString(args.User), host, "ansible_user")
  73. }
  74. if len(args.UserBecome) > 0 {
  75. hostVars.Add(jsonutils.NewString(args.UserBecome), host, "ansible_become_user")
  76. }
  77. }
  78. }
  79. }
  80. total = retList.Total
  81. }
  82. output := jsonutils.NewDict()
  83. output.Add(hostVars, "_meta", "hostvars")
  84. children := jsonutils.NewArray(jsonutils.NewString("ungrouped"))
  85. output.Add(children, "all", "children")
  86. output.Add(hosts, "ungrouped", "hosts")
  87. fmt.Printf("%s\n", output.PrettyString())
  88. return nil
  89. }
  90. func doHost(s *mcclient.ClientSession, host string, args *AnsibleHostsOptions) error {
  91. srv, err := compute.Servers.Get(s, host, nil)
  92. if err != nil {
  93. return err
  94. }
  95. _, ipstr, err := serverGetNameIP(srv)
  96. if err != nil {
  97. return err
  98. }
  99. hostVar := jsonutils.NewDict()
  100. hostVar.Add(jsonutils.NewString(ipstr), "ansible_host")
  101. if args.Port > 0 {
  102. hostVar.Add(jsonutils.NewInt(int64(args.Port)), "ansible_port")
  103. }
  104. if len(args.PrivateKey) > 0 {
  105. hostVar.Add(jsonutils.NewString(args.PrivateKey), "ansible_ssh_private_key_file")
  106. }
  107. if len(args.User) > 0 {
  108. hostVar.Add(jsonutils.NewString(args.User), "ansible_user")
  109. }
  110. if len(args.UserBecome) > 0 {
  111. hostVar.Add(jsonutils.NewString(args.UserBecome), "ansible_become_user")
  112. }
  113. fmt.Printf("%s\n", hostVar.PrettyString())
  114. return nil
  115. }
  116. func init() {
  117. R(&AnsibleHostsOptions{}, "ansible-hosts", "List ansible inventory", func(s *mcclient.ClientSession, args *AnsibleHostsOptions) error {
  118. if len(args.Host) > 0 {
  119. return doHost(s, args.Host, args)
  120. } else if args.List {
  121. return doList(s, args)
  122. } else {
  123. return fmt.Errorf("Invalid arguments, either --list or --host must be specified")
  124. }
  125. })
  126. }