PageRenderTime 46ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/ohai/plugins/cloud_v2.rb

https://github.com/wistia/ohai
Ruby | 289 lines | 156 code | 43 blank | 90 comment | 24 complexity | 22d290ea161ccb01b5cfb2d8ca86295b MD5 | raw file
Possible License(s): Apache-2.0
  1. #
  2. # Author:: Cary Penniman (<cary@rightscale.com>)
  3. # License:: Apache License, Version 2.0
  4. #
  5. # Licensed under the Apache License, Version 2.0 (the "License");
  6. # you may not use this file except in compliance with the License.
  7. # You may obtain a copy of the License at
  8. #
  9. # http://www.apache.org/licenses/LICENSE-2.0
  10. #
  11. # Unless required by applicable law or agreed to in writing, software
  12. # distributed under the License is distributed on an "AS IS" BASIS,
  13. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. # See the License for the specific language governing permissions and
  15. # limitations under the License.
  16. Ohai.plugin(:CloudV2) do
  17. provides "cloud_v2"
  18. depends "ec2"
  19. depends "gce"
  20. depends "rackspace"
  21. depends "eucalyptus"
  22. depends "linode"
  23. depends "openstack"
  24. depends "azure"
  25. # Class to help enforce the interface exposed to node[:cloud] (OHAI-542)
  26. #
  27. # cloud[:provider] - (String) the cloud provider the VM is running on.
  28. #
  29. # cloud[:public_hostname] - (String) a fully qualified hostname
  30. # cloud[:local_hostname] - (String) a hostname resolvable on the internal (private) network
  31. #
  32. # cloud[:public_ipv4_addrs] - (Array) a list of all publicly accessible IPv4 addresses
  33. # cloud[:local_ipv4_addrs] - (Array) a list of all private IPv4 addresses
  34. # cloud[:public_ipv4] - (String) the first public IPv4 address detected
  35. # cloud[:local_ipv4] - (String) the first private IPv4 address detected
  36. #
  37. # cloud[:public_ipv6_addrs] - (Array) a list of all publicly accessible IPv6 addresses
  38. # cloud[:local_ipv6_addrs] - (Array) a list of all private IPv6 addresses
  39. # cloud[:public_ipv6] - (String) the first public IPv6 address detected
  40. # cloud[:local_ipv6] - (String) the first private IPv6 address detected
  41. #
  42. class CloudAttrs
  43. attr_writer :provider, :public_hostname, :local_hostname
  44. def initialize
  45. @cloud = Mash.new
  46. end
  47. def add_ipv4_addr(ip, accessibility)
  48. return if ip.nil? # just skip if ip is nil
  49. ipaddr = validate_ip_addr(ip, :ipv4)
  50. case accessibility
  51. when :public
  52. @cloud[:public_ipv4_addrs] ||= Array.new
  53. @cloud[:public_ipv4_addrs] << ipaddr.to_s
  54. when :private
  55. @cloud[:local_ipv4_addrs] ||= Array.new
  56. @cloud[:local_ipv4_addrs] << ipaddr.to_s
  57. else
  58. raise "ERROR: in valid accessibility param of '#{accessibility}'. must be :public or :private."
  59. end
  60. end
  61. def add_ipv6_addr(ip, accessibility)
  62. return if ip.nil? # just skip if ip is nil
  63. ipaddr = validate_ip_addr(ip, :ipv6)
  64. raise "ERROR: invalid ipv6 address of '#{ip}' detected. " unless ipaddr.ipv6?
  65. case accessibility
  66. when :public
  67. @cloud[:public_ipv6_addrs] ||= Array.new
  68. @cloud[:public_ipv6_addrs] << ipaddr.to_s
  69. when :private
  70. @cloud[:local_ipv6_addrs] ||= Array.new
  71. @cloud[:local_ipv6_addrs] << ipaddr.to_s
  72. else
  73. raise "ERROR: in valid accessibility param of '#{accessibility}'. must be :public or :private."
  74. end
  75. end
  76. def cloud_mash
  77. @cloud[:provider] = @provider if @provider
  78. @cloud[:public_hostname] = @public_hostname if @public_hostname
  79. @cloud[:local_hostname] = @local_hostname if @local_hostname
  80. @cloud[:public_ipv4] = @cloud[:public_ipv4_addrs][0] if @cloud[:public_ipv4_addrs]
  81. @cloud[:local_ipv4] = @cloud[:local_ipv4_addrs][0] if @cloud[:local_ipv4_addrs]
  82. @cloud[:public_ipv6] = @cloud[:public_ipv6_addrs][0] if @cloud[:public_ipv6_addrs]
  83. @cloud[:local_ipv6] = @cloud[:local_ipv6_addrs][0] if @cloud[:local_ipv6_addrs]
  84. # if empty, return nil
  85. (@cloud.empty?) ? nil : @cloud
  86. end
  87. private
  88. def validate_ip_addr(ip, address_family = :ipv4)
  89. ipaddr = ""
  90. begin
  91. ipaddr = IPAddr.new(ip)
  92. raise ArgumentError, "not valid #{address_family} address" unless (address_family == :ipv4) ? ipaddr.ipv4? : ipaddr.ipv6?
  93. rescue ArgumentError => e
  94. raise "ERROR: the ohai 'cloud' plugin failed with an IP address of '#{ip}' : #{e.message}"
  95. end
  96. ipaddr
  97. end
  98. end
  99. #---------------------------------------
  100. # Google Compute Engine (gce)
  101. #--------------------------------------
  102. def on_gce?
  103. gce != nil
  104. end
  105. def get_gce_values
  106. public_ips = gce['instance']['networkInterfaces'].collect do |interface|
  107. if interface.has_key?('accessConfigs')
  108. interface['accessConfigs'].collect{|ac| ac['externalIp']}
  109. end
  110. end.flatten.compact
  111. private_ips = gce['instance']['networkInterfaces'].collect do |interface|
  112. interface['ip']
  113. end.compact
  114. public_ips.each { |ipaddr| @cloud_attr_obj.add_ipv4_addr(ipaddr, :public) }
  115. private_ips.each { |ipaddr| @cloud_attr_obj.add_ipv4_addr(ipaddr, :private) }
  116. @cloud_attr_obj.local_hostname = gce['instance']['hostname']
  117. @cloud_attr_obj.provider = "gce"
  118. end
  119. # ----------------------------------------
  120. # ec2
  121. # ----------------------------------------
  122. # Is current cloud ec2?
  123. #
  124. # === Return
  125. # true:: If ec2 Hash is defined
  126. # false:: Otherwise
  127. def on_ec2?
  128. ec2 != nil
  129. end
  130. # Fill cloud hash with ec2 values
  131. def get_ec2_values
  132. @cloud_attr_obj.add_ipv4_addr(ec2['public_ipv4'], :public)
  133. @cloud_attr_obj.add_ipv4_addr(ec2['local_ipv4'], :private)
  134. @cloud_attr_obj.public_hostname = ec2['public_hostname']
  135. @cloud_attr_obj.local_hostname = ec2['local_hostname']
  136. @cloud_attr_obj.provider = "ec2"
  137. end
  138. # ----------------------------------------
  139. # rackspace
  140. # ----------------------------------------
  141. # Is current cloud rackspace?
  142. #
  143. # === Return
  144. # true:: If rackspace Hash is defined
  145. # false:: Otherwise
  146. def on_rackspace?
  147. rackspace != nil
  148. end
  149. # Fill cloud hash with rackspace values
  150. def get_rackspace_values
  151. @cloud_attr_obj.add_ipv4_addr(rackspace['public_ipv4'], :public)
  152. @cloud_attr_obj.add_ipv4_addr(rackspace['local_ipv4'], :private)
  153. @cloud_attr_obj.add_ipv6_addr(rackspace['public_ipv6'], :public)
  154. @cloud_attr_obj.add_ipv6_addr(rackspace['local_ipv6'], :private)
  155. @cloud_attr_obj.public_hostname = rackspace['public_hostname']
  156. @cloud_attr_obj.local_hostname = rackspace['local_hostname']
  157. @cloud_attr_obj.provider = "rackspace"
  158. end
  159. # ----------------------------------------
  160. # linode
  161. # ----------------------------------------
  162. # Is current cloud linode?
  163. #
  164. # === Return
  165. # true:: If linode Hash is defined
  166. # false:: Otherwise
  167. def on_linode?
  168. linode != nil
  169. end
  170. # Fill cloud hash with linode values
  171. def get_linode_values
  172. @cloud_attr_obj.add_ipv4_addr(linode['public_ip'], :public)
  173. @cloud_attr_obj.add_ipv4_addr(linode['private_ip'], :private)
  174. @cloud_attr_obj.public_hostname = linode['public_hostname']
  175. @cloud_attr_obj.local_hostname = linode['local_hostname']
  176. @cloud_attr_obj.provider = "linode"
  177. end
  178. # ----------------------------------------
  179. # eucalyptus
  180. # ----------------------------------------
  181. # Is current cloud eucalyptus?
  182. #
  183. # === Return
  184. # true:: If eucalyptus Hash is defined
  185. # false:: Otherwise
  186. def on_eucalyptus?
  187. eucalyptus != nil
  188. end
  189. def get_eucalyptus_values
  190. @cloud_attr_obj.add_ipv4_addr(eucalyptus['public_ipv4'], :public)
  191. @cloud_attr_obj.add_ipv4_addr(eucalyptus['local_ipv4'], :private)
  192. @cloud_attr_obj.public_hostname = eucalyptus['public_hostname']
  193. @cloud_attr_obj.local_hostname = eucalyptus['local_hostname']
  194. @cloud_attr_obj.provider = "eucalyptus"
  195. end
  196. # ----------------------------------------
  197. # openstack
  198. # ----------------------------------------
  199. # Is current cloud openstack-based?
  200. #
  201. # === Return
  202. # true:: If openstack Hash is defined
  203. # false:: Otherwise
  204. def on_openstack?
  205. openstack != nil
  206. end
  207. # Fill cloud hash with openstack values
  208. def get_openstack_values
  209. @cloud_attr_obj.add_ipv4_addr(openstack['public_ipv4'], :public)
  210. @cloud_attr_obj.add_ipv4_addr(openstack['local_ipv4'], :private)
  211. @cloud_attr_obj.public_hostname = openstack['public_hostname']
  212. @cloud_attr_obj.local_hostname = openstack['local_hostname']
  213. @cloud_attr_obj.provider = "openstack"
  214. end
  215. # ----------------------------------------
  216. # azure
  217. # ----------------------------------------
  218. # Is current cloud azure?
  219. #
  220. # === Return
  221. # true:: If azure Hash is defined
  222. # false:: Otherwise
  223. def on_azure?
  224. azure != nil
  225. end
  226. # Fill cloud hash with azure values
  227. def get_azure_values
  228. @cloud_attr_obj.add_ipv4_addr(azure['public_ip'], :public)
  229. @cloud_attr_obj.add_ipv4_addr(azure['private_ip'], :private)
  230. @cloud_attr_obj.public_hostname = azure['public_fqdn']
  231. @cloud_attr_obj.provider = "azure"
  232. end
  233. collect_data do
  234. require "ipaddr"
  235. @cloud_attr_obj = CloudAttrs.new()
  236. get_gce_values if on_gce?
  237. get_ec2_values if on_ec2?
  238. get_rackspace_values if on_rackspace?
  239. get_linode_values if on_linode?
  240. get_eucalyptus_values if on_eucalyptus?
  241. get_openstack_values if on_openstack?
  242. get_azure_values if on_azure?
  243. # set node[:cloud] hash here
  244. cloud_v2 @cloud_attr_obj.cloud_mash
  245. end
  246. end