knife-rackspace-load-balancer 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ *.gem
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 HowAboutWe
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,28 @@
1
+ ==Setup
2
+ Add region to your knife configuration:
3
+ #knife.rb
4
+ knife[:rackspace_api_region] = "ord"
5
+
6
+ ==Commands
7
+ List:
8
+ bundle exec knife rackspace load balancer list
9
+
10
+ Show:
11
+ bundle exec knife rackspace load balancer show <load_balancer_id>
12
+ bundle exec knife rackspace load balancer show <load_balancer_id> <load_balancer_id> --resolve-node-names
13
+
14
+ Create:
15
+ bundle exec knife rackspace load balancer create "some.site.com" --port 80 --node-port 80 --add-nodes-by-name "app1,app2" --algorithm RANDOM
16
+
17
+ Delete:
18
+ bundle exec knife rackspace load balancer delete <load_balancer_id>
19
+
20
+ Add Node:
21
+ bundle exec knife rackspace load balancer add node --by-name "app1" --port 80 --only "<load_balancer_id>,<load_balancer_id>"
22
+ bundle exec knife rackspace load balancer add node --by-name "app1,app2" --auto-resolve-port --except "<load_balancer_id>"
23
+
24
+ Delete Node:
25
+ bundle exec knife rackspace load balancer delete node --by-search "chef_environment:staging AND name:staging-app" --all
26
+
27
+ == Copyright
28
+ Copyright (c) 2012 HowAboutWe. See LICENSE.txt for further details.
@@ -0,0 +1,18 @@
1
+ $:.push File.expand_path("../lib", __FILE__)
2
+ require "version"
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "knife-rackspace-load-balancer"
6
+ s.version = Knife::Rackspace::LoadBalancer::VERSION
7
+ s.authors = ["Matthew Vermaak"]
8
+ s.email = "dev@howaboutwe.com"
9
+ s.summary = "Rackspace cloud load balancer support for knife"
10
+ s.description = "A gem to extend knife-rackspace allowing cloud load balancer management."
11
+ s.homepage = "http://github.com/howaboutwe/knife-rackspace-load-balancer"
12
+ s.licenses = ["MIT"]
13
+ s.files = `git ls-files`.split("\n")
14
+ s.add_dependency "chef", "~> 0.10.8"
15
+ s.add_dependency "knife-rackspace", "~> 0.5.12"
16
+ s.add_dependency "cloudlb", "~> 0.1.0"
17
+ s.require_paths = ["lib"]
18
+ end
@@ -0,0 +1,161 @@
1
+ require 'chef/knife'
2
+ require 'chef/knife/rackspace_base'
3
+ require 'chef/knife/rackspace_load_balancer_base'
4
+ require 'chef/knife/rackspace_load_balancer_nodes'
5
+ require 'cloudlb'
6
+
7
+ module KnifePlugins
8
+ class RackspaceLoadBalancerAddNode < Chef::Knife
9
+ include Chef::Knife::RackspaceBase
10
+ include Chef::Knife::RackspaceLoadBalancerBase
11
+ include Chef::Knife::RackspaceLoadBalancerNodes
12
+
13
+ banner "knife rackspace load balancer add node (options)"
14
+
15
+ option :force,
16
+ :long => "--force",
17
+ :description => "Skip user input"
18
+
19
+ option :all,
20
+ :long => "--all",
21
+ :description => "Add to all load balancers"
22
+
23
+ option :except,
24
+ :long => "--except \"ID[,ID]\"",
25
+ :description => "Comma deliminated list of load balancer ids to omit (Implies --all)"
26
+
27
+ option :only,
28
+ :long => "--only \"ID[,ID]\"",
29
+ :description => "Comma deliminated list of load balancer ids to add to"
30
+
31
+ option :port,
32
+ :long => "--port PORT",
33
+ :description => "Add node listening to this port [DEFAULT: 80]",
34
+ :default => "80"
35
+
36
+ option :condition,
37
+ :long => "--condition CONDITION",
38
+ :description => "Add node in this condition [DEFAULT: ENABLED]",
39
+ :default => "ENABLED"
40
+
41
+ option :weight,
42
+ :long => "--weight WEIGHT",
43
+ :description => "Add node with this weight [DEFAULT: 1]",
44
+ :default => "1"
45
+
46
+ option :by_name,
47
+ :long => "--by-name \"NAME[,NAME]\"",
48
+ :description => "Resolve names against chef server to produce list of nodes to add"
49
+
50
+ option :by_private_ip,
51
+ :long => "--by-private-ip \"IP[,IP]\"",
52
+ :description => "List of nodes given by private ips to add"
53
+
54
+ option :by_search,
55
+ :long => "--by-search SEARCH",
56
+ :description => "Resolve search against chef server to produce list of nodes to add"
57
+
58
+ option :auto_resolve_port,
59
+ :long => "--auto-resolve-port",
60
+ :description => "Auto resolve port of node addition"
61
+
62
+ def run
63
+ unless [:all, :except, :only].any? {|target| not config[target].nil?}
64
+ ui.fatal("Must provide a target set of load balancers with --all, --except, or --only")
65
+ show_usage
66
+ exit 1
67
+ end
68
+
69
+ unless [:by_name, :by_private_ip, :by_search].any? {|addition| not config[addition].nil?}
70
+ ui.fatal("Must provide a set of additional nodes with --by-name, --by-private-ip, or --by-search")
71
+ show_usage
72
+ exit 2
73
+ end
74
+
75
+ node_ips = resolve_node_ips_from_config({
76
+ :by_search => config[:by_search],
77
+ :by_name => config[:by_name],
78
+ :by_private_ip => config[:by_private_ip]
79
+ })
80
+
81
+ nodes = node_ips.map do |ip|
82
+ {
83
+ :address => ip,
84
+ :port => config[:auto_resolve_port] ? "Auto resolve" : config[:port],
85
+ :condition => config[:condition],
86
+ :weight => config[:weight]
87
+ }
88
+ end
89
+
90
+ if nodes.empty?
91
+ ui.fatal("Node resolution did not provide a set of nodes for addition")
92
+ exit 3
93
+ end
94
+
95
+ target_load_balancers = lb_connection.list_load_balancers
96
+
97
+ if config[:only]
98
+ only = config[:only].split(",").map(&:to_s)
99
+ target_load_balancers = target_load_balancers.select {|lb| only.include? lb[:id].to_s}
100
+ end
101
+
102
+ if config[:except]
103
+ except = config[:except].split(",").map(&:to_s)
104
+ target_load_balancers = target_load_balancers.reject {|lb| except.include? lb[:id].to_s}
105
+ end
106
+
107
+ if target_load_balancers.empty?
108
+ ui.fatal("Load balancer resolution did not provide a set of target load balancers")
109
+ exit 4
110
+ end
111
+
112
+ ui.output(format_for_display({
113
+ :targets => target_load_balancers.map {|lb| lb[:name]},
114
+ :nodes => nodes
115
+ }))
116
+
117
+ unless config[:force]
118
+ ui.confirm("Do you really want to add these nodes")
119
+ end
120
+
121
+ target_load_balancers.each do |lb|
122
+ begin
123
+ ui.output("Opening #{lb[:name]}")
124
+ balancer = lb_connection.get_load_balancer(lb[:id])
125
+ lb_nodes = balancer.list_nodes
126
+ lb_node_ips = lb_nodes.map {|lbn| lbn[:address]}
127
+
128
+ if config[:auto_resolve_port]
129
+ nodes_for_balancer = nodes.dup
130
+
131
+ port = lb_nodes.first[:port]
132
+ ui.output(ui.color("Auto resolved port to: #{port}", :cyan))
133
+
134
+ nodes_for_balancer.each do |nfb|
135
+ nfb[:port] = port
136
+ end
137
+ else
138
+ nodes_for_balancer = nodes
139
+ end
140
+
141
+ nodes_for_balancer.each do |node|
142
+ if lb_node_ips.include?(node[:address])
143
+ ui.warn("Skipping node #{node[:address]}")
144
+ else
145
+ ui.output("Adding node #{node[:address]}")
146
+ if balancer.create_node(node)
147
+ ui.output(ui.color("Success", :green))
148
+ else
149
+ ui.output(ui.color("Failed", :red))
150
+ end
151
+ end
152
+ end
153
+ rescue CloudLB::Exception::Other => e
154
+ ui.error("Failed on #{lb[:name]}: CloudLB::Exception [#{e.class.name}] - #{e.message}")
155
+ end
156
+ end
157
+
158
+ ui.output(ui.color("Complete", :green))
159
+ end
160
+ end
161
+ end
@@ -0,0 +1,26 @@
1
+ class Chef
2
+ class Knife
3
+ module RackspaceLoadBalancerBase
4
+ def self.included(base)
5
+ base.class_eval do
6
+ option :rackspace_api_region,
7
+ :short => "-R REGION",
8
+ :long => "--rackspace-api-region REGION",
9
+ :description => "Your rackspace API region. IE: ord, dfw",
10
+ :proc => Proc.new {|region| Chef::Config[:knife][:rackspace_api_region] = region}
11
+ end
12
+ end
13
+ def rackspace_api_credentials
14
+ {
15
+ :username => Chef::Config[:knife][:rackspace_api_username],
16
+ :api_key => Chef::Config[:knife][:rackspace_api_key],
17
+ :region => Chef::Config[:knife][:rackspace_api_region]
18
+ }
19
+ end
20
+
21
+ def lb_connection
22
+ @lb_connection ||= CloudLB::Connection.new(rackspace_api_credentials)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,124 @@
1
+ require 'chef/knife'
2
+ require 'chef/knife/rackspace_base'
3
+ require 'chef/knife/rackspace_load_balancer_base'
4
+ require 'chef/knife/rackspace_load_balancer_nodes'
5
+ require 'cloudlb'
6
+
7
+ module KnifePlugins
8
+ class RackspaceLoadBalancerCreate < Chef::Knife
9
+ include Chef::Knife::RackspaceBase
10
+ include Chef::Knife::RackspaceLoadBalancerBase
11
+ include Chef::Knife::RackspaceLoadBalancerNodes
12
+
13
+ banner "knife rackspace load balancer create NAME (options)"
14
+
15
+ option :force,
16
+ :long => "--force",
17
+ :description => "Skip user input"
18
+
19
+ option :protocol,
20
+ :long => "--protocol PROTOCOL",
21
+ :description => "The protocol to balance [Default: HTTP]",
22
+ :default => "HTTP"
23
+
24
+ option :add_nodes_by_search,
25
+ :long => "--add-nodes-by-search SEARCH",
26
+ :description => "Node search query resolved by Chef Server to add"
27
+
28
+ option :add_nodes_by_private_ip,
29
+ :long => "--add-nodes-by-private-ip \"IP[,IP]\"",
30
+ :description => "Comma deliminated list of private ips to add"
31
+
32
+ option :add_nodes_by_name,
33
+ :long => "--add-nodes-by-name \"NAME[,NAME]\"",
34
+ :description => "Comma deliminated list of node names resolved by Chef Server to add"
35
+
36
+ option :node_port,
37
+ :long => "--node-port PORT",
38
+ :description => "Add nodes listening to this port DEFAULT: 80",
39
+ :default => "80"
40
+
41
+ option :node_weight,
42
+ :long => "--node-weight WEIGHT",
43
+ :description => "Add nodes with this weight",
44
+ :default => "1"
45
+
46
+ option :node_condition,
47
+ :long => "--node-condition CONDITION",
48
+ :description => "Add nodes with this condition",
49
+ :default => "ENABLED"
50
+
51
+ option :port,
52
+ :long => "--port PORT",
53
+ :description => "Configure the load balancer to listen to this port DEFAULT: 80",
54
+ :default => "80"
55
+
56
+ option :algorithm,
57
+ :long => "--algorithm ALGORITHM",
58
+ :description => "The algorithm to employ for load balancing [Defualt: RANDOM]",
59
+ :default => "RANDOM"
60
+
61
+ option :virtual_ip_ids,
62
+ :long => "--virtual-ip-id \"ID[,ID]\"",
63
+ :description => "Comma deliminated list of virtual ip ids"
64
+
65
+ option :virtual_ip_type,
66
+ :long => "--virtual-ip-type TYPE",
67
+ :description => "Type of virtual IP to obtain [DEFAULT: PUBLIC]",
68
+ :default => "PUBLIC"
69
+
70
+
71
+
72
+ def run
73
+ if @name_args.first.nil?
74
+ ui.fatal("Must provide name")
75
+ show_usage
76
+ exit 1
77
+ end
78
+
79
+ unless [:add_nodes_by_search, :add_nodes_by_name, :add_nodes_by_private_ip].any? {|addition| not config[addition].nil?}
80
+ ui.fatal("Must provide nodes via --add-nodes-by-search, --add-nodes-by-node-name, or --add-nodes-by-private-ip")
81
+ show_usage
82
+ exit 2
83
+ end
84
+
85
+ node_ips = resolve_node_ips_from_config({
86
+ :by_search => config[:add_nodes_by_search],
87
+ :by_name => config[:add_nodes_by_name],
88
+ :by_private_ip => config[:add_nodes_by_private_ip]
89
+ })
90
+
91
+ nodes = node_ips.map do |ip|
92
+ {
93
+ :address => ip,
94
+ :port => config[:node_port],
95
+ :condition => config[:node_condition],
96
+ :weight => config[:node_weight]
97
+ }
98
+ end
99
+
100
+ load_balancer_configuration = {
101
+ :name => @name_args.first,
102
+ :protocol => config[:protocol],
103
+ :port => config[:port],
104
+ :algorithm => config[:algorithm],
105
+ :nodes => nodes,
106
+ :virtual_ip_type => config[:virtual_ip_type]
107
+ }
108
+
109
+ unless config[:virtual_ip_ids].nil?
110
+ load_balancer_configuration[:virtual_ip_ids] = config[:virtual_ip_ids].split(",")
111
+ end
112
+
113
+ ui.output format_for_display(load_balancer_configuration)
114
+
115
+ unless config[:force]
116
+ ui.confirm("Do you really want to create this load balancer")
117
+ end
118
+
119
+ load_balancer_id = lb_connection.create_load_balancer(load_balancer_configuration)
120
+
121
+ ui.output(ui.color("Created load balancer #{@name_args.first}", :green))
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,41 @@
1
+ require 'chef/knife'
2
+ require 'chef/knife/rackspace_base'
3
+ require 'chef/knife/rackspace_load_balancer_base'
4
+ require 'cloudlb'
5
+
6
+ require 'chef/knife/rackspace_load_balancer_show'
7
+
8
+ module KnifePlugins
9
+ class RackspaceLoadBalancerDelete < Chef::Knife
10
+ include Chef::Knife::RackspaceBase
11
+ include Chef::Knife::RackspaceLoadBalancerBase
12
+
13
+ banner "knife rackspace load balancer delete ID [ID] (options)"
14
+
15
+ option :force,
16
+ :long => "--force",
17
+ :description => "Skip user prompts"
18
+
19
+ option :resolve_node_names,
20
+ :long => "--resolve-node-names",
21
+ :description => "Resolve node names against Chef Server"
22
+
23
+ def run
24
+ @name_args.each do |load_balancer_id|
25
+ show_load_balancer = RackspaceLoadBalancerShow.new
26
+ show_load_balancer.config[:resolve_node_names] = true if config[:resolve_node_names]
27
+ show_load_balancer.name_args = [load_balancer_id]
28
+ show_load_balancer.run
29
+
30
+ unless config[:force]
31
+ ui.confirm("Do you really want to delete this load balancer")
32
+ end
33
+
34
+ load_balancer = lb_connection.get_load_balancer(load_balancer_id)
35
+ load_balancer.destroy!
36
+
37
+ ui.warn("Deleted load balancer #{load_balancer_id}")
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,117 @@
1
+ require 'chef/knife'
2
+ require 'chef/knife/rackspace_base'
3
+ require 'chef/knife/rackspace_load_balancer_base'
4
+ require 'chef/knife/rackspace_load_balancer_nodes'
5
+ require 'cloudlb'
6
+
7
+ module KnifePlugins
8
+ class RackspaceLoadBalancerDeleteNode < Chef::Knife
9
+ include Chef::Knife::RackspaceBase
10
+ include Chef::Knife::RackspaceLoadBalancerBase
11
+ include Chef::Knife::RackspaceLoadBalancerNodes
12
+
13
+ banner "knife rackspace load balancer delete node (options)"
14
+
15
+ option :force,
16
+ :long => "--force",
17
+ :description => "Skip user input"
18
+
19
+ option :all,
20
+ :long => "--all",
21
+ :description => "Remove from all load balancers"
22
+
23
+ option :except,
24
+ :long => "--except \"ID[,ID]\"",
25
+ :description => "List of load balancer ids to omit (Implies --all)"
26
+
27
+ option :only,
28
+ :long => "--only \"ID[,ID]\"",
29
+ :description => "List of load balancer ids to remove from"
30
+
31
+ option :by_name,
32
+ :long => "--by-name \"NAME[,NAME]\"",
33
+ :description => "Resolve names against chef server to produce list of nodes to remove"
34
+
35
+ option :by_private_ip,
36
+ :long => "--by-private-ip \"IP[,IP]\"",
37
+ :description => "List of nodes given by private ips to remove"
38
+
39
+ option :by_search,
40
+ :long => "--by-search SEARCH",
41
+ :description => "Resolve search against chef server to produce list of nodes to remove"
42
+
43
+ def run
44
+ unless [:all, :except, :only].any? {|target| not config[target].nil?}
45
+ ui.fatal("Must provide a target set of load balancers with --all, --except, or --only")
46
+ show_usage
47
+ exit 1
48
+ end
49
+
50
+ unless [:by_name, :by_private_ip, :by_search].any? {|addition| not config[addition].nil?}
51
+ ui.fatal("Must provide a set of nodes to remove with --by-name, --by-private-ip, or --by-search")
52
+ show_usage
53
+ exit 2
54
+ end
55
+
56
+ node_ips = resolve_node_ips_from_config({
57
+ :by_search => config[:by_search],
58
+ :by_name => config[:by_name],
59
+ :by_private_ip => config[:by_private_ip]
60
+ })
61
+
62
+ nodes = node_ips.map do |ip|
63
+ { :address => ip }
64
+ end
65
+
66
+ if nodes.empty?
67
+ ui.fatal("Node resolution did not provide a set of nodes for removal")
68
+ exit 3
69
+ end
70
+
71
+ target_load_balancers = lb_connection.list_load_balancers
72
+
73
+ if config[:only]
74
+ only = config[:only].split(",").map(&:to_s)
75
+ target_load_balancers = target_load_balancers.select {|lb| only.include? lb[:id].to_s}
76
+ end
77
+
78
+ if config[:except]
79
+ except = config[:except].split(",").map(&:to_s)
80
+ target_load_balancers = target_load_balancers.reject {|lb| except.include? lb[:id].to_s}
81
+ end
82
+
83
+ if target_load_balancers.empty?
84
+ ui.fatal("Load balancer resolution did not provide a set of target load balancers")
85
+ exit 4
86
+ end
87
+
88
+ ui.output(format_for_display({
89
+ :targets => target_load_balancers.map {|lb| lb[:name]},
90
+ :nodes => nodes
91
+ }))
92
+
93
+ unless config[:force]
94
+ ui.confirm("Do you really want to remove these nodes")
95
+ end
96
+
97
+ target_load_balancers.each do |lb|
98
+ ui.output("Opening #{lb[:name]}")
99
+ balancer = lb_connection.get_load_balancer(lb[:id])
100
+
101
+ lb_nodes = balancer.list_nodes
102
+ lb_nodes.each do |lb_node_hash|
103
+ if node_ips.include? lb_node_hash[:address].to_s
104
+ lb_node = balancer.get_node(lb_node_hash[:id])
105
+ ui.output("Removing node #{lb_node.address}")
106
+ if lb_node.destroy!
107
+ ui.output(ui.color("Success", :green))
108
+ end
109
+ end
110
+ end
111
+ end
112
+
113
+ ui.output(ui.color("Complete", :green))
114
+ end
115
+ end
116
+ end
117
+
@@ -0,0 +1,39 @@
1
+ require 'chef/knife'
2
+ require 'chef/knife/rackspace_base'
3
+ require 'chef/knife/rackspace_load_balancer_base'
4
+ require 'cloudlb'
5
+
6
+ module KnifePlugins
7
+ class RackspaceLoadBalancerList < Chef::Knife
8
+
9
+ include Chef::Knife::RackspaceBase
10
+ include Chef::Knife::RackspaceLoadBalancerBase
11
+
12
+ banner "knife rackspace load balancer list"
13
+
14
+ def run
15
+ load_balancer_list = [
16
+ ui.color("Id", :bold),
17
+ ui.color("Name", :bold),
18
+ ui.color("Nodes", :bold),
19
+ ui.color("Virtual Ip", :bold),
20
+ ui.color("Protocol / Port", :bold),
21
+ ui.color("Status", :bold),
22
+ ]
23
+
24
+ lb_connection.list_load_balancers.each do |load_balancer|
25
+ vip = (load_balancer[:virtualIps].detect {|vip| vip[:ipVersion] == "IPV4"})
26
+ vip ||= load_balancer[:virtualIps].first
27
+
28
+ load_balancer_list << load_balancer[:id].to_s
29
+ load_balancer_list << load_balancer[:name].to_s
30
+ load_balancer_list << load_balancer[:nodeCount].to_s
31
+ load_balancer_list << (vip.nil? ? "None" : vip[:address].to_s)
32
+ load_balancer_list << "#{load_balancer[:protocol]} / #{load_balancer[:port].to_s}"
33
+ load_balancer_list << ui.color(load_balancer[:status].to_s, load_balancer[:status] == "ACTIVE" ? :green : :red)
34
+ end
35
+
36
+ puts ui.list(load_balancer_list, :columns_across, 6)
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,32 @@
1
+ class Chef
2
+ class Knife
3
+ module RackspaceLoadBalancerNodes
4
+ def nodes_by_search(query)
5
+ nodes = []
6
+ Chef::Search::Query.new.search(:node, query) do |n|
7
+ nodes << n
8
+ end
9
+
10
+ nodes
11
+ end
12
+
13
+ def resolve_node_ips_from_config(options)
14
+ node_ips = []
15
+ if options[:by_search]
16
+ nodes_from_chef = nodes_by_search(options[:by_search])
17
+
18
+ node_ips = nodes_from_chef.map {|n| n.rackspace.private_ip}
19
+ elsif options[:by_name]
20
+ node_names = options[:by_name].split(",")
21
+ nodes_from_chef = nodes_by_search(node_names.map {|n| "name:#{n}"}.join(" OR "))
22
+
23
+ node_ips = nodes_from_chef.map {|n| n.rackspace.private_ip}
24
+ elsif options[:by_private_ip]
25
+ node_ips = config[:by_private_ip].split(",")
26
+ end
27
+
28
+ node_ips
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,75 @@
1
+ require 'chef/knife'
2
+ require 'chef/search/query'
3
+ require 'chef/knife/rackspace_base'
4
+ require 'chef/knife/rackspace_load_balancer_base'
5
+ require 'chef/knife/rackspace_load_balancer_nodes'
6
+ require 'cloudlb'
7
+
8
+ module KnifePlugins
9
+ class RackspaceLoadBalancerShow < Chef::Knife
10
+ include Chef::Knife::RackspaceBase
11
+ include Chef::Knife::RackspaceLoadBalancerBase
12
+ include Chef::Knife::RackspaceLoadBalancerNodes
13
+
14
+ banner "knife rackspace load balancer show ID [ID] (options)"
15
+
16
+ option :resolve_node_names,
17
+ :long => "--resolve-node-names",
18
+ :description => "Resolve node names against chef server"
19
+
20
+ def run
21
+ @name_args.each do |load_balancer_id|
22
+ load_balancer = lb_connection.get_load_balancer(load_balancer_id)
23
+ nodes = load_balancer.list_nodes
24
+
25
+ load_balancer_info = {
26
+ :name => load_balancer.name,
27
+ :id => load_balancer.id,
28
+ :protocol => load_balancer.protocol,
29
+ :port => load_balancer.port,
30
+ :status => ui.color(load_balancer.status, load_balancer.status == "ACTIVE" ? :green : :red)
31
+ }
32
+
33
+ vip_list = [
34
+ ui.color("Virtual Ip(s)", :bold),
35
+ ui.color("Id", :bold),
36
+ ui.color("Version", :bold),
37
+ ]
38
+
39
+ load_balancer.list_virtual_ips.each do |vip|
40
+ vip_list << vip[:address].to_s
41
+ vip_list << vip[:id].to_s
42
+ vip_list << vip[:ipVersion].to_s
43
+ end
44
+
45
+ node_list = [
46
+ ui.color("Node(s)", :bold),
47
+ ui.color("Address", :bold),
48
+ ui.color("Port", :bold),
49
+ ui.color("Condition", :bold),
50
+ ui.color("Status", :bold)
51
+ ]
52
+
53
+ nodes.each do |node|
54
+ node_name = node[:id]
55
+
56
+ if config[:resolve_node_names]
57
+ first_node = nodes_by_search("private_ip:#{node[:address]}").first
58
+ node_name = first_node.name unless first_node.nil? || first_node.name.nil?
59
+ end
60
+
61
+ node_list << node_name.to_s
62
+ node_list << node[:address].to_s
63
+ node_list << node[:port].to_s
64
+ node_list << ui.color(node[:condition].to_s, node[:condition] == "ENABLED" ? :green : :red)
65
+ node_list << ui.color(node[:status].to_s, node[:status] == "ONLINE" ? :green : :red)
66
+ end
67
+
68
+ ui.output(format_for_display(load_balancer_info))
69
+ ui.output("\n")
70
+ ui.output(ui.list(vip_list, :columns_across, 3))
71
+ ui.output(ui.list(node_list, :columns_across, 5))
72
+ end
73
+ end
74
+ end
75
+ end
data/lib/version.rb ADDED
@@ -0,0 +1,8 @@
1
+ module Knife
2
+ module Rackspace
3
+ module LoadBalancer
4
+ VERSION="0.0.1"
5
+ MAJOR, MINOR, TINY = VERSION.split(".")
6
+ end
7
+ end
8
+ end
metadata ADDED
@@ -0,0 +1,100 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: knife-rackspace-load-balancer
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors:
8
+ - Matthew Vermaak
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2012-04-12 00:00:00 -04:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: chef
18
+ prerelease: false
19
+ requirement: &id001 !ruby/object:Gem::Requirement
20
+ none: false
21
+ requirements:
22
+ - - ~>
23
+ - !ruby/object:Gem::Version
24
+ version: 0.10.8
25
+ type: :runtime
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
28
+ name: knife-rackspace
29
+ prerelease: false
30
+ requirement: &id002 !ruby/object:Gem::Requirement
31
+ none: false
32
+ requirements:
33
+ - - ~>
34
+ - !ruby/object:Gem::Version
35
+ version: 0.5.12
36
+ type: :runtime
37
+ version_requirements: *id002
38
+ - !ruby/object:Gem::Dependency
39
+ name: cloudlb
40
+ prerelease: false
41
+ requirement: &id003 !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ~>
45
+ - !ruby/object:Gem::Version
46
+ version: 0.1.0
47
+ type: :runtime
48
+ version_requirements: *id003
49
+ description: A gem to extend knife-rackspace allowing cloud load balancer management.
50
+ email: dev@howaboutwe.com
51
+ executables: []
52
+
53
+ extensions: []
54
+
55
+ extra_rdoc_files: []
56
+
57
+ files:
58
+ - .gitignore
59
+ - LICENSE.txt
60
+ - README.rdoc
61
+ - knife-rackspace-load-balancer.gemspec
62
+ - lib/chef/knife/rackspace_load_balancer_add_node.rb
63
+ - lib/chef/knife/rackspace_load_balancer_base.rb
64
+ - lib/chef/knife/rackspace_load_balancer_create.rb
65
+ - lib/chef/knife/rackspace_load_balancer_delete.rb
66
+ - lib/chef/knife/rackspace_load_balancer_delete_node.rb
67
+ - lib/chef/knife/rackspace_load_balancer_list.rb
68
+ - lib/chef/knife/rackspace_load_balancer_nodes.rb
69
+ - lib/chef/knife/rackspace_load_balancer_show.rb
70
+ - lib/version.rb
71
+ has_rdoc: true
72
+ homepage: http://github.com/howaboutwe/knife-rackspace-load-balancer
73
+ licenses:
74
+ - MIT
75
+ post_install_message:
76
+ rdoc_options: []
77
+
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: "0"
86
+ required_rubygems_version: !ruby/object:Gem::Requirement
87
+ none: false
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ version: "0"
92
+ requirements: []
93
+
94
+ rubyforge_project:
95
+ rubygems_version: 1.6.2
96
+ signing_key:
97
+ specification_version: 3
98
+ summary: Rackspace cloud load balancer support for knife
99
+ test_files: []
100
+