knife-rackspace-load-balancer 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+