netscaler-cli 0.3.3 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. data/Gemfile +7 -3
  2. data/Gemfile.lock +17 -8
  3. data/README.markdown +6 -3
  4. data/Rakefile +4 -6
  5. data/bin/{netscaler-server → netscaler} +2 -2
  6. data/etc/Version +1 -1
  7. data/lib/netscaler/{baseexecutor.rb → base_request.rb} +3 -4
  8. data/lib/netscaler/cli.rb +201 -0
  9. data/lib/netscaler/config.rb +20 -15
  10. data/lib/netscaler/executor.rb +34 -0
  11. data/lib/netscaler/extensions.rb +47 -0
  12. data/lib/netscaler/server/request.rb +35 -0
  13. data/lib/netscaler/server/response.rb +67 -0
  14. data/lib/netscaler/service/request.rb +42 -0
  15. data/lib/netscaler/service/response.rb +44 -0
  16. data/lib/netscaler/vserver/request.rb +67 -0
  17. data/lib/netscaler/vserver/response.rb +125 -0
  18. data/spec/netscaler/cli_spec.rb +140 -0
  19. data/spec/{config_spec.rb → netscaler/config_spec.rb} +23 -9
  20. data/spec/{configs → netscaler/configs}/bad-yaml.yml +0 -0
  21. data/spec/{configs → netscaler/configs}/missing-username.yml +0 -0
  22. data/spec/{configs → netscaler/configs}/simple-config.yml +2 -1
  23. data/spec/netscaler/extenstions_spec.rb +26 -0
  24. data/spec/{helpers.rb → spec_helpers.rb} +0 -0
  25. metadata +108 -53
  26. data/bin/netscaler-service +0 -5
  27. data/bin/netscaler-vserver +0 -5
  28. data/lib/netscaler/clitemplate.rb +0 -147
  29. data/lib/netscaler/server/cli.rb +0 -60
  30. data/lib/netscaler/server/executor.rb +0 -115
  31. data/lib/netscaler/service/cli.rb +0 -49
  32. data/lib/netscaler/service/executor.rb +0 -82
  33. data/lib/netscaler/vserver/cli.rb +0 -92
  34. data/lib/netscaler/vserver/executor.rb +0 -194
  35. data/spec/server/cli_spec.rb +0 -33
  36. data/spec/service/cli_spec.rb +0 -45
  37. data/spec/vserver/cli_spec.rb +0 -75
@@ -0,0 +1,47 @@
1
+
2
+ # Alter the standard Array class
3
+ class Array
4
+ def to_s
5
+ base = ""
6
+ each do |e|
7
+ base << e.to_s
8
+ base << "\n"
9
+ end
10
+ base
11
+ end
12
+
13
+ def to_json(prefix=nil)
14
+ value = if prefix
15
+ prefix.dup
16
+ else
17
+ ""
18
+ end
19
+ if empty?
20
+ return value << "[]"
21
+ end
22
+
23
+ indent = if prefix
24
+ " " << prefix
25
+ else
26
+ " "
27
+ end
28
+
29
+ value << "[\n"
30
+
31
+ each_with_index do |e, i|
32
+ value << indent
33
+ value << e.to_json(indent)
34
+ value << ",\n" unless i == length - 1
35
+ end
36
+
37
+ value << "\n"
38
+ value << prefix if prefix
39
+ value << "]\n"
40
+ end
41
+ end
42
+
43
+ class String
44
+ def to_json(prefix=nil)
45
+ "\"#{self}\""
46
+ end
47
+ end
@@ -0,0 +1,35 @@
1
+ require 'netscaler/base_request'
2
+ require 'netscaler/server/response'
3
+
4
+ module Netscaler::Server
5
+ class Request < Netscaler::BaseRequest
6
+ def enable(server, options)
7
+ send_request('enableserver', {:name => server})
8
+ end
9
+
10
+ def disable(server, options)
11
+ send_request('disableserver', {:name => server})
12
+ end
13
+
14
+ def list(server, options)
15
+ responses = []
16
+ send_request('getserver', {:empty => :ok}) do |response|
17
+ response_part(response).each_with_index do |server, i|
18
+ responses << Response.new(server)
19
+ end
20
+ end
21
+ yield responses if block_given?
22
+ end
23
+
24
+ def status(server, options)
25
+ send_request('getserver', {:name => server }) do |response|
26
+ yield Response.new(response_part(response)) if block_given?
27
+ end
28
+ end
29
+
30
+ private
31
+ def response_part(response)
32
+ response[:return][:list][:item]
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,67 @@
1
+ module Netscaler::Server
2
+ class Response
3
+ FORMAT = "%-30s %15s %10s"
4
+
5
+ attr_reader :info
6
+
7
+ def initialize(raw_response)
8
+ @info = raw_response
9
+ end
10
+
11
+ def name
12
+ info[:name]
13
+ end
14
+
15
+ def ip_address
16
+ info[:ipaddress]
17
+ end
18
+
19
+ def state
20
+ info[:state]
21
+ end
22
+
23
+ def header
24
+ line = sprintf FORMAT, 'Name', 'IP Address', 'State'
25
+ eqls = '=' * line.length
26
+ line + "\n" + eqls
27
+ end
28
+
29
+ def services
30
+ if info[:servicename]
31
+ res = info[:servicename][:item]
32
+ if !res.is_a?(Array)
33
+ [res]
34
+ else
35
+ res
36
+ end
37
+ else
38
+ []
39
+ end
40
+ end
41
+
42
+ def to_s
43
+ base = sprintf FORMAT, name, ip_address, state
44
+ if !services.empty?
45
+ base << "\n"
46
+ services.each do |s|
47
+ base << "| service: #{s}\n"
48
+ end
49
+ end
50
+ base
51
+ end
52
+
53
+ def to_json(prefix=nil)
54
+ indent = if prefix
55
+ prefix + " "
56
+ else
57
+ " "
58
+ end
59
+ base = "{\n#{indent}'name': '#{name}',\n#{indent}'ip_address': '#{ip_address}',\n#{indent}'state': '#{state}'"
60
+ if !services.empty?
61
+ base << ",\n#{indent}'services':\n#{services.to_json(indent)}"
62
+ end
63
+ base.chomp!
64
+ base << "\n#{prefix}}"
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,42 @@
1
+ require 'netscaler/base_request'
2
+ require 'netscaler/service/response'
3
+
4
+ module Netscaler::Service
5
+ class Request < Netscaler::BaseRequest
6
+ def enable(service, options)
7
+ params = { :name => service }
8
+ send_request('enableservice', params)
9
+ end
10
+
11
+ def disable(service, options)
12
+ params = {
13
+ :name => service,
14
+ :delay => 0
15
+ }
16
+ send_request('disableservice', params)
17
+ end
18
+
19
+ def bind(service, options)
20
+ params = {
21
+ :name => options[:vserver],
22
+ :servicename => service
23
+ }
24
+ send_request('bindlbvserver_service', params)
25
+ end
26
+
27
+ def unbind(service, options)
28
+ params = {
29
+ :name => options[:vserver],
30
+ :servicename => service
31
+ }
32
+ send_request('unbindlbvserver_service', params)
33
+ end
34
+
35
+ def status(service, options)
36
+ params = { :name => service }
37
+ send_request('getservice', params) do |response|
38
+ yield Response.new(response) if block_given?
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,44 @@
1
+ module Netscaler::Service
2
+ class Response
3
+ FORMAT = "%-30s %15s %10s %10s"
4
+
5
+ def initialize(raw_response)
6
+ @info = raw_response[:return][:list][:item]
7
+ end
8
+
9
+ def name
10
+ @info[:name]
11
+ end
12
+
13
+ def ip_address
14
+ @info[:ipaddress]
15
+ end
16
+
17
+ def state
18
+ @info[:svrstate]
19
+ end
20
+
21
+ def port
22
+ @info[:port]
23
+ end
24
+
25
+ def header
26
+ line = sprintf FORMAT, 'Name', 'IP Address', 'State', 'Port'
27
+ eqls = '=' * line.length
28
+ line + "\n" + eqls
29
+ end
30
+
31
+ def to_s
32
+ sprintf FORMAT, name, ip_address, state, port
33
+ end
34
+
35
+ def to_json(prefix=nil)
36
+ indent = if prefix
37
+ ' ' + prefix
38
+ else
39
+ ' '
40
+ end
41
+ "{\n#{indent}'name': '#{name}',\n#{indent}'ip_address': '#{ip_address}',\n#{indent}'state': '#{state}',\n#{indent}'port': #{port}\n#{prefix}}"
42
+ end
43
+ end
44
+ end
@@ -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)
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) 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,125 @@
1
+
2
+ module Netscaler::VServer
3
+ class Response
4
+ FORMAT = "%-47s %15s %15s %10s %10s"
5
+
6
+ attr_reader :info
7
+
8
+ def initialize(raw_response)
9
+ @info = if raw_response[:return]
10
+ raw_response[:return][:list][:item]
11
+ else
12
+ raw_response
13
+ end
14
+ end
15
+
16
+ def name
17
+ info[:name]
18
+ end
19
+
20
+ def ip_address
21
+ if info[:ipaddress] =~ /0\.0\.0\.0/
22
+ info[:ipaddress2]
23
+ else
24
+ info[:ipaddress]
25
+ end
26
+ end
27
+
28
+ def type
29
+ info[:servicetype]
30
+ end
31
+
32
+ def port
33
+ info[:port]
34
+ end
35
+
36
+ def state
37
+ info[:state]
38
+ end
39
+
40
+ def header
41
+ line = sprintf FORMAT, 'Name', 'IP Address', 'State', 'Port', 'Type'
42
+ eqls = '=' * line.length
43
+ line + "\n" + eqls
44
+ end
45
+
46
+ def servers
47
+ @parsed_servers ||= []
48
+ if !@parsed_servers.empty? || info[:servicename].nil?
49
+ return @parsed_servers
50
+ end
51
+
52
+ if info[:servicename][:item].is_a?(String)
53
+ @parsed_servers << ServerInfo.new(info, nil)
54
+ else
55
+ info[:servicename][:item].each_with_index do |name, i|
56
+ @parsed_servers << ServerInfo.new(info, i)
57
+ end
58
+ end
59
+
60
+ @parsed_servers
61
+ end
62
+
63
+ def to_s
64
+ base = sprintf FORMAT, name, ip_address, state, port, type
65
+
66
+ if !servers.empty?
67
+ base << "\n"
68
+ servers.each do |server|
69
+ base << "|> server: #{server}\n"
70
+ end
71
+ end
72
+
73
+ base
74
+ end
75
+
76
+ def to_json(prefix=nil)
77
+ indent = if prefix
78
+ ' ' + prefix
79
+ else
80
+ ' '
81
+ end
82
+ base = "{\n#{indent}'name': '#{name}',\n#{indent}'ip_address': '#{ip_address}',\n#{indent}'state': '#{state}',\n#{indent}'port': #{port},\n#{indent}'type': '#{type}'"
83
+
84
+ if !servers.empty?
85
+ base << ",\n#{indent}'servers':\n#{servers.to_json(indent)}"
86
+ end
87
+
88
+ base << "\n#{prefix}}"
89
+ base
90
+ end
91
+ end
92
+
93
+ class ServerInfo
94
+ attr_accessor :name, :ip_address, :state, :port, :type
95
+
96
+ def initialize(raw_response, index)
97
+ @name = raw_response[:servicename][:item]
98
+ @ip_address = raw_response[:svcipaddress][:item]
99
+ @state = raw_response[:svcstate][:item]
100
+ @port = raw_response[:svcport][:item]
101
+ @type = raw_response[:svctype][:item]
102
+
103
+ if !index.nil?
104
+ @name = @name[i]
105
+ @ip_address = @ip_address[i]
106
+ @state = @state[i]
107
+ @port = @port[i]
108
+ @type = @type[i]
109
+ end
110
+ end
111
+
112
+ def to_s
113
+ sprintf "%-26s %15s %18s %10s %10s", name, ip_address, state, port, type
114
+ end
115
+
116
+ def to_json(prefix=nil)
117
+ indent = if prefix
118
+ ' ' + prefix
119
+ else
120
+ ' '
121
+ end
122
+ "{\n#{indent}'name': '#{'here' + name}',\n#{indent}'ip_address': '#{ip_address}',\n#{indent}'state': '#{state}',\n#{indent}'port': #{port},\n#{indent}'type': '#{type}'\n#{prefix}}"
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,140 @@
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 services" do
59
+ it "should fail when the service is given to a non-list action" do
60
+ attempting {
61
+ parse('-n', 'else', 'service', '-a', 'disable')
62
+ }.should raise_error(Choosy::ValidationError, /no services given to act/)
63
+ end
64
+
65
+ it "should fail when --vserver flag is used with a non-bind/unbind action" do
66
+ attempting {
67
+ parse('-n', 'else', 'service', '-a', 'disable', '-v', 'blarg', 'a-service')
68
+ }.should raise_error(Choosy::ValidationError, /only used with bind/)
69
+ end
70
+
71
+ it "should fail when the --vserver flag is not present with the bind/unbind action" do
72
+ attempting {
73
+ parse('-n', 'else', 'service', '-a', 'bind', 'a-service')
74
+ }.should raise_error(Choosy::ValidationError, /requires the -v\/--vserver flag/)
75
+ end
76
+
77
+ it "should succeed in setting the service name as an argument" do
78
+ res = parse('-n', 'else', 'service', '-a', 'bind', '-v', 'blah', 'a-service')
79
+ res.subresults[0].args[0].should eql('a-service')
80
+ end
81
+
82
+ it "should succed in setting the vserver name" do
83
+ res = parse('-n', 'else', 'service', '-a', 'bind', '-v', 'blah', 'a-service')
84
+ res.subresults[0][:vserver].should eql('blah')
85
+ end
86
+
87
+ it "should succeed in setting the action" do
88
+ res = parse('-n', 'else', 'service', '-a', 'bind', '-v', 'blah', 'a-service')
89
+ res.subresults[0][:action].should eql(:bind)
90
+ end
91
+
92
+ it "should set the default action to status" do
93
+ res = parse('-n', 'else', 'service', 'a-service')
94
+ res.subresults[0][:action].should eql(:status)
95
+ end
96
+ end
97
+
98
+ describe "for vserver" do
99
+ it "should fail when the vserver is given to a non-list option" do
100
+ attempting {
101
+ parse('-n', 'else', 'vserver', '-a', 'disable')
102
+ }.should raise_error(Choosy::ValidationError, /no virtual server/)
103
+ end
104
+
105
+ it "should fail when the --policy flag is unset on a bind/unbind" do
106
+ attempting {
107
+ parse('-n', 'else', 'vserver', '-a', 'bind', 'vserv')
108
+ }.should raise_error(Choosy::ValidationError, /required by the 'bind\/unbind' actions/)
109
+ end
110
+
111
+ it "should fail when the --policy flag is used on anything other than bind/unbind" do
112
+ attempting {
113
+ parse('-n', 'else', 'vserver', '-a', 'disable', '-p', 'pol', 'vserv')
114
+ }.should raise_error(Choosy::ValidationError, /only used with bind/)
115
+ end
116
+
117
+ it "should fail when priority flag is used on anything other than a bind" do
118
+ attempting {
119
+ parse('-n', 'else', 'vserver', '-a', 'disable', '-P', '20', 'vserv')
120
+ }.should raise_error(Choosy::ValidationError, /only used with the bind action/)
121
+ end
122
+
123
+ it "should set the default value for the priority to 100" do
124
+ res = parse('-n', 'else', 'vserver', '-a', 'bind', '-p', 'pol', 'vserv')
125
+ res.subresults[0][:Priority].should eql(100)
126
+ end
127
+
128
+ it "should set the policy name" do
129
+ res = parse('-n', 'else', 'vserver', '-a', 'bind', '-p', 'pol', 'vserv')
130
+ res.subresults[0][:policy].should eql('pol')
131
+ end
132
+
133
+ it "should fail on a bad action" do
134
+ attempting {
135
+ parse('-n', 'else', 'vserver', '-a', 'asdf', 'vserv')
136
+ }.should raise_error(Choosy::ValidationError, /unrecognized value/)
137
+ end
138
+ end
139
+ end
140
+ end