diff options
author | Tim Smith <tsmith84@gmail.com> | 2021-02-07 20:45:59 -0800 |
---|---|---|
committer | Tim Smith <tsmith84@gmail.com> | 2021-02-07 20:46:38 -0800 |
commit | 49f2cae7a02a132757a4d698ce329f170260ef2e (patch) | |
tree | 166da5f4201fcb095c529ca815ceac9b5f55614b | |
parent | 92aa163d2716972a72b22828e4c48665ed716c9d (diff) | |
download | ohai-49f2cae7a02a132757a4d698ce329f170260ef2e.tar.gz |
Add Alibaba cloud plugin
Detects Alibaba on Linux boxes and fetches metadata
Signed-off-by: Tim Smith <tsmith@chef.io>
-rw-r--r-- | lib/ohai/mixin/alibaba_metadata.rb | 87 | ||||
-rw-r--r-- | lib/ohai/plugins/alibaba.rb | 72 |
2 files changed, 159 insertions, 0 deletions
diff --git a/lib/ohai/mixin/alibaba_metadata.rb b/lib/ohai/mixin/alibaba_metadata.rb new file mode 100644 index 00000000..ba14b7b2 --- /dev/null +++ b/lib/ohai/mixin/alibaba_metadata.rb @@ -0,0 +1,87 @@ +# frozen_string_literal: true +# +# Author:: Tim Smith (<tsmith@chef.io>) +# Copyright:: Copyright (c) Chef Software Inc. +# License:: Apache License, Version 2.0 +# +# 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. + +require "net/http" unless defined?(Net::HTTP) + +module Ohai + module Mixin + # + # This code parses the Alibaba Instance Metadata API to provide details + # of the running instance. + # + # As of 2021-02-07 there is only one API release so this removes the + # API parsing logic in the ec2 metadata mixin. If that changes we + # may want to merge these two codebases + # + module AlibabaMetadata + + ALI_METADATA_ADDR ||= "100.100.100.200" + + def http_get(uri) + conn = Net::HTTP.start(ALI_METADATA_ADDR) + conn.read_timeout = 6 + conn.keep_alive_timeout = 6 + conn.get("/2016-01-01/#{uri}", { "User-Agent" => "chef-ohai/#{Ohai::VERSION}" }) + end + + def fetch_metadata(id = "") + response = http_get(id) + return nil unless response.code == "200" + + if json?(response.body) + data = String(response.body) + parser = FFI_Yajl::Parser.new + parser.parse(data) + elsif response.body.include?("\n") + temp = {} + response.body.split("\n").each do |sub_attr| + temp[sanitize_key(sub_attr)] = fetch_metadata("#{id}#{sub_attr}") + end + temp + else + response.body + end + end + + # @param [String] data that might be JSON + # + # @return [Boolean] is the data JSON or not? + def json?(data) + data = String(data) + parser = FFI_Yajl::Parser.new + begin + parser.parse(data) + true + rescue FFI_Yajl::ParseError + false + end + end + + # @param data [String] + # + # @return [Boolean] is there a trailing /? + def has_trailing_slash?(data) + !!( data =~ %r{/$} ) + end + + def sanitize_key(key) + key.gsub(%r{\-|/}, "_") + end + end + end +end diff --git a/lib/ohai/plugins/alibaba.rb b/lib/ohai/plugins/alibaba.rb new file mode 100644 index 00000000..ac3c8088 --- /dev/null +++ b/lib/ohai/plugins/alibaba.rb @@ -0,0 +1,72 @@ +# frozen_string_literal: true +# +# Author:: Tim Smith (<tsmith@chef.io>) +# Copyright:: Copyright (c) Chef Software Inc. +# License:: Apache License, Version 2.0 +# +# 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. + +# How we detect Alibaba from easiest to hardest & least reliable +# 1. Ohai alibaba hint exists. This always works +# 2. DMI sys_vendor data mentions alibaba. + +Ohai.plugin(:Alibaba) do + require_relative "../mixin/alibaba_metadata" + require_relative "../mixin/http_helper" + + include Ohai::Mixin::AlibabaMetadata + include Ohai::Mixin::HttpHelper + + provides "alibaba" + + # look for alibaba string in dmi sys_vendor data within the sys tree. + # this works even if the system lacks dmidecode use by the Dmi plugin + # @return [Boolean] do we have Alibaba DMI data? + def has_ali_dmi? + if /Alibaba/.match?(file_val_if_exists("/sys/class/dmi/id/sys_vendor")) + logger.trace("Plugin Alibaba: has_ali_dmi? == true") + true + else + logger.trace("Plugin Alibaba: has_ali_dmi? == false") + false + end + end + + # return the contents of a file if the file exists + # @param path[String] abs path to the file + # @return [String] contents of the file if it exists + def file_val_if_exists(path) + if file_exist?(path) + file_read(path) + end + end + + # a single check that combines all the various detection methods for Alibaba + # @return [Boolean] Does the system appear to be on Alibaba + def looks_like_alibaba? + return true if hint?("alibaba") || has_ali_dmi? + end + + collect_data do + if looks_like_alibaba? + logger.trace("Plugin Alibaba: looks_like_alibaba? == true") + alibaba Mash.new + fetch_metadata.each do |k, v| + alibaba[k] = v + end + else + logger.trace("Plugin Alibaba: looks_like_alibaba? == false") + false + end + end +end |