rea-netscaler-cli 0.5.9

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.
@@ -0,0 +1,67 @@
1
+ require 'netscaler/logging'
2
+ require 'netscaler/base_request'
3
+ require 'netscaler/vserver/response'
4
+
5
+ module Netscaler::VServer
6
+ class Request < Netscaler::BaseRequest
7
+ include Netscaler::Logging
8
+
9
+ def enable(vserver, options)
10
+ params = { :name => vserver }
11
+ send_request('enablelbvserver', params)
12
+ end
13
+
14
+ def disable(vserver, options)
15
+ params = { :name => vserver }
16
+ send_request('disablelbvserver', params)
17
+ end
18
+
19
+ def list(vserver, options)
20
+ vservers = []
21
+ send_request('getlbvserver', {:empty => :ok}) do |response|
22
+ response[:return][:list][:item].each do |vserver|
23
+ vservers << Response.new(vserver).to_hash
24
+ end
25
+ end
26
+ yield vservers if block_given?
27
+ end
28
+
29
+ def status(vserver, options)
30
+ params = { :name => vserver }
31
+ send_request('getlbvserver', params) do |response|
32
+ yield Response.new(response).to_hash if block_given?
33
+ end
34
+ end
35
+
36
+ def bind(vserver, options)
37
+ params = {
38
+ :name => vserver,
39
+ :policyname => options[:policy],
40
+ :priority => options[:Priority],
41
+ :gotopriorityexpression => 'END'
42
+ }
43
+
44
+ method = if options[:netscaler].version == "9.2"
45
+ 'bindlbvserver'
46
+ else
47
+ 'bindlbvserver_policy'
48
+ end
49
+ send_request(method, params)
50
+ end
51
+
52
+ def unbind(vserver, options)
53
+ params = {
54
+ :name => vserver,
55
+ :policyname => options[:policy],
56
+ :type => 'REQUEST'
57
+ }
58
+
59
+ method = if options[:netscaler].version == "9.2"
60
+ 'unbindlbvserver'
61
+ else
62
+ 'unbindlbvserver_policy'
63
+ end
64
+ send_request(method, params)
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,115 @@
1
+ module Netscaler::VServer
2
+ class Response
3
+ def initialize(raw_response)
4
+ @info = if raw_response[:return]
5
+ raw_response[:return][:list][:item]
6
+ else
7
+ raw_response
8
+ end
9
+ end
10
+
11
+ def name
12
+ @info[:name]
13
+ end
14
+
15
+ def ip_address
16
+ if @info[:ipaddress] =~ /0\.0\.0\.0/
17
+ @info[:ipaddress2]
18
+ else
19
+ @info[:ipaddress]
20
+ end
21
+ end
22
+
23
+ def type
24
+ @info[:servicetype]
25
+ end
26
+
27
+ def port
28
+ @info[:port].to_i
29
+ end
30
+
31
+ def state
32
+ @info[:state]
33
+ end
34
+
35
+ def services
36
+ @parsed_services ||= []
37
+ return @parsed_services if !@parsed_services.empty? || @info[:servicename].nil?
38
+
39
+ if @info[:servicename][:item].is_a?(String)
40
+ @parsed_services << ServiceInfo.new(@info, nil)
41
+ else
42
+ @info[:servicename][:item].each_with_index do |name, i|
43
+ @parsed_services << ServiceInfo.new(@info, i)
44
+ end
45
+ end
46
+
47
+ @parsed_services
48
+ end
49
+
50
+ def service_groups
51
+ @service_groups ||= if @info[:servicegroupname] && @info[:servicegroupname][:item]
52
+ groups = @info[:servicegroupname][:item]
53
+ if groups.is_a?(Array)
54
+ groups
55
+ else
56
+ [groups]
57
+ end
58
+ else
59
+ []
60
+ end
61
+ end
62
+
63
+ def to_hash
64
+ hash = { :name => name,
65
+ :ip_address => ip_address,
66
+ :state => state,
67
+ :port => port,
68
+ :type => type,
69
+ }
70
+
71
+ if !services.empty?
72
+ hash[:services] = services.map {|s| s.to_hash}
73
+ end
74
+
75
+ if !service_groups.empty?
76
+ hash[:service_groups] = service_groups
77
+ end
78
+
79
+ hash
80
+ end
81
+ end
82
+
83
+ class ServiceInfo
84
+ attr_accessor :name, :ip_address, :state, :type
85
+
86
+ def initialize(raw_response, index)
87
+ @name = raw_response[:servicename][:item]
88
+ @ip_address = raw_response[:svcipaddress][:item]
89
+ @state = raw_response[:svcstate][:item]
90
+ @port = raw_response[:svcport][:item]
91
+ @type = raw_response[:svctype][:item]
92
+
93
+ if !index.nil?
94
+ @name = @name[index]
95
+ @ip_address = @ip_address[index]
96
+ @state = @state[index]
97
+ @port = @port[index]
98
+ @type = @type[index]
99
+ end
100
+ end
101
+
102
+ def port
103
+ @port.to_i
104
+ end
105
+
106
+ def to_hash
107
+ { :name => name,
108
+ :ip_address => ip_address,
109
+ :state => state,
110
+ :port => port,
111
+ :type => type
112
+ }
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,204 @@
1
+ require 'spec_helpers'
2
+ require 'netscaler/cli'
3
+
4
+ module Netscaler
5
+
6
+ module CLIHelper
7
+ def parse(*args)
8
+ args << '-c'
9
+ args << File.join(File.dirname(__FILE__), 'configs', 'simple-config.yml')
10
+ cli = CLI.new(args)
11
+ cli.parse!(true)
12
+ end
13
+ end
14
+
15
+ describe CLI do
16
+ include CLIHelper
17
+
18
+ it "should fail when the netscaler alias doesn't exist" do
19
+ attempting {
20
+ parse('-n', 'asdf', 'server', '--action', 'list')
21
+ }.should raise_error(Netscaler::ConfigurationError, /host was not found/)
22
+ end
23
+
24
+ it "should be able to set the netscaler configuration correctly" do
25
+ res = parse('-n', 'else', 'server', '--action', 'list')
26
+ res.options[:netscaler].password.should eql('blah')
27
+ end
28
+
29
+ it "should set the json flag correctly" do
30
+ res = parse('-n', 'else', 'server', '--action', 'list', '--json')
31
+ res.options[:json].should be(true)
32
+ end
33
+
34
+ it "should set the debug flag correctly" do
35
+ res = parse('-n', 'else', 'server', '-a', 'list', '--debug')
36
+ res.options[:debug].should be(true)
37
+ end
38
+
39
+ describe "for servers" do
40
+ it "should fail when the server is not given to a non-list action" do
41
+ attempting {
42
+ parse('-n', 'else', 'server', '-a', 'status')
43
+ }.should raise_error(Choosy::ValidationError, /no server given/)
44
+ end
45
+
46
+ it "should succeed when given the list action with no arguments" do
47
+ res = parse('-n', 'else', 'server', '-a', 'list')
48
+ res.subresults[0][:action].should eql(:list)
49
+ end
50
+
51
+ it "should have the server argument on a non-list action" do
52
+ res = parse('-n', 'else', 'server', '-a', 'status', 'blarg')
53
+ res.subresults[0].args[0].should eql('blarg')
54
+ res.subresults[0][:action].should eql(:status)
55
+ end
56
+ end
57
+
58
+ describe "for vserver" do
59
+ it "should fail when the vserver is given to a non-list option" do
60
+ attempting {
61
+ parse('-n', 'else', 'vserver', '-a', 'disable')
62
+ }.should raise_error(Choosy::ValidationError, /no virtual server/)
63
+ end
64
+
65
+ it "should fail when the --policy flag is unset on a bind/unbind" do
66
+ attempting {
67
+ parse('-n', 'else', 'vserver', '-a', 'bind', 'vserv')
68
+ }.should raise_error(Choosy::ValidationError, /required by the 'bind\/unbind' actions/)
69
+ end
70
+
71
+ it "should fail when the --policy flag is used on anything other than bind/unbind" do
72
+ attempting {
73
+ parse('-n', 'else', 'vserver', '-a', 'disable', '-p', 'pol', 'vserv')
74
+ }.should raise_error(Choosy::ValidationError, /only used with bind/)
75
+ end
76
+
77
+ it "should fail when priority flag is used on anything other than a bind" do
78
+ attempting {
79
+ parse('-n', 'else', 'vserver', '-a', 'disable', '-P', '20', 'vserv')
80
+ }.should raise_error(Choosy::ValidationError, /only used with the bind action/)
81
+ end
82
+
83
+ it "should set the default value for the priority to 100" do
84
+ res = parse('-n', 'else', 'vserver', '-a', 'bind', '-p', 'pol', 'vserv')
85
+ res.subresults[0][:Priority].should eql(100)
86
+ end
87
+
88
+ it "should set the policy name" do
89
+ res = parse('-n', 'else', 'vserver', '-a', 'bind', '-p', 'pol', 'vserv')
90
+ res.subresults[0][:policy].should eql('pol')
91
+ end
92
+
93
+ it "should fail on a bad action" do
94
+ attempting {
95
+ parse('-n', 'else', 'vserver', '-a', 'asdf', 'vserv')
96
+ }.should raise_error(Choosy::ValidationError, /unrecognized value/)
97
+ end
98
+ end
99
+
100
+ describe "for services" do
101
+ it "should fail when the service is given to a non-list action" do
102
+ attempting {
103
+ parse('-n', 'else', 'service', '-a', 'disable')
104
+ }.should raise_error(Choosy::ValidationError, /no services given to act/)
105
+ end
106
+
107
+ it "should fail when --vserver flag is used with a non-bind/unbind action" do
108
+ attempting {
109
+ parse('-n', 'else', 'service', '-a', 'disable', '-v', 'blarg', 'a-service')
110
+ }.should raise_error(Choosy::ValidationError, /only used with bind/)
111
+ end
112
+
113
+ it "should fail when the --vserver flag is not present with the bind/unbind action" do
114
+ attempting {
115
+ parse('-n', 'else', 'service', '-a', 'bind', 'a-service')
116
+ }.should raise_error(Choosy::ValidationError, /requires the -v\/--vserver flag/)
117
+ end
118
+
119
+ it "should succeed in setting the service name as an argument" do
120
+ res = parse('-n', 'else', 'service', '-a', 'bind', '-v', 'blah', 'a-service')
121
+ res.subresults[0].args[0].should eql('a-service')
122
+ end
123
+
124
+ it "should succed in setting the vserver name" do
125
+ res = parse('-n', 'else', 'service', '-a', 'bind', '-v', 'blah', 'a-service')
126
+ res.subresults[0][:vserver].should eql('blah')
127
+ end
128
+
129
+ it "should succeed in setting the action" do
130
+ res = parse('-n', 'else', 'service', '-a', 'bind', '-v', 'blah', 'a-service')
131
+ res.subresults[0][:action].should eql(:bind)
132
+ end
133
+
134
+ it "should set the default action to status" do
135
+ res = parse('-n', 'else', 'service', 'a-service')
136
+ res.subresults[0][:action].should eql(:status)
137
+ end
138
+ end
139
+
140
+ describe "for servicegroups" do
141
+ it "should fail when the service is given to a non-list action" do
142
+ attempting {
143
+ parse('-n', 'else', 'servicegroup', '-a', 'disable')
144
+ }.should raise_error(Choosy::ValidationError, /no service group given to act/)
145
+ end
146
+
147
+ it "should fail when --vserver flag is used with a non-bind/unbind action" do
148
+ attempting {
149
+ parse('-n', 'else', 'servicegroup', '-a', 'disable', '-v', 'blarg', 'a-service-group')
150
+ }.should raise_error(Choosy::ValidationError, /only used with bind/)
151
+ end
152
+
153
+ it "should fail when the --vserver flag is not present with the bind/unbind action" do
154
+ attempting {
155
+ parse('-n', 'else', 'servicegroup', '-a', 'bind', 'a-service-group')
156
+ }.should raise_error(Choosy::ValidationError, /requires the -v\/--vserver flag/)
157
+ end
158
+
159
+ it "should succeed in setting the service name as an argument" do
160
+ res = parse('-n', 'else', 'servicegroup', '-a', 'bind', '-v', 'blah', 'a-service-group')
161
+ res.subresults[0].args[0].should eql('a-service-group')
162
+ end
163
+
164
+ it "should succeed in setting the vserver name" do
165
+ res = parse('-n', 'else', 'servicegroup', '-a', 'bind', '-v', 'blah', 'a-service-group')
166
+ res.subresults[0][:vserver].should eql('blah')
167
+ end
168
+
169
+ it "should succeed in setting the action" do
170
+ res = parse('-n', 'else', 'servicegroup', '-a', 'bind', '-v', 'blah', 'a-service-group')
171
+ res.subresults[0][:action].should eql(:bind)
172
+ end
173
+
174
+ it "should set the default action to status" do
175
+ res = parse('-n', 'else', 'servicegroup', 'a-service-group')
176
+ res.subresults[0][:action].should eql(:status)
177
+ end
178
+
179
+ describe "scoping to an individual service" do
180
+ before :each do
181
+ @res = parse('-n', 'else', 'servicegroup', '-a', 'enable', 'a-service-group', '-s', 'a-server-name', '-p', '8080', '-d', '180')
182
+ end
183
+
184
+ it "should set the servername to a-server-name" do
185
+ @res.subresults[0][:servername].should eql('a-server-name')
186
+ end
187
+
188
+ it "should set the port to 8080" do
189
+ @res.subresults[0][:port].should eql('8080')
190
+ end
191
+
192
+ it "should set the delay to 180" do
193
+ @res.subresults[0][:delay].should eql('180')
194
+ end
195
+
196
+ it "should set the delay to 0 if not specified" do
197
+ @res = parse('-n', 'else', 'servicegroup', '-a', 'enable', 'a-service-group', '-s', 'a-server-name', '-p', '8080')
198
+ @res.subresults[0][:delay].should eql('0')
199
+ end
200
+ end
201
+ end
202
+
203
+ end
204
+ end
@@ -0,0 +1,63 @@
1
+ require 'spec_helpers'
2
+ require 'netscaler/config'
3
+ require 'netscaler/errors'
4
+
5
+ module Netscaler
6
+
7
+ module ConfigurationHelper
8
+ def reading(file)
9
+ actual_file = File.expand_path("./configs/#{file}", File.dirname(__FILE__))
10
+ Netscaler::ConfigurationReader.read_config_file(actual_file)
11
+ end
12
+ end
13
+
14
+ describe "Configuration Reader" do
15
+ include ConfigurationHelper
16
+
17
+ before :each do
18
+ @config = reading('simple-config.yml')
19
+ end
20
+
21
+ describe "when reading an existing file" do
22
+ it "should be able to load the basic config file" do
23
+ @config.load_balancers.length.should eql(2)
24
+ end
25
+
26
+ it "should set the username and password correctly when set in the file." do
27
+ ns = @config['something.goes.here']
28
+ ns.username.should eql('some_user')
29
+ ns.password.should eql('somepass')
30
+ end
31
+
32
+ it "should load via an alias" do
33
+ ns = @config['else']
34
+ ns.alias.should eql('else')
35
+ ns.username.should eql('here')
36
+ end
37
+
38
+ it "should set the default version to 9.2" do
39
+ ns = @config['something.goes.here']
40
+ ns.version.should eql("9.2")
41
+ end
42
+
43
+ it "should read the version if present" do
44
+ ns = @config['else']
45
+ ns.version.should eql("9.1")
46
+ end
47
+ end
48
+
49
+ describe "when reading a non-existent or bad file" do
50
+ it "should fail when the config doesn't exist" do
51
+ attempting { reading('non-config.yml') }.should raise_error(Netscaler::ConfigurationError)
52
+ end
53
+
54
+ it "should fail when the config is poorly formed" do
55
+ attempting { reading('bad-yaml.yml') }.should raise_error(Netscaler::ConfigurationError)
56
+ end
57
+
58
+ it "should fail when the username is missing" do
59
+ attempting { reading('missing-username.yml')['load-balancer'] }.should raise_error(Netscaler::ConfigurationError)
60
+ end
61
+ end
62
+ end
63
+ end