cloud-mu 2.1.0beta → 3.0.0beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (291) hide show
  1. checksums.yaml +5 -5
  2. data/Berksfile +4 -5
  3. data/Berksfile.lock +179 -0
  4. data/README.md +1 -6
  5. data/ansible/roles/geerlingguy.firewall/templates/firewall.bash.j2 +0 -0
  6. data/ansible/roles/mu-installer/README.md +33 -0
  7. data/ansible/roles/mu-installer/defaults/main.yml +2 -0
  8. data/ansible/roles/mu-installer/handlers/main.yml +2 -0
  9. data/ansible/roles/mu-installer/meta/main.yml +60 -0
  10. data/ansible/roles/mu-installer/tasks/main.yml +13 -0
  11. data/ansible/roles/mu-installer/tests/inventory +2 -0
  12. data/ansible/roles/mu-installer/tests/test.yml +5 -0
  13. data/ansible/roles/mu-installer/vars/main.yml +2 -0
  14. data/bin/mu-adopt +125 -0
  15. data/bin/mu-aws-setup +4 -4
  16. data/bin/mu-azure-setup +265 -0
  17. data/bin/mu-azure-tests +43 -0
  18. data/bin/mu-cleanup +20 -8
  19. data/bin/mu-configure +224 -98
  20. data/bin/mu-deploy +8 -3
  21. data/bin/mu-gcp-setup +16 -8
  22. data/bin/mu-gen-docs +92 -8
  23. data/bin/mu-load-config.rb +52 -12
  24. data/bin/mu-momma-cat +36 -0
  25. data/bin/mu-node-manage +34 -27
  26. data/bin/mu-self-update +2 -2
  27. data/bin/mu-ssh +12 -8
  28. data/bin/mu-upload-chef-artifacts +11 -4
  29. data/bin/mu-user-manage +3 -0
  30. data/cloud-mu.gemspec +8 -11
  31. data/cookbooks/firewall/libraries/helpers_iptables.rb +2 -2
  32. data/cookbooks/firewall/metadata.json +1 -1
  33. data/cookbooks/firewall/recipes/default.rb +5 -9
  34. data/cookbooks/mu-firewall/attributes/default.rb +2 -0
  35. data/cookbooks/mu-firewall/metadata.rb +1 -1
  36. data/cookbooks/mu-glusterfs/templates/default/mu-gluster-client.erb +0 -0
  37. data/cookbooks/mu-master/Berksfile +2 -2
  38. data/cookbooks/mu-master/files/default/check_mem.pl +0 -0
  39. data/cookbooks/mu-master/files/default/cloudamatic.png +0 -0
  40. data/cookbooks/mu-master/metadata.rb +5 -4
  41. data/cookbooks/mu-master/recipes/389ds.rb +1 -1
  42. data/cookbooks/mu-master/recipes/basepackages.rb +30 -10
  43. data/cookbooks/mu-master/recipes/default.rb +59 -7
  44. data/cookbooks/mu-master/recipes/firewall-holes.rb +1 -1
  45. data/cookbooks/mu-master/recipes/init.rb +65 -47
  46. data/cookbooks/mu-master/recipes/{eks-kubectl.rb → kubectl.rb} +4 -10
  47. data/cookbooks/mu-master/recipes/sssd.rb +2 -1
  48. data/cookbooks/mu-master/recipes/update_nagios_only.rb +6 -6
  49. data/cookbooks/mu-master/templates/default/web_app.conf.erb +2 -2
  50. data/cookbooks/mu-master/templates/mods/ldap.conf.erb +4 -0
  51. data/cookbooks/mu-php54/Berksfile +1 -2
  52. data/cookbooks/mu-php54/metadata.rb +4 -5
  53. data/cookbooks/mu-php54/recipes/default.rb +1 -1
  54. data/cookbooks/mu-splunk/templates/default/splunk-init.erb +0 -0
  55. data/cookbooks/mu-tools/Berksfile +3 -2
  56. data/cookbooks/mu-tools/files/default/Mu_CA.pem +33 -0
  57. data/cookbooks/mu-tools/libraries/helper.rb +20 -8
  58. data/cookbooks/mu-tools/metadata.rb +5 -2
  59. data/cookbooks/mu-tools/recipes/apply_security.rb +2 -3
  60. data/cookbooks/mu-tools/recipes/eks.rb +1 -1
  61. data/cookbooks/mu-tools/recipes/gcloud.rb +5 -30
  62. data/cookbooks/mu-tools/recipes/nagios.rb +1 -1
  63. data/cookbooks/mu-tools/recipes/rsyslog.rb +1 -0
  64. data/cookbooks/mu-tools/recipes/selinux.rb +19 -0
  65. data/cookbooks/mu-tools/recipes/split_var_partitions.rb +0 -1
  66. data/cookbooks/mu-tools/recipes/windows-client.rb +256 -122
  67. data/cookbooks/mu-tools/resources/disk.rb +3 -1
  68. data/cookbooks/mu-tools/templates/amazon/sshd_config.erb +1 -1
  69. data/cookbooks/mu-tools/templates/default/etc_hosts.erb +1 -1
  70. data/cookbooks/mu-tools/templates/default/{kubeconfig.erb → kubeconfig-eks.erb} +0 -0
  71. data/cookbooks/mu-tools/templates/default/kubeconfig-gke.erb +27 -0
  72. data/cookbooks/mu-tools/templates/windows-10/sshd_config.erb +137 -0
  73. data/cookbooks/mu-utility/recipes/nat.rb +4 -0
  74. data/extras/alpha.png +0 -0
  75. data/extras/beta.png +0 -0
  76. data/extras/clean-stock-amis +2 -2
  77. data/extras/generate-stock-images +131 -0
  78. data/extras/git-fix-permissions-hook +0 -0
  79. data/extras/image-generators/AWS/centos6.yaml +17 -0
  80. data/extras/image-generators/{aws → AWS}/centos7-govcloud.yaml +0 -0
  81. data/extras/image-generators/{aws → AWS}/centos7.yaml +0 -0
  82. data/extras/image-generators/{aws → AWS}/rhel7.yaml +0 -0
  83. data/extras/image-generators/{aws → AWS}/win2k12.yaml +0 -0
  84. data/extras/image-generators/{aws → AWS}/win2k16.yaml +0 -0
  85. data/extras/image-generators/{aws → AWS}/windows.yaml +0 -0
  86. data/extras/image-generators/{gcp → Google}/centos6.yaml +1 -0
  87. data/extras/image-generators/Google/centos7.yaml +18 -0
  88. data/extras/python_rpm/build.sh +0 -0
  89. data/extras/release.png +0 -0
  90. data/extras/ruby_rpm/build.sh +0 -0
  91. data/extras/ruby_rpm/muby.spec +1 -1
  92. data/install/README.md +43 -5
  93. data/install/deprecated-bash-library.sh +0 -0
  94. data/install/installer +1 -1
  95. data/install/jenkinskeys.rb +0 -0
  96. data/install/mu-master.yaml +55 -0
  97. data/modules/mommacat.ru +41 -7
  98. data/modules/mu.rb +444 -149
  99. data/modules/mu/adoption.rb +500 -0
  100. data/modules/mu/cleanup.rb +235 -158
  101. data/modules/mu/cloud.rb +675 -138
  102. data/modules/mu/clouds/aws.rb +156 -24
  103. data/modules/mu/clouds/aws/alarm.rb +4 -14
  104. data/modules/mu/clouds/aws/bucket.rb +60 -18
  105. data/modules/mu/clouds/aws/cache_cluster.rb +8 -20
  106. data/modules/mu/clouds/aws/collection.rb +12 -22
  107. data/modules/mu/clouds/aws/container_cluster.rb +209 -118
  108. data/modules/mu/clouds/aws/database.rb +120 -45
  109. data/modules/mu/clouds/aws/dnszone.rb +7 -18
  110. data/modules/mu/clouds/aws/endpoint.rb +5 -15
  111. data/modules/mu/clouds/aws/firewall_rule.rb +144 -72
  112. data/modules/mu/clouds/aws/folder.rb +4 -11
  113. data/modules/mu/clouds/aws/function.rb +6 -16
  114. data/modules/mu/clouds/aws/group.rb +4 -12
  115. data/modules/mu/clouds/aws/habitat.rb +11 -13
  116. data/modules/mu/clouds/aws/loadbalancer.rb +40 -28
  117. data/modules/mu/clouds/aws/log.rb +5 -13
  118. data/modules/mu/clouds/aws/msg_queue.rb +9 -24
  119. data/modules/mu/clouds/aws/nosqldb.rb +4 -12
  120. data/modules/mu/clouds/aws/notifier.rb +6 -13
  121. data/modules/mu/clouds/aws/role.rb +69 -40
  122. data/modules/mu/clouds/aws/search_domain.rb +17 -20
  123. data/modules/mu/clouds/aws/server.rb +184 -94
  124. data/modules/mu/clouds/aws/server_pool.rb +33 -38
  125. data/modules/mu/clouds/aws/storage_pool.rb +5 -12
  126. data/modules/mu/clouds/aws/user.rb +59 -33
  127. data/modules/mu/clouds/aws/userdata/linux.erb +18 -30
  128. data/modules/mu/clouds/aws/userdata/windows.erb +9 -9
  129. data/modules/mu/clouds/aws/vpc.rb +214 -145
  130. data/modules/mu/clouds/azure.rb +978 -44
  131. data/modules/mu/clouds/azure/container_cluster.rb +413 -0
  132. data/modules/mu/clouds/azure/firewall_rule.rb +500 -0
  133. data/modules/mu/clouds/azure/habitat.rb +167 -0
  134. data/modules/mu/clouds/azure/loadbalancer.rb +205 -0
  135. data/modules/mu/clouds/azure/role.rb +211 -0
  136. data/modules/mu/clouds/azure/server.rb +810 -0
  137. data/modules/mu/clouds/azure/user.rb +257 -0
  138. data/modules/mu/clouds/azure/userdata/README.md +4 -0
  139. data/modules/mu/clouds/azure/userdata/linux.erb +137 -0
  140. data/modules/mu/clouds/azure/userdata/windows.erb +275 -0
  141. data/modules/mu/clouds/azure/vpc.rb +782 -0
  142. data/modules/mu/clouds/cloudformation.rb +12 -9
  143. data/modules/mu/clouds/cloudformation/firewall_rule.rb +5 -13
  144. data/modules/mu/clouds/cloudformation/server.rb +10 -1
  145. data/modules/mu/clouds/cloudformation/server_pool.rb +1 -0
  146. data/modules/mu/clouds/cloudformation/vpc.rb +0 -2
  147. data/modules/mu/clouds/google.rb +554 -117
  148. data/modules/mu/clouds/google/bucket.rb +173 -32
  149. data/modules/mu/clouds/google/container_cluster.rb +1112 -157
  150. data/modules/mu/clouds/google/database.rb +24 -47
  151. data/modules/mu/clouds/google/firewall_rule.rb +344 -89
  152. data/modules/mu/clouds/google/folder.rb +156 -79
  153. data/modules/mu/clouds/google/group.rb +272 -82
  154. data/modules/mu/clouds/google/habitat.rb +177 -52
  155. data/modules/mu/clouds/google/loadbalancer.rb +9 -34
  156. data/modules/mu/clouds/google/role.rb +1211 -0
  157. data/modules/mu/clouds/google/server.rb +491 -227
  158. data/modules/mu/clouds/google/server_pool.rb +233 -48
  159. data/modules/mu/clouds/google/user.rb +479 -125
  160. data/modules/mu/clouds/google/userdata/linux.erb +3 -3
  161. data/modules/mu/clouds/google/userdata/windows.erb +9 -9
  162. data/modules/mu/clouds/google/vpc.rb +381 -223
  163. data/modules/mu/config.rb +689 -214
  164. data/modules/mu/config/bucket.rb +1 -1
  165. data/modules/mu/config/cache_cluster.rb +1 -1
  166. data/modules/mu/config/cache_cluster.yml +0 -4
  167. data/modules/mu/config/container_cluster.rb +18 -9
  168. data/modules/mu/config/database.rb +6 -23
  169. data/modules/mu/config/firewall_rule.rb +9 -15
  170. data/modules/mu/config/folder.rb +22 -21
  171. data/modules/mu/config/habitat.rb +22 -21
  172. data/modules/mu/config/loadbalancer.rb +2 -2
  173. data/modules/mu/config/role.rb +9 -40
  174. data/modules/mu/config/server.rb +26 -5
  175. data/modules/mu/config/server_pool.rb +1 -1
  176. data/modules/mu/config/storage_pool.rb +2 -2
  177. data/modules/mu/config/user.rb +4 -0
  178. data/modules/mu/config/vpc.rb +350 -110
  179. data/modules/mu/defaults/{amazon_images.yaml → AWS.yaml} +37 -39
  180. data/modules/mu/defaults/Azure.yaml +17 -0
  181. data/modules/mu/defaults/Google.yaml +24 -0
  182. data/modules/mu/defaults/README.md +1 -1
  183. data/modules/mu/deploy.rb +168 -125
  184. data/modules/mu/groomer.rb +2 -1
  185. data/modules/mu/groomers/ansible.rb +104 -32
  186. data/modules/mu/groomers/chef.rb +96 -44
  187. data/modules/mu/kittens.rb +20602 -0
  188. data/modules/mu/logger.rb +38 -11
  189. data/modules/mu/master.rb +90 -8
  190. data/modules/mu/master/chef.rb +2 -3
  191. data/modules/mu/master/ldap.rb +0 -1
  192. data/modules/mu/master/ssl.rb +250 -0
  193. data/modules/mu/mommacat.rb +917 -513
  194. data/modules/scratchpad.erb +1 -1
  195. data/modules/tests/super_complex_bok.yml +0 -0
  196. data/modules/tests/super_simple_bok.yml +0 -0
  197. data/roles/mu-master.json +2 -1
  198. data/spec/azure_creds +5 -0
  199. data/spec/mu.yaml +56 -0
  200. data/spec/mu/clouds/azure_spec.rb +164 -27
  201. data/spec/spec_helper.rb +5 -0
  202. data/test/clean_up.py +0 -0
  203. data/test/exec_inspec.py +0 -0
  204. data/test/exec_mu_install.py +0 -0
  205. data/test/exec_retry.py +0 -0
  206. data/test/smoke_test.rb +0 -0
  207. metadata +90 -118
  208. data/cookbooks/mu-jenkins/Berksfile +0 -14
  209. data/cookbooks/mu-jenkins/CHANGELOG.md +0 -13
  210. data/cookbooks/mu-jenkins/LICENSE +0 -37
  211. data/cookbooks/mu-jenkins/README.md +0 -105
  212. data/cookbooks/mu-jenkins/attributes/default.rb +0 -42
  213. data/cookbooks/mu-jenkins/files/default/cleanup_deploy_config.xml +0 -73
  214. data/cookbooks/mu-jenkins/files/default/deploy_config.xml +0 -44
  215. data/cookbooks/mu-jenkins/metadata.rb +0 -21
  216. data/cookbooks/mu-jenkins/recipes/default.rb +0 -195
  217. data/cookbooks/mu-jenkins/recipes/node-ssh-config.rb +0 -54
  218. data/cookbooks/mu-jenkins/recipes/public_key.rb +0 -24
  219. data/cookbooks/mu-jenkins/templates/default/example_job.config.xml.erb +0 -24
  220. data/cookbooks/mu-jenkins/templates/default/org.jvnet.hudson.plugins.SSHBuildWrapper.xml.erb +0 -14
  221. data/cookbooks/mu-jenkins/templates/default/ssh_config.erb +0 -6
  222. data/cookbooks/nagios/Berksfile +0 -11
  223. data/cookbooks/nagios/CHANGELOG.md +0 -589
  224. data/cookbooks/nagios/CONTRIBUTING.md +0 -11
  225. data/cookbooks/nagios/LICENSE +0 -37
  226. data/cookbooks/nagios/README.md +0 -328
  227. data/cookbooks/nagios/TESTING.md +0 -2
  228. data/cookbooks/nagios/attributes/config.rb +0 -171
  229. data/cookbooks/nagios/attributes/default.rb +0 -228
  230. data/cookbooks/nagios/chefignore +0 -102
  231. data/cookbooks/nagios/definitions/command.rb +0 -33
  232. data/cookbooks/nagios/definitions/contact.rb +0 -33
  233. data/cookbooks/nagios/definitions/contactgroup.rb +0 -33
  234. data/cookbooks/nagios/definitions/host.rb +0 -33
  235. data/cookbooks/nagios/definitions/hostdependency.rb +0 -33
  236. data/cookbooks/nagios/definitions/hostescalation.rb +0 -34
  237. data/cookbooks/nagios/definitions/hostgroup.rb +0 -33
  238. data/cookbooks/nagios/definitions/nagios_conf.rb +0 -38
  239. data/cookbooks/nagios/definitions/resource.rb +0 -33
  240. data/cookbooks/nagios/definitions/service.rb +0 -33
  241. data/cookbooks/nagios/definitions/servicedependency.rb +0 -33
  242. data/cookbooks/nagios/definitions/serviceescalation.rb +0 -34
  243. data/cookbooks/nagios/definitions/servicegroup.rb +0 -33
  244. data/cookbooks/nagios/definitions/timeperiod.rb +0 -33
  245. data/cookbooks/nagios/libraries/base.rb +0 -314
  246. data/cookbooks/nagios/libraries/command.rb +0 -91
  247. data/cookbooks/nagios/libraries/contact.rb +0 -230
  248. data/cookbooks/nagios/libraries/contactgroup.rb +0 -112
  249. data/cookbooks/nagios/libraries/custom_option.rb +0 -36
  250. data/cookbooks/nagios/libraries/data_bag_helper.rb +0 -23
  251. data/cookbooks/nagios/libraries/default.rb +0 -90
  252. data/cookbooks/nagios/libraries/host.rb +0 -412
  253. data/cookbooks/nagios/libraries/hostdependency.rb +0 -181
  254. data/cookbooks/nagios/libraries/hostescalation.rb +0 -173
  255. data/cookbooks/nagios/libraries/hostgroup.rb +0 -119
  256. data/cookbooks/nagios/libraries/nagios.rb +0 -282
  257. data/cookbooks/nagios/libraries/resource.rb +0 -59
  258. data/cookbooks/nagios/libraries/service.rb +0 -455
  259. data/cookbooks/nagios/libraries/servicedependency.rb +0 -215
  260. data/cookbooks/nagios/libraries/serviceescalation.rb +0 -195
  261. data/cookbooks/nagios/libraries/servicegroup.rb +0 -144
  262. data/cookbooks/nagios/libraries/timeperiod.rb +0 -160
  263. data/cookbooks/nagios/libraries/users_helper.rb +0 -54
  264. data/cookbooks/nagios/metadata.rb +0 -25
  265. data/cookbooks/nagios/recipes/_load_databag_config.rb +0 -153
  266. data/cookbooks/nagios/recipes/_load_default_config.rb +0 -241
  267. data/cookbooks/nagios/recipes/apache.rb +0 -48
  268. data/cookbooks/nagios/recipes/default.rb +0 -204
  269. data/cookbooks/nagios/recipes/nginx.rb +0 -82
  270. data/cookbooks/nagios/recipes/pagerduty.rb +0 -143
  271. data/cookbooks/nagios/recipes/server_package.rb +0 -40
  272. data/cookbooks/nagios/recipes/server_source.rb +0 -164
  273. data/cookbooks/nagios/templates/default/apache2.conf.erb +0 -96
  274. data/cookbooks/nagios/templates/default/cgi.cfg.erb +0 -266
  275. data/cookbooks/nagios/templates/default/commands.cfg.erb +0 -13
  276. data/cookbooks/nagios/templates/default/contacts.cfg.erb +0 -37
  277. data/cookbooks/nagios/templates/default/hostgroups.cfg.erb +0 -25
  278. data/cookbooks/nagios/templates/default/hosts.cfg.erb +0 -15
  279. data/cookbooks/nagios/templates/default/htpasswd.users.erb +0 -6
  280. data/cookbooks/nagios/templates/default/nagios.cfg.erb +0 -22
  281. data/cookbooks/nagios/templates/default/nginx.conf.erb +0 -62
  282. data/cookbooks/nagios/templates/default/pagerduty.cgi.erb +0 -185
  283. data/cookbooks/nagios/templates/default/resource.cfg.erb +0 -27
  284. data/cookbooks/nagios/templates/default/servicedependencies.cfg.erb +0 -15
  285. data/cookbooks/nagios/templates/default/servicegroups.cfg.erb +0 -14
  286. data/cookbooks/nagios/templates/default/services.cfg.erb +0 -14
  287. data/cookbooks/nagios/templates/default/templates.cfg.erb +0 -31
  288. data/cookbooks/nagios/templates/default/timeperiods.cfg.erb +0 -13
  289. data/extras/image-generators/aws/centos6.yaml +0 -18
  290. data/modules/mu/defaults/google_images.yaml +0 -16
  291. data/roles/mu-master-jenkins.json +0 -24
@@ -0,0 +1,167 @@
1
+ # Copyright:: Copyright (c) 2019 eGlobalTech, Inc., all rights reserved
2
+ #
3
+ # Licensed under the BSD-3 license (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License in the root of the project or at
6
+ #
7
+ # http://egt-labs.com/mu/LICENSE.html
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
+
15
+ module MU
16
+ class Cloud
17
+ class Azure
18
+ # Creates an Azure directory as configured in {MU::Config::BasketofKittens::habitats}
19
+ class Habitat < MU::Cloud::Habitat
20
+
21
+ # Placeholder method, just here to see which bits of the subscription
22
+ # API actually work. Delete this once we actually have enough
23
+ # functionality for a real implementation.
24
+ def self.testcalls
25
+
26
+ #pp MU::Cloud::Azure::Habitat.find
27
+
28
+ pp MU::Cloud::Azure.billing.enrollment_accounts.list
29
+
30
+ # pp MU::Cloud::Azure.subfactory.api.class.name
31
+
32
+ # pp MU::Cloud::Azure.subfactory.subscription_factory.create_subscription_in_enrollment_account # this should barf
33
+ end
34
+
35
+ # Initialize this cloud resource object. Calling +super+ will invoke the initializer defined under {MU::Cloud}, which should set the attribtues listed in {MU::Cloud::PUBLIC_ATTRS} as well as applicable dependency shortcuts, like <tt>@vpc</tt>, for us.
36
+ # @param args [Hash]: Hash of named arguments passed via Ruby's double-splat
37
+ def initialize(**args)
38
+ super
39
+
40
+ cloud_desc if @cloud_id # XXX why don't I have this on regroom?
41
+ if !@cloud_id and cloud_desc and cloud_desc.project_id
42
+ @cloud_id = cloud_desc.project_id
43
+ end
44
+
45
+ if !mu_name.nil?
46
+ @mu_name = mu_name
47
+ elsif @config['scrub_mu_isms']
48
+ @mu_name = @config['name']
49
+ else
50
+ @mu_name = @deploy.getResourceName(@config['name'])
51
+ end
52
+ end
53
+
54
+ # Called automatically by {MU::Deploy#createResources}
55
+ def create
56
+ end
57
+
58
+ # Called automatically by {MU::Deploy#createResources}
59
+ def groom
60
+ end
61
+
62
+ # Return the cloud descriptor for the Habitat
63
+ def cloud_desc
64
+ @cached_cloud_desc ||= MU::Cloud::Azure::Habitat.find(cloud_id: @cloud_id).values.first
65
+ # @habitat_id ||= @cached_cloud_desc.parent.id if @cached_cloud_desc
66
+ @cached_cloud_desc
67
+ end
68
+
69
+ # Return the metadata for this project's configuration
70
+ # @return [Hash]
71
+ def notify
72
+ # MU.structToHash(MU::Cloud::Google.resource_manager(credentials: @config['credentials']).get_project(@cloud_id))
73
+ {}
74
+ end
75
+
76
+ # Does this resource type exist as a global (cloud-wide) artifact, or
77
+ # is it localized to a region/zone?
78
+ # @return [Boolean]
79
+ def self.isGlobal?
80
+ true
81
+ end
82
+
83
+ # Denote whether this resource implementation is experiment, ready for
84
+ # testing, or ready for production use.
85
+ def self.quality
86
+ MU::Cloud::ALPHA
87
+ end
88
+
89
+ # Check whether is in the +ACTIVE+ state and has billing enabled.
90
+ # @param project_id [String]
91
+ # @return [Boolean]
92
+ def self.isLive?(project_id, credentials = nil)
93
+ true
94
+ end
95
+
96
+ # Stub method. Azure resources are cleaned up by removing the parent
97
+ # resource group.
98
+ # @return [void]
99
+ def self.cleanup(**args)
100
+ end
101
+
102
+ @@list_projects_cache = nil
103
+
104
+ # Locate and return cloud provider descriptors of this resource type
105
+ # which match the provided parameters, or all visible resources if no
106
+ # filters are specified. At minimum, implementations of +find+ must
107
+ # honor +credentials+ and +cloud_id+ arguments. We may optionally
108
+ # support other search methods, such as +tag_key+ and +tag_value+, or
109
+ # cloud-specific arguments like +project+. See also {MU::MommaCat.findStray}.
110
+ # @param args [Hash]: Hash of named arguments passed via Ruby's double-splat
111
+ # @return [Hash<String,OpenStruct>]: The cloud provider's complete descriptions of matching resources
112
+ def self.find(**args)
113
+ #MU.log "habitat.find called by #{caller[0]}", MU::WARN, details: args
114
+ found = {}
115
+
116
+ args[:cloud_id] ||= args[:project]
117
+ # XXX we probably want to cache this
118
+ # XXX but why are we being called over and over?
119
+
120
+ if args[:cloud_id]
121
+ found[args[:cloud_id]] = MU::Cloud::Azure.subs.subscriptions.get(args[:cloud_id])
122
+ else
123
+ MU::Cloud::Azure.subs.subscriptions.list.each { |sub|
124
+ found[sub.subscription_id] = sub
125
+ }
126
+ end
127
+
128
+ found
129
+ end
130
+
131
+ # Reverse-map our cloud description into a runnable config hash.
132
+ # We assume that any values we have in +@config+ are placeholders, and
133
+ # calculate our own accordingly based on what's live in the cloud.
134
+ def toKitten(rootparent: nil, billing: nil)
135
+ bok = {
136
+ "cloud" => "Azure",
137
+ "credentials" => @config['credentials']
138
+ }
139
+
140
+ bok
141
+ end
142
+
143
+ # Cloud-specific configuration properties.
144
+ # @param config [MU::Config]: The calling MU::Config object
145
+ # @return [Array<Array,Hash>]: List of required fields, and json-schema Hash of cloud-specific configuration parameters for this resource
146
+ def self.schema(config)
147
+ toplevel_required = []
148
+ schema = {
149
+ }
150
+ [toplevel_required, schema]
151
+ end
152
+
153
+ # Cloud-specific pre-processing of {MU::Config::BasketofKittens::habitats}, bare and unvalidated.
154
+ # @param habitat [Hash]: The resource to process and validate
155
+ # @param configurator [MU::Config]: The overall deployment configurator of which this resource is a member
156
+ # @return [Boolean]: True if validation succeeded, False otherwise
157
+ def self.validateConfig(habitat, configurator)
158
+ ok = true
159
+ habitat['region'] ||= MU::Cloud::Azure.myRegion(habitat['credentials'])
160
+
161
+ ok
162
+ end
163
+
164
+ end
165
+ end
166
+ end
167
+ end
@@ -0,0 +1,205 @@
1
+ # Copyright:: Copyright (c) 2019 eGlobalTech, Inc., all rights reserved
2
+ #
3
+ # Licensed under the BSD-3 license (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License in the root of the project or at
6
+ #
7
+ # http://egt-labs.com/mu/LICENSE.html
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
+
15
+ module MU
16
+ class Cloud
17
+ class Azure
18
+ # A load balancer as configured in {MU::Config::BasketofKittens::loadbalancers}
19
+ class LoadBalancer < MU::Cloud::LoadBalancer
20
+
21
+ # Initialize this cloud resource object. Calling +super+ will invoke the initializer defined under {MU::Cloud}, which should set the attribtues listed in {MU::Cloud::PUBLIC_ATTRS} as well as applicable dependency shortcuts, like <tt>@vpc</tt>, for us.
22
+ # @param args [Hash]: Hash of named arguments passed via Ruby's double-splat
23
+ def initialize(**args)
24
+ super
25
+ @mu_name ||= @deploy.getResourceName(@config["name"])
26
+ end
27
+
28
+ # Called automatically by {MU::Deploy#createResources}
29
+ def create
30
+ create_update
31
+ end
32
+
33
+ # Called automatically by {MU::Deploy#createResources}
34
+ def groom
35
+ create_update
36
+
37
+ if cloud_desc.tags != @tags
38
+ tags_obj = MU::Cloud::Azure.network(:TagsObject).new
39
+ tags_obj.tags = @tags
40
+ MU.log "Updating tags on LoadBalancer #{@mu_name}", MU::NOTICE, details: @tags
41
+ MU::Cloud::Azure.network(credentials: @config['credentials']).load_balancers.update_tags(@resource_group, @mu_name, tags_obj)
42
+ end
43
+ end
44
+
45
+ # Return the metadata for this LoadBalancer
46
+ # @return [Hash]
47
+ def notify
48
+ end
49
+
50
+ # Register a Server node with an existing LoadBalancer.
51
+ #
52
+ # @param instance_id [String] A node to register.
53
+ # @param targetgroups [Array<String>] The target group(s) of which this node should be made a member. Not applicable to classic LoadBalancers. If not supplied, the node will be registered to all available target groups on this LoadBalancer.
54
+ def registerNode(instance_id, targetgroups: nil)
55
+ end
56
+
57
+ # Does this resource type exist as a global (cloud-wide) artifact, or
58
+ # is it localized to a region/zone?
59
+ # @return [Boolean]
60
+ def self.isGlobal?
61
+ false
62
+ end
63
+
64
+ # Denote whether this resource implementation is experiment, ready for
65
+ # testing, or ready for production use.
66
+ def self.quality
67
+ MU::Cloud::ALPHA
68
+ end
69
+
70
+ # Stub method. Azure resources are cleaned up by removing the parent
71
+ # resource group.
72
+ # @return [void]
73
+ def self.cleanup(**args)
74
+ end
75
+
76
+ # Cloud-specific configuration properties.
77
+ # @param config [MU::Config]: The calling MU::Config object
78
+ # @return [Array<Array,Hash>]: List of required fields, and json-schema Hash of cloud-specific configuration parameters for this resource
79
+ def self.schema(config)
80
+ toplevel_required = []
81
+ schema = {
82
+ # "named_ports" => {
83
+ # "type" => "array",
84
+ # "items" => {
85
+ # "type" => "object",
86
+ # "required" => ["name", "port"],
87
+ # "additionalProperties" => false,
88
+ # "description" => "A named network port for a Azure instance group, used for health checks and forwarding targets.",
89
+ # "properties" => {
90
+ # "name" => {
91
+ # "type" => "string"
92
+ # },
93
+ # "port" => {
94
+ # "type" => "integer"
95
+ # }
96
+ # }
97
+ # }
98
+ # }
99
+ }
100
+ [toplevel_required, schema]
101
+ end
102
+
103
+ # Cloud-specific pre-processing of {MU::Config::BasketofKittens::loadbalancers}, bare and unvalidated.
104
+ # @param lb [Hash]: The resource to process and validate
105
+ # @param configurator [MU::Config]: The overall deployment configurator of which this resource is a member
106
+ # @return [Boolean]: True if validation succeeded, False otherwise
107
+ def self.validateConfig(lb, configurator)
108
+ ok = true
109
+ lb['region'] ||= MU::Cloud::Azure.myRegion(lb['credentials'])
110
+
111
+ ok
112
+ end
113
+
114
+ # Locate and return cloud provider descriptors of this resource type
115
+ # which match the provided parameters, or all visible resources if no
116
+ # filters are specified. At minimum, implementations of +find+ must
117
+ # honor +credentials+ and +cloud_id+ arguments. We may optionally
118
+ # support other search methods, such as +tag_key+ and +tag_value+, or
119
+ # cloud-specific arguments like +project+. See also {MU::MommaCat.findStray}.
120
+ # @param args [Hash]: Hash of named arguments passed via Ruby's double-splat
121
+ # @return [Hash<String,OpenStruct>]: The cloud provider's complete descriptions of matching resources
122
+ def self.find(**args)
123
+ found = {}
124
+
125
+ # Azure resources are namedspaced by resource group. If we weren't
126
+ # told one, we may have to search all the ones we can see.
127
+ resource_groups = if args[:resource_group]
128
+ [args[:resource_group]]
129
+ elsif args[:cloud_id] and args[:cloud_id].is_a?(MU::Cloud::Azure::Id)
130
+ [args[:cloud_id].resource_group]
131
+ else
132
+ MU::Cloud::Azure.resources(credentials: args[:credentials]).resource_groups.list.map { |rg| rg.name }
133
+ end
134
+
135
+ if args[:cloud_id]
136
+ id_str = args[:cloud_id].is_a?(MU::Cloud::Azure::Id) ? args[:cloud_id].name : args[:cloud_id]
137
+ resource_groups.each { |rg|
138
+ resp = MU::Cloud::Azure.network(credentials: args[:credentials]).load_balancers.get(rg, id_str)
139
+ found[Id.new(resp.id)] = resp if resp
140
+ }
141
+ else
142
+ if args[:resource_group]
143
+ MU::Cloud::Azure.network(credentials: args[:credentials]).load_balancers.list(args[:resource_group]).each { |lb|
144
+ found[Id.new(lb.id)] = lb
145
+ }
146
+ else
147
+ MU::Cloud::Azure.network(credentials: args[:credentials]).load_balancers.list_all.each { |net|
148
+ found[Id.new(lb.id)] = lb
149
+ }
150
+ end
151
+ end
152
+
153
+ found
154
+ end
155
+
156
+ private
157
+
158
+ def create_update
159
+ @config['region'] ||= MU::Cloud::Azure.myRegion(@config['credentials'])
160
+
161
+ # XXX expose that second argument to BoK language to use a pre-existing resource
162
+ ip_obj = MU::Cloud::Azure.fetchPublicIP(@resource_group, @mu_name, credentials: @config['credentials'], region: @config['region'], tags: @tags)
163
+
164
+ # XXX can have multiples of these
165
+ front_obj = MU::Cloud::Azure.network(:FrontendIPConfiguration).new
166
+ front_obj.name = @mu_name
167
+ front_obj.public_ipaddress = ip_obj
168
+ front_obj.private_ipallocation_method = "Dynamic"
169
+
170
+ lb_obj = MU::Cloud::Azure.network(:LoadBalancer).new
171
+ lb_obj.frontend_ipconfigurations = [front_obj]
172
+ lb_obj.location = @config['region']
173
+ lb_obj.tags = @tags
174
+
175
+
176
+ need_apply = false
177
+ ext_lb = MU::Cloud::Azure.network(credentials: @config['credentials']).load_balancers.get(
178
+ @resource_group,
179
+ @mu_name
180
+ )
181
+ if ext_lb
182
+ pp ext_lb
183
+ @cloud_id = MU::Cloud::Azure::Id.new(ext_lb.id)
184
+ end
185
+ #MU.log "WHAT I GOT", MU::NOTICE, details: ext_lb
186
+ #MU.log "WHAT I NEED", MU::NOTICE, details: @config
187
+
188
+ if !ext_lb
189
+ MU.log "Creating Load Balancer #{@mu_name} in #{@config['region']}", details: lb_obj
190
+ need_apply = true
191
+ elsif ext_lb.frontend_ipconfigurations != lb_obj.frontend_ipconfigurations
192
+ MU.log "Updating Network Security Group #{@mu_name} in #{@config['region']}", MU::NOTICE, details: lb_obj
193
+ need_apply = true
194
+ end
195
+
196
+ if need_apply
197
+ resp = MU::Cloud::Azure.network(credentials: @config['credentials']).load_balancers.create_or_update(@resource_group, @mu_name, lb_obj)
198
+ @cloud_id = Id.new(resp.id)
199
+ end
200
+ end
201
+
202
+ end
203
+ end
204
+ end
205
+ end
@@ -0,0 +1,211 @@
1
+ # Copyright:: Copyright (c) 2018 eGlobalTech, Inc., all rights reserved
2
+ #
3
+ # Licensed under the BSD-3 license (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License in the root of the project or at
6
+ #
7
+ # http://egt-labs.com/mu/LICENSE.html
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
+
15
+ module MU
16
+ class Cloud
17
+ class Azure
18
+ # A user as configured in {MU::Config::BasketofKittens::roles}
19
+ class Role < MU::Cloud::Role
20
+
21
+ # Initialize this cloud resource object. Calling +super+ will invoke the initializer defined under {MU::Cloud}, which should set the attribtues listed in {MU::Cloud::PUBLIC_ATTRS} as well as applicable dependency shortcuts, like <tt>@vpc</tt>, for us.
22
+ # @param args [Hash]: Hash of named arguments passed via Ruby's double-splat
23
+ def initialize(**args)
24
+ super
25
+ if !mu_name.nil?
26
+ @mu_name = mu_name
27
+ @cloud_id = Id.new(cloud_desc.id) if @cloud_id
28
+ else
29
+ @mu_name ||= @deploy.getResourceName(@config["name"], max_length: 31)
30
+ end
31
+
32
+ end
33
+
34
+ # Called automatically by {MU::Deploy#createResources}
35
+ def create
36
+ end
37
+
38
+ # Called automatically by {MU::Deploy#createResources}
39
+ def groom
40
+ end
41
+
42
+ # Return the metadata for this user configuration
43
+ # @return [Hash]
44
+ def notify
45
+ description = MU.structToHash(cloud_desc)
46
+ if description
47
+ description.delete(:etag)
48
+ return description
49
+ end
50
+ {
51
+ }
52
+ end
53
+
54
+ # Does this resource type exist as a global (cloud-wide) artifact, or
55
+ # is it localized to a region/zone?
56
+ # @return [Boolean]
57
+ def self.isGlobal?
58
+ false
59
+ end
60
+
61
+ # Denote whether this resource implementation is experiment, ready for
62
+ # testing, or ready for production use.
63
+ def self.quality
64
+ MU::Cloud::ALPHA
65
+ end
66
+
67
+ # Assign this role object to a given principal (create a RoleAssignment)
68
+ # @param principal [MU::Cloud::Azure::Id]
69
+ def assignTo(principal)
70
+ MU::Cloud::Azure::Role.assignTo(principal_id, role_id: @cloud_id)
71
+ end
72
+
73
+ # Assign a role to a particular principal (create a RoleAssignment). We
74
+ # support multiple ways of referring to a role
75
+ # @param principal [MU::Cloud::Azure::Id]
76
+ def self.assignTo(principal, role_name: nil, role_id: nil, credentials: nil)
77
+ # XXX subscription might need extraction
78
+ if !role_name and !role_id
79
+ raise MuError, "Role.assignTo requries one of role_name, role_id, or permissions in order to look up roles for association"
80
+
81
+ end
82
+
83
+ existing = MU::Cloud::Azure.authorization(credentials: credentials).role_assignments.list()
84
+
85
+ roles = MU::Cloud::Azure::Role.find(cloud_id: role_id, role_name: role_name, credentials: credentials)
86
+ role = roles.values.first # XXX handle failures and multiples
87
+
88
+ assign_obj = MU::Cloud::Azure.authorization(:RoleAssignmentCreateParameters, model_version: "V2018_09_01_preview").new
89
+ assign_obj.principal_id = principal
90
+ assign_obj.principal_type = "ServicePrincipal"
91
+ assign_obj.role_definition_id = role.id
92
+
93
+ # TODO this should defintiely be configurable, and for most Mu
94
+ # deploy resources will be scoped to the resource group level
95
+ scope = "/subscriptions/"+MU::Cloud::Azure.default_subscription(credentials)
96
+
97
+ role_name = begin
98
+ role.role_name
99
+ rescue NoMethodError
100
+ role.properties.role_name
101
+ end
102
+
103
+ used_ids = []
104
+ existing.each { |ext_assignment|
105
+ used_ids << ext_assignment.name
106
+ if ext_assignment.role_definition_id == role.id and
107
+ ext_assignment.scope == scope and
108
+ ext_assignment.principal_id == principal
109
+ return
110
+ end
111
+ }
112
+
113
+ guid = nil
114
+ begin
115
+ guid = MU::Cloud::Azure.genGUID
116
+ end while used_ids.include?(guid)
117
+
118
+ MU.log "Assigning role '#{role_name}' to principal #{principal}", details: assign_obj
119
+ MU::Cloud::Azure.authorization(credentials: credentials).role_assignments.create(
120
+ scope,
121
+ guid,
122
+ assign_obj
123
+ )
124
+ end
125
+
126
+ @@role_list_cache = {}
127
+ @@role_list_semaphore = Mutex.new
128
+
129
+ # Locate and return cloud provider descriptors of this resource type
130
+ # which match the provided parameters, or all visible resources if no
131
+ # filters are specified. At minimum, implementations of +find+ must
132
+ # honor +credentials+ and +cloud_id+ arguments. We may optionally
133
+ # support other search methods, such as +tag_key+ and +tag_value+, or
134
+ # cloud-specific arguments like +project+. See also {MU::MommaCat.findStray}.
135
+ # @param args [Hash]: Hash of named arguments passed via Ruby's double-splat
136
+ # @return [Hash<String,OpenStruct>]: The cloud provider's complete descriptions of matching resources
137
+ def self.find(**args)
138
+ found = {}
139
+
140
+ sub_id = MU::Cloud::Azure.default_subscription(args[:credentials])
141
+ scope = "/subscriptions/"+sub_id
142
+
143
+ if args[:cloud_id]
144
+ id_str = args[:cloud_id].is_a?(MU::Cloud::Azure::Id) ? args[:cloud_id].name : args[:cloud_id]
145
+ begin
146
+ resp = MU::Cloud::Azure.authorization(credentials: args[:credentials]).role_definitions.get(scope, id_str)
147
+ found[Id.new(resp.id)] = resp
148
+ rescue MsRestAzure::AzureOperationError => e
149
+ # this is fine, we're doing a blind search after all
150
+ end
151
+ else
152
+ @@role_list_semaphore.synchronize {
153
+ if !@@role_list_cache[scope]
154
+ @@role_list_cache[scope] = Hash[MU::Cloud::Azure.authorization(credentials: args[:credentials]).role_definitions.list(scope).map { |r| [Id.new(r.id), r] }]
155
+ end
156
+ }
157
+ if args[:role_name]
158
+ @@role_list_cache[scope].each_pair { |key, role|
159
+ begin
160
+ if role.role_name == args[:role_name]
161
+ found[Id.new(role.id)] = role
162
+ break
163
+ end
164
+ rescue NoMethodError
165
+ if role.properties.role_name == args[:role_name]
166
+ found[Id.new(role.id)] = role
167
+ break
168
+ end
169
+ end
170
+ }
171
+ else
172
+ found = @@role_list_cache[scope].dup
173
+ end
174
+ end
175
+
176
+ found
177
+ end
178
+
179
+ # Stub method. Azure resources are cleaned up by removing the parent
180
+ # resource group.
181
+ # @return [void]
182
+ def self.cleanup(**args)
183
+ end
184
+
185
+ # Cloud-specific configuration properties.
186
+ # @param config [MU::Config]: The calling MU::Config object
187
+ # @return [Array<Array,Hash>]: List of required fields, and json-schema Hash of cloud-specific configuration parameters for this resource
188
+ def self.schema(config)
189
+ toplevel_required = []
190
+ schema = {
191
+ }
192
+ [toplevel_required, schema]
193
+ end
194
+
195
+ # Cloud-specific pre-processing of {MU::Config::BasketofKittens::roles}, bare and unvalidated.
196
+ # @param role [Hash]: The resource to process and validate
197
+ # @param configurator [MU::Config]: The overall deployment configurator of which this resource is a member
198
+ # @return [Boolean]: True if validation succeeded, False otherwise
199
+ def self.validateConfig(role, configurator)
200
+ ok = true
201
+ role['region'] ||= MU::Cloud::Azure.myRegion(role['credentials'])
202
+
203
+ ok
204
+ end
205
+
206
+ private
207
+
208
+ end
209
+ end
210
+ end
211
+ end