warthog 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,31 @@
1
+ /*
2
+ * Copyright (c) 2012 by Evernote Corporation, All rights reserved.
3
+ *
4
+ * Use of the source code and binary libraries included in this package
5
+ * is permitted under the following terms:
6
+ *
7
+ * Redistribution and use in source and binary forms, with or without
8
+ * modification, are permitted provided that the following conditions
9
+ * are met:
10
+ *
11
+ * 1. Redistributions of source code must retain the above copyright
12
+ * notice, this list of conditions and the following disclaimer.
13
+ * 2. Redistributions in binary form must reproduce the above copyright
14
+ * notice, this list of conditions and the following disclaimer in the
15
+ * documentation and/or other materials provided with the distribution.
16
+ *
17
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+ *
28
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
29
+ * not use this file except in compliance with the License. You may obtain a
30
+ * copy of the License at http://www.apache.org/licenses/LICENSE-2.0
31
+ */
File without changes
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ lib = File.expand_path(File.dirname(__FILE__) + '/../lib')
4
+ $LOAD_PATH.unshift(lib) if File.directory?(lib) && !$LOAD_PATH.include?(lib)
5
+
6
+ require 'rubygems'
7
+ require 'warthog'
8
+ require 'warthog/cli'
9
+
10
+ module Warthog
11
+
12
+ ID = File.basename($PROGRAM_NAME).to_sym
13
+
14
+ app = CLI::CLI.new(ARGV)
15
+ app.run
16
+
17
+ end
@@ -0,0 +1,3 @@
1
+ module Warthog
2
+
3
+ end
@@ -0,0 +1,84 @@
1
+ require 'httparty'
2
+
3
+ module Warthog; module A10
4
+
5
+ class AXDevice
6
+
7
+ class AuthenticationError < StandardError; end
8
+ class HTTPError < StandardError; end
9
+ class AXapiError < StandardError; end
10
+
11
+ include HTTParty
12
+
13
+ API_VERSIONS = %w(V2)
14
+
15
+ def initialize(hostname,username,password,options={})
16
+ @hostname = hostname
17
+ @session_id = nil
18
+ @api_version = nil
19
+
20
+ axapi :authenticate, :username => username, :password => password
21
+ raise StandardError, "unable to obtain session id" unless @session_id
22
+ end
23
+
24
+ def slb_service_group_all
25
+ output = ''
26
+ service_group_list = axapi 'slb.service_group.getAll'
27
+ service_group_list['response']['service_group_list']['service_group'].each do |service_group|
28
+ name = service_group['name']
29
+ service_group['member_list']['member'].each do |member|
30
+ output << "%-16s %12s:%-5s %s %s %s\n" % [name,member['server'],member['port'],member['template'],member['priority'],member['status']] if Hash === member
31
+ end
32
+ end
33
+ output
34
+ end
35
+
36
+ def slb_service_group_search(name)
37
+ output = ''
38
+ service_group = axapi 'slb.service_group.search', :name => name
39
+ service_group['response']['service_group']['member_list']['member'].each do |member|
40
+ output << "%-16s %12s:%-5s %s %s %s\n" % [name,member['server'],member['port'],member['template'],member['priority'],member['status']]
41
+ end
42
+ output
43
+ end
44
+
45
+ protected
46
+
47
+ def axapi(method,paramvalues={})
48
+ if @session_id and @api_version
49
+ uri = "https://#@hostname/services/rest/#@api_version/?session_id=#@session_id&method=#{method}"
50
+ paramvalues.each do |param,value|
51
+ uri << "&#{param}=#{value}"
52
+ end
53
+ r = self.class.get(uri)
54
+ if r.code == 200
55
+ if r['response']['status'] == 'ok'
56
+ return r
57
+ elsif r['response']['status'] == 'fail'
58
+ raise AXapiError, r['response']['error']['msg']
59
+ end
60
+ else
61
+ raise HTTPError, "HTTP code: #{r.code}"
62
+ end
63
+ else
64
+ API_VERSIONS.each do |api_version|
65
+ r = self.class.get("https://#@hostname/services/rest/#{api_version}/?method=#{method}&username=#{paramvalues[:username]}&password=#{paramvalues[:password]}")
66
+ if r.code == 200
67
+ if r['response']['status'] == 'ok'
68
+ @session_id = r['response']['session_id']
69
+ @api_version = api_version
70
+ elsif r['response']['status'] == 'fail'
71
+ next if r['response']['error']['code'] == '1004'
72
+ raise AuthenticationError, r['response']['error']['msg'] if r['response']['error']['code'] == '520486968'
73
+ end
74
+ else
75
+ raise HTTPError, "HTTP code: #{r.code}"
76
+ end
77
+ raise StandardError, "unable to obtain session id" unless @session_id
78
+ end
79
+ end
80
+ end
81
+
82
+ end
83
+
84
+ end end
@@ -0,0 +1,5 @@
1
+ require 'warthog/version'
2
+ module Warthog
3
+ ME = :warthog
4
+ ABOUT = "#{ME} v#{VERSION}\nhttps://github.com/evernote/ops-#{ME}\nCopyright (c) 2012 by Evernote Corporation\nLicensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)"
5
+ end
@@ -0,0 +1,103 @@
1
+ require 'optparse'
2
+ require 'etc'
3
+ require 'warthog'
4
+ require 'warthog/cli/action'
5
+ require 'warthog/a10/rest'
6
+ require 'warthog/version'
7
+ require 'warthog/about'
8
+
9
+ include Warthog::CLI::Action
10
+
11
+ module Warthog; module CLI
12
+
13
+ class CLI
14
+
15
+ COMMANDS = %w(show)
16
+
17
+ def initialize(arguments)
18
+ @arguments = arguments
19
+ @whoami = File.basename($PROGRAM_NAME).to_sym
20
+
21
+ @options = { :debug => false, :username => Etc.getlogin }
22
+ @action = nil
23
+ @elesai = nil
24
+ end
25
+
26
+ def run
27
+ begin
28
+ parsed_options?
29
+ arguments_valid?
30
+ options_valid?
31
+ process_options
32
+ process_arguments
33
+ process_command
34
+
35
+ rescue => e #ArgumentError, OptionParser::MissingArgument, Senedsa::SendNsca::ConfigurationError => e
36
+ if @options[:debug]
37
+ output_message "#{e.class}: #{e.message}\n #{e.backtrace.join("\n ")}",1
38
+ else
39
+ output_message e.message,1
40
+ end
41
+ end
42
+ end
43
+
44
+ protected
45
+
46
+ def parsed_options?
47
+ opts = OptionParser.new
48
+
49
+ opts.banner = "Usage: #{ID} [options] <action> [options] [arguments]"
50
+ opts.separator ""
51
+ opts.separator "Actions: (<action> -h displays help for specific action)"
52
+ opts.separator " show Displays component information"
53
+ opts.separator ""
54
+ opts.separator "General options:"
55
+ opts.on('-H', '--hostname HOSTNAME', String, "A10 Load Balancer hostname") { |o| @options[:hostname] = o }
56
+ opts.on('-l', '--login USERNAME', String, "Username") { |o| @options[:username] = o }
57
+ opts.on('-f', '--fake DIRECTORY', String, "Path to directory with output") { |o| @options[:fake] = o }
58
+ opts.on('-d', '--debug', "Enable debug mode") { @options[:debug] = true}
59
+ opts.on('-a', '--about', "Display #{ID} information") { output_message ABOUT, 0 }
60
+ opts.on('-V', '--version', "Display #{ID} version") { output_message VERSION, 0 }
61
+ opts.on_tail('--help', "Show this message") { @options[:HELP] = true }
62
+
63
+ opts.order!(@arguments)
64
+ output_message opts, 0 if (@arguments.size == 0 and @whoami != :check_a10) or @options[:HELP]
65
+
66
+ @action = @whoami == :check_a10 ? :check : @arguments.shift.to_sym
67
+ case @action
68
+ when :show then @a10 = Show.new(@arguments,@options)
69
+ else raise OptionParser::InvalidArgument, "invalid action #@action"
70
+ end
71
+ end
72
+
73
+ def arguments_valid?
74
+ true
75
+ end
76
+
77
+ def options_valid?
78
+ true
79
+ end
80
+
81
+ def process_options
82
+ raise OptionParser::MissingArgument, "load balancer hostname (-H) must be specified" if @options[:hostname].nil?
83
+ true
84
+ end
85
+
86
+ def process_arguments
87
+ true
88
+ end
89
+
90
+ def process_command
91
+ @a10.exec
92
+ end
93
+
94
+ def output_message(message, exitstatus=nil)
95
+ m = (! exitstatus.nil? and exitstatus > 0) ? "%s: error: %s" % [ID, message] : message
96
+ # Syslog.open("elesai", Syslog::LOG_PID | Syslog::LOG_CONS) { |s| s.err "error: #{message}" } unless @options[:debug]
97
+ $stderr.write "#{m}\n" if STDIN.tty?
98
+ exit exitstatus unless exitstatus.nil?
99
+ end
100
+
101
+
102
+ end
103
+ end end
@@ -0,0 +1,4 @@
1
+ require 'warthog/cli/action/show'
2
+
3
+ module Warthog; module CLI; module Action
4
+ end end end
@@ -0,0 +1,78 @@
1
+ module Warthog; module CLI; module Action
2
+
3
+ class Show
4
+
5
+ COMPONENTS = %w(service-group)
6
+
7
+ def initialize(arguments,options)
8
+
9
+ @options = options
10
+ @arguments = arguments
11
+
12
+ @component = nil
13
+ @subcomponent = nil
14
+
15
+ opts = OptionParser.new
16
+ opts.banner = "Usage: #{ID} [options] show <component> [arguments]"
17
+ opts.separator ""
18
+ opts.separator " <component> is service-group"
19
+ opts.order!(@arguments)
20
+
21
+ options_valid?
22
+ arguments_valid?
23
+ process_arguments
24
+
25
+ @show = { :service_group => self.method(:show_service_group)
26
+ }
27
+ end
28
+
29
+ def exec
30
+ @a10slb = Warthog::A10::AXDevice.new(@options[:hostname],@options[:username],get_password)
31
+ @show[@component].call(@subcomponent)
32
+ end
33
+
34
+ def show_service_group(name=nil)
35
+ if name.nil?
36
+ printf "%s" % [@a10slb.slb_service_group_all]
37
+ else
38
+ printf "%s" % [@a10slb.slb_service_group_search(name)]
39
+ end
40
+ end
41
+
42
+ protected
43
+
44
+ def options_valid?
45
+ true
46
+ end
47
+
48
+ def arguments_valid?
49
+ raise ArgumentError, "missing component" if @arguments.size == 0
50
+ raise ArgumentError, "invalid component #{@arguments[0]}" unless COMPONENTS.include? @arguments[0]
51
+ true
52
+ end
53
+
54
+ def process_arguments
55
+ @component = case @arguments[0].gsub(/-/,'_').to_sym
56
+ when :dummy then a10 = nil
57
+ else @arguments[0].gsub(/-/,'_').to_sym
58
+ end
59
+ @subcomponent = @arguments[1]
60
+ end
61
+
62
+ def get_password
63
+ password = nil
64
+ begin
65
+ printf "Password: "
66
+ STDOUT.flush
67
+ system "stty -echo"
68
+ password = $stdin.gets.chomp
69
+ ensure
70
+ system "stty echo"
71
+ printf "\n"
72
+ end
73
+ password
74
+ end
75
+ end
76
+
77
+ end end end
78
+
@@ -0,0 +1,3 @@
1
+ module Warthog
2
+ VERSION = "0.1.0"
3
+ end
metadata ADDED
@@ -0,0 +1,72 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: warthog
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Gerardo López-Fernádez
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-11-23 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: httparty
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ description: POkes A10 SLBs with a RESTick
31
+ email: gerir@evernote.com
32
+ executables:
33
+ - warthog
34
+ extensions: []
35
+ extra_rdoc_files: []
36
+ files:
37
+ - lib/warthog/a10/rest.rb
38
+ - lib/warthog/about.rb
39
+ - lib/warthog/cli/action/show.rb
40
+ - lib/warthog/cli/action.rb
41
+ - lib/warthog/cli.rb
42
+ - lib/warthog/version.rb
43
+ - lib/warthog.rb
44
+ - bin/warthog
45
+ - LICENSE
46
+ - README.md
47
+ homepage: https://github.com/evernote/ops-warthog
48
+ licenses:
49
+ - Apache License, Version 2.0
50
+ post_install_message:
51
+ rdoc_options: []
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ! '>='
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: 1.3.5
66
+ requirements: []
67
+ rubyforge_project:
68
+ rubygems_version: 1.8.23
69
+ signing_key:
70
+ specification_version: 3
71
+ summary: A10 REST poker
72
+ test_files: []