netscaler-cli 0.3.3 → 0.4.0

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.
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