# -*- encoding: utf-8 -*- # # Author:: Ryan Hass () # # Copyright (C) 2015, Ryan Hass # # 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 'scaleway' require 'kitchen' module Kitchen module Driver # Scaleway Driver for Kitchen. # # @author Ryan Hass class Scaleway < Kitchen::Driver::SSHBase default_config :username, 'root' default_config :port, '22' default_config(:image) { |driver| driver.default_image.id } default_config(:server_name) { |driver| driver.default_name } default_config :scaleway_org do ENV['SCALEWAY_ORG_TOKEN'] end default_config :scaleway_access_token do ENV['SCALEWAY_ACCESS_TOKEN'] end required_config :scaleway_org required_config :scaleway_access_token def create(state) client server = create_server state[:server_id] = server.id info("Scaleway instance <#{state[:server_id]}> created.") loop do info("Waiting for Public IP to become available...") sleep 8 begin instance = ::Scaleway::Server.find(state[:server_id]) rescue ::Scaleway::NotFound info('instance still not ready.') end break if instance && ! instance.public_ip.nil? end instance ||= ::Scaleway::Server.find(state[:server_id]) state[:hostname] = instance.public_ip[:address] wait_for_sshd(state[:hostname]); print "(ssh ready)\n" end def destroy(state) client return if state[:server_id].nil? loop do begin instance = ::Scaleway::Server.find(state[:server_id]) break if !instance if instance && instance.state != 'pending' volume = ::Scaleway::Server.find(state[:server_id]).image[:id] ::Scaleway::Server.terminate(state[:server_id]) ::Scaleway::Image.destroy(volume) break end rescue ::Scaleway::APIError break if !instance if instance && instance.state == 'stopped' ::Scaleway::Server.destroy(state[:server_id]) ::Scaleway::Image.destroy(state[:server_id].image[:id]) raise ::Kitchen::Error end rescue ::Scaleway::NotFound instance = false end end info("Scaleway instance <#{state[:server_id]}> destroyed.") state.delete(:server_id) state.delete(:hostname) end def default_image client ::Scaleway::Image.find_by_name( platform_to_slug_mapping.fetch( instance.platform.name, instance.platform.name ) ) end # Generate what should be a unique server name up to 63 total chars # Base name: 15 # Username: 15 # Hostname: 23 # Random string: 7 # Separators: 3 # ================ # Total: 63 def default_name [ @instance.name.gsub(/\W/, '')[0..14], Etc.getlogin.gsub(/\W/, '')[0..14], Socket.gethostname.gsub(/\W/, '')[0..22], Array.new(7) { rand(36).to_s(36) }.join ].join('-').gsub(/_/, '-') end def client ::Scaleway.organization = config[:scaleway_org] ::Scaleway.token = config[:scaleway_access_token] end def create_server client instance = ::Scaleway::Server.create( { name: config[:server_name], image: config[:image] } ) ::Scaleway::Server.power_on(instance.id) instance end def platform_to_slug_mapping { 'debian-7.0' => 'Debian Wheezy (7.8)', 'debian-70' => 'Debian Wheezy (7.8)', 'debian-78' => 'Debian Wheezy (7.8)', 'debian-8.1' => 'Debian Jessie (8.1)', 'debian-81' => 'Debian Jessie (8.1)', 'fedora-22' => 'Fedora 22', 'opensuse-13.2' => 'openSUSE 13.2', 'opensuse-132' => 'openSUSE 13.2', 'ubuntu-12.04' => 'Ubuntu Precise (12.04)', 'ubuntu-1204' => 'Ubuntu Precise (12.04)', 'ubuntu-14.04' => 'Ubuntu Trusty (14.04 LTS)', 'ubuntu-1404' => 'Ubuntu Trusty (14.04 LTS)', 'ubuntu-14.10' => 'Ubuntu Utopic (14.10 EOL)', 'ubuntu-1410' => 'Ubuntu Utopic (14.10 EOL)', 'ubuntu-15.04' => 'Ubuntu Vivid (15.04 latest)', 'ubuntu-1504' => 'Ubuntu Vivid (15.04 latest)' } end end end end