diff options
author | Thom May <thom@may.lt> | 2018-02-27 13:23:38 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-02-27 13:23:38 +0000 |
commit | e5f74b4996a01c36212782accd336e4ddf512d3d (patch) | |
tree | d89e6feb2cf1d8aea577819fa86439a1a471ab1d | |
parent | d912c89946f9e550c1cd48bb7e10153b9fa94f6f (diff) | |
parent | 522f6a290465768887555d2a12cc8c022355351d (diff) | |
download | ohai-e5f74b4996a01c36212782accd336e4ddf512d3d.tar.gz |
Merge pull request #1124 from josqu4red/scaleway
Add scaleway plugin
-rw-r--r-- | lib/ohai/mixin/scaleway_metadata.rb | 46 | ||||
-rw-r--r-- | lib/ohai/plugins/scaleway.rb | 57 | ||||
-rw-r--r-- | spec/unit/plugins/scaleway_spec.rb | 90 |
3 files changed, 193 insertions, 0 deletions
diff --git a/lib/ohai/mixin/scaleway_metadata.rb b/lib/ohai/mixin/scaleway_metadata.rb new file mode 100644 index 00000000..280c5153 --- /dev/null +++ b/lib/ohai/mixin/scaleway_metadata.rb @@ -0,0 +1,46 @@ +# +# Author:: Jonathan Amiez (<jonathan.amiez@gmail.com>) +# 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" + +module Ohai + module Mixin + module ScalewayMetadata + + SCALEWAY_METADATA_ADDR = "169.254.42.42" unless defined?(SCALEWAY_METADATA_ADDR) + SCALEWAY_METADATA_URL = "/conf?format=json" unless defined?(SCALEWAY_METADATA_URL) + + def http_client + Net::HTTP.start(SCALEWAY_METADATA_ADDR).tap { |h| h.read_timeout = 6 } + end + + def fetch_metadata + uri = "#{SCALEWAY_METADATA_URL}" + response = http_client.get(uri) + case response.code + when "200" + parser = FFI_Yajl::Parser.new + parser.parse(response.body) + when "404" + Ohai::Log.debug("Mixin ScalewayMetadata: Encountered 404 response retrieving Scaleway metadata: #{uri} ; continuing.") + {} + else + raise "Mixin ScalewayMetadata: Encountered error retrieving Scaleway metadata (#{uri} returned #{response.code} response)" + end + end + end + end +end diff --git a/lib/ohai/plugins/scaleway.rb b/lib/ohai/plugins/scaleway.rb new file mode 100644 index 00000000..5cfd1079 --- /dev/null +++ b/lib/ohai/plugins/scaleway.rb @@ -0,0 +1,57 @@ +# +# Author:: Jonathan Amiez (<jonathan.amiez@gmail.com>) +# 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. + +Ohai.plugin(:Scaleway) do + require "ohai/mixin/scaleway_metadata" + require "ohai/mixin/http_helper" + + include Ohai::Mixin::ScalewayMetadata + include Ohai::Mixin::HttpHelper + + provides "scaleway" + + # looks for `scaleway` keyword in kernel command line + # @return [Boolean] do we have the keyword or not? + def has_scaleway_cmdline? + if ::File.read("/proc/cmdline") =~ /scaleway/ + Ohai::Log.debug("Plugin Scaleway: has_scaleway_cmdline? == true") + return true + end + Ohai::Log.debug("Plugin Scaleway: has_scaleway_cmdline? == false") + false + end + + # a single check that combines all the various detection methods for Scaleway + # @return [Boolean] Does the system appear to be on Scaleway + def looks_like_scaleway? + return true if hint?("scaleway") + return true if has_scaleway_cmdline? && can_socket_connect?(Ohai::Mixin::ScalewayMetadata::SCALEWAY_METADATA_ADDR, 80) + false + end + + collect_data do + if looks_like_scaleway? + Ohai::Log.debug("Plugin Scaleway: looks_like_scaleway? == true") + scaleway Mash.new + fetch_metadata.each do |k, v| + scaleway[k] = v + end + else + Ohai::Log.debug("Plugin Scaleway: No hints present for and doesn't look like scaleway") + false + end + end +end diff --git a/spec/unit/plugins/scaleway_spec.rb b/spec/unit/plugins/scaleway_spec.rb new file mode 100644 index 00000000..8352e9f7 --- /dev/null +++ b/spec/unit/plugins/scaleway_spec.rb @@ -0,0 +1,90 @@ +# +# Author:: Jonathan Amiez (<jonathan.amiez@gmail.com>) +# 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 "spec_helper" + +describe Ohai::System, "plugin scaleway" do + let(:plugin) { get_plugin("scaleway") } + + before(:each) do + allow(plugin).to receive(:hint?).with("scaleway").and_return(false) + end + + shared_examples_for "!scaleway" do + it "should NOT attempt to fetch the scaleway metadata" do + expect(plugin).not_to receive(:http_client) + expect(plugin[:scaleway]).to be_nil + plugin.run + end + end + + shared_examples_for "scaleway" do + before(:each) do + @http_client = double("Net::HTTP client") + allow(plugin).to receive(:http_client).and_return(@http_client) + allow(IO).to receive(:select).and_return([[], [1], []]) + t = double("connection") + allow(t).to receive(:connect_nonblock).and_raise(Errno::EINPROGRESS) + allow(Socket).to receive(:new).and_return(t) + allow(Socket).to receive(:pack_sockaddr_in).and_return(nil) + end + + let(:body) do + '{"tags": [], "state_detail": "booted", "public_ip": {"dynamic": false, "id": "7564c721-a128-444e-9c95-0754a7616482", "address": "5.1.9.3"}, "ssh_public_keys": [{"key": "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAgEA5qK2s41yyrNpaXXiQtb/1ADaVHVZZp9rYEtG6Dz7trOPtxkxNsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/j2C+NAzo6TZCLTbJjBf89ieazqVqhY/dMNLDJINY2Ss2ytgyiJm9bp5bYcZz441czijBlmY/qmI0cFCVOJoDq6X9Lmn/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee+hmLFaTE3FeMr1hmeZT2ChH6ruHi8m6m18SfW0fl2fS8zG4yB+WE2IawdsoZmtgtY/Re3CpvhYP9S/JxpUedl+zzzzzzzzzzzzzzzzz5+YONBAt/PWMelXThfMukbwykto6IXmsX2qflBPsRVrWe0D7vt48loVScHDv5D05ZwqWY9rizFqCx3Y8xCLr6649ieonnnjHEsSOBREU507eXVJL6njHard+s+vuTC4bNH5LiP2INQS+9MaT37/l8WzIAL3U+hvcj95HS8KfATX+7XWa54bGJgeOnPle8ojwp1ssl7ddh2yFJozgk2CkUEyE4f1lmEX2YFJGoEoaW0QC2j0nNYiLs37yHG0h84AOgjoIAJo1rxpBAGGJOgFTkgnSdHjtDZsC9WjJYeu/QpxQ7Lf2Z+FCKoypfnZz/F10/z6nxnkZ3IKKM=", "fingerprint": "4096 4c:71:db:64:cd:24:da:4a:fa:5f:9e:70:af:ea:40:6e (no comment) (RSA)"}], "private_ip": "10.8.23.7", "timezone": "UTC", "id": "77fab916-e7ff-44c6-a025-ae08837b4c4f", "extra_networks": [], "name": "sample-hostname", "hostname": "sample-hostname", "bootscript": {"kernel": "http://169.254.42.24/kernel/x86_64-4.9.20-std-1/vmlinuz-4.9.20-std-1", "title": "x86_64 4.9.20 std #1 (longterm/latest)", "default": false, "dtb": "", "public": false, "initrd": "http://169.254.42.24/initrd/initrd-Linux-x86_64-v3.12.7.gz", "bootcmdargs": "LINUX_COMMON scaleway boot=local", "architecture": "x86_64", "organization": "11111110-1112-4112-8112-111111111116", "id": "855f21ba-e7f9-421d-91b0-976a6ad59910"}, "location": {"platform_id": "21", "hypervisor_id": "518", "node_id": "4", "cluster_id": "82", "zone_id": "par1"}, "volumes": {"0": {"name": "x86_64-debian-stretch-2017-06-29_10:17", "modification_date": "2018-01-26T10:22:28.268074+00:00", "export_uri": "device://dev/vda", "volume_type": "l_ssd", "creation_date": "2018-01-26T10:22:28.268074+00:00", "organization": "90f39224-d0a2-4771-a2f0-1036a9402b97", "server": {"id": "77fab916-e7ff-44c6-a024-ae08837b4c4f", "name": "sample-hostname"}, "id": "3be53d4d-93d7-4430-a513-61cb4410624b", "size": 50000000000}}, "ipv6": null, "organization": "89f39224-d0a2-4771-a2f0-1036a9402b97", "commercial_type": "VC1S"}' + end + + it "should fetch and properly parse json metadata" do + expect(@http_client).to receive(:get). + with("/conf?format=json"). + and_return(double("Net::HTTP Response", :body => body, :code => "200")) + plugin.run + + expect(plugin[:scaleway]).not_to be_nil + expect(plugin[:scaleway]["id"]).to eq("77fab916-e7ff-44c6-a025-ae08837b4c4f") + expect(plugin[:scaleway]["hostname"]).to eq("sample-hostname") + end + + it "should complete the run despite unavailable metadata" do + expect(@http_client).to receive(:get). + with("/conf?format=json"). + and_return(double("Net::HTTP Response", :body => "", :code => "404")) + plugin.run + + expect(plugin[:scaleway]).to be_nil + end + end + + describe "without hint or cmdline" do + it_should_behave_like "!scaleway" + end + + describe "with scaleway hint file" do + it_should_behave_like "scaleway" + + before(:each) do + allow(plugin).to receive(:hint?).with("scaleway").and_return(true) + end + end + + describe "with scaleway cmdline" do + it_should_behave_like "scaleway" + + before(:each) do + allow(File).to receive(:read).with("/proc/cmdline").and_return("initrd=initrd showopts console=ttyS0,115200 nousb vga=0 root=/dev/vda scaleway boot=local") + end + end +end |