devtooltemplate.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  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 options
  15. import (
  16. "fmt"
  17. "io/ioutil"
  18. "strings"
  19. "yunion.io/x/jsonutils"
  20. apis "yunion.io/x/onecloud/pkg/apis/ansible"
  21. "yunion.io/x/onecloud/pkg/util/ansible"
  22. )
  23. type DevtoolTemplateIdOptions struct {
  24. ID string `help:"name/id of the playbook"`
  25. }
  26. type DevtoolTemplateBindingOptions struct {
  27. DevtoolTemplateIdOptions
  28. ServerID string `help:"host/vm name/id to apply"`
  29. }
  30. type DevtoolTemplateListOptions struct {
  31. BaseListOptions
  32. }
  33. type DevtoolTemplateCronjobOptions struct {
  34. Day int `help:"Cronjob runs at given day" default:"0"`
  35. Hour int `help:"Cronjob runs at given hour" default:"0"`
  36. Min int `help:"Cronjob runs at given min" default:"0"`
  37. Sec int `help:"Cronjob runs at given sec" default:"0"`
  38. Interval int64 `help:"Cronjob runs at given interval" default:"0"`
  39. Start bool `help:"start job when created" default:"false"`
  40. Enabled bool `help:"Set job status enabled" default:"false"`
  41. }
  42. type DevtoolTemplateCommonOptions struct {
  43. DevtoolTemplateCronjobOptions
  44. Host []string `help:"name or id of server or host in format '<[server:]id|host:id>|ipaddr var=val'"`
  45. Mod []string `help:"ansible modules and their arguments in format 'name k1=v1 k2=v2'"`
  46. File []string `help:"files for use by modules, e.g. name=content, name=@file"`
  47. }
  48. func (opts *DevtoolTemplateCommonOptions) ToPlaybook() (*ansible.Playbook, error) {
  49. if len(opts.Mod) == 0 {
  50. return nil, fmt.Errorf("Requires at least one --mod argument")
  51. }
  52. if len(opts.Host) == 0 {
  53. return nil, fmt.Errorf("Requires at least one server/host to operate on")
  54. }
  55. pb := ansible.NewPlaybook()
  56. hosts := []ansible.Host{}
  57. for _, s := range opts.Host {
  58. host, err := ansible.ParseHostLine(s)
  59. if err != nil {
  60. return nil, err
  61. }
  62. hosts = append(hosts, host)
  63. }
  64. pb.Inventory = ansible.Inventory{Hosts: hosts}
  65. for _, s := range opts.Mod {
  66. module, err := ansible.ParseModuleLine(s)
  67. if err != nil {
  68. return nil, err
  69. }
  70. pb.Modules = append(pb.Modules, module)
  71. }
  72. files := map[string][]byte{}
  73. for _, s := range opts.File {
  74. i := strings.IndexByte(s, '=')
  75. if i < 0 {
  76. return nil, fmt.Errorf("missing '=' in argument for --file. Read command help")
  77. }
  78. name := strings.TrimSpace(s[:i])
  79. if name == "" {
  80. return nil, fmt.Errorf("empty file name: %s", s)
  81. }
  82. v := s[i+1:]
  83. if len(v) > 0 && v[0] == '@' {
  84. path := v[1:]
  85. d, err := ioutil.ReadFile(path)
  86. if err != nil {
  87. return nil, fmt.Errorf("read file %s: %v", path, err)
  88. }
  89. files[name] = d
  90. } else {
  91. files[name] = []byte(v)
  92. }
  93. }
  94. pb.Files = files
  95. return pb, nil
  96. }
  97. type DevtoolTemplateCreateOptions struct {
  98. NAME string `help:"name of the playbook"`
  99. DevtoolTemplateCommonOptions
  100. }
  101. func (opts *DevtoolTemplateCreateOptions) Params() (*jsonutils.JSONDict, error) {
  102. pb, err := opts.DevtoolTemplateCommonOptions.ToPlaybook()
  103. if err != nil {
  104. return nil, err
  105. }
  106. input := &apis.AnsiblePlaybookCreateInput{
  107. Name: opts.NAME,
  108. Playbook: *pb,
  109. }
  110. params := input.JSON(input)
  111. params.Add(jsonutils.NewInt(int64(opts.Day)), "day")
  112. params.Add(jsonutils.NewInt(int64(opts.Hour)), "hour")
  113. params.Add(jsonutils.NewInt(int64(opts.Min)), "min")
  114. params.Add(jsonutils.NewInt(int64(opts.Sec)), "sec")
  115. params.Add(jsonutils.NewInt(opts.Interval), "interval")
  116. params.Add(jsonutils.NewBool(opts.Start), "start")
  117. params.Add(jsonutils.NewBool(opts.Enabled), "enabled")
  118. return params, nil
  119. }
  120. type DevtoolTemplateUpdateOptions struct {
  121. ID string `json:"-" help:"name/id of the playbook"`
  122. Name string
  123. DevtoolTemplateCommonOptions
  124. Rebind bool `help:"Unbind and Bind all related servers" default:"false"`
  125. }
  126. func (opts *DevtoolTemplateUpdateOptions) Params() (*jsonutils.JSONDict, error) {
  127. pb, err := opts.DevtoolTemplateCommonOptions.ToPlaybook()
  128. if err != nil {
  129. return nil, err
  130. }
  131. input := &apis.AnsiblePlaybookUpdateInput{
  132. Name: opts.Name,
  133. Playbook: *pb,
  134. }
  135. params := input.JSON(input)
  136. params.Add(jsonutils.NewBool(opts.Rebind), "rebind")
  137. params.Add(jsonutils.NewInt(int64(opts.Day)), "day")
  138. params.Add(jsonutils.NewInt(int64(opts.Hour)), "hour")
  139. params.Add(jsonutils.NewInt(int64(opts.Min)), "min")
  140. params.Add(jsonutils.NewInt(int64(opts.Sec)), "sec")
  141. params.Add(jsonutils.NewInt(opts.Interval), "interval")
  142. params.Add(jsonutils.NewBool(opts.Start), "start")
  143. params.Add(jsonutils.NewBool(opts.Enabled), "enabled")
  144. return params, nil
  145. }