netscaler-cli 0.2.3 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source :rubygems
2
+
3
+ gem 'log4r', '~> 1.1'
4
+ gem 'savon', '~> 0.7'
5
+ gem 'highline', '>= 1.6'
6
+
7
+ group :test do
8
+ gem 'rspec'
9
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,28 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ builder (3.0.0)
5
+ crack (0.1.8)
6
+ diff-lcs (1.1.2)
7
+ highline (1.6.1)
8
+ log4r (1.1.9)
9
+ rspec (2.2.0)
10
+ rspec-core (~> 2.2)
11
+ rspec-expectations (~> 2.2)
12
+ rspec-mocks (~> 2.2)
13
+ rspec-core (2.2.1)
14
+ rspec-expectations (2.2.0)
15
+ diff-lcs (~> 1.1.2)
16
+ rspec-mocks (2.2.0)
17
+ savon (0.7.9)
18
+ builder (>= 2.1.2)
19
+ crack (>= 0.1.4)
20
+
21
+ PLATFORMS
22
+ ruby
23
+
24
+ DEPENDENCIES
25
+ highline (>= 1.6)
26
+ log4r (~> 1.1)
27
+ rspec
28
+ savon (~> 0.7)
data/README.markdown CHANGED
@@ -12,9 +12,12 @@ The command line tools can be installed with:
12
12
 
13
13
  The following commands are currently a part of the system:
14
14
 
15
- * *netscaler-vserver* -- An interface for enabling, disabling, and binding responder policies to a specific virtual server.
16
- * *netscaler-service* -- An interface for enabling, disabling, and binding virtual servers to specific service.
15
+ * *netscaler-vserver* -- An interface for enabling, disabling, querying, and binding responder policies to a specific virtual server.
16
+ * *netscaler-service* -- An interface for enabling, disabling, querying, and binding servers to specific services.
17
+ * *netscaler-server* -- An interface for enabling, disabling, querying, and binding servers to virtual servers.
17
18
 
19
+ Each command requires at least the --netscaler flag (which can be the full netscaler host name in the configuration file, or its alias, see below).
20
+
18
21
  # Configuration
19
22
 
20
23
  All of the commands rely upon a configuration file in the YAML format. By default, it looks for a file in your home directory
@@ -23,8 +26,9 @@ All of the commands rely upon a configuration file in the YAML format. By defau
23
26
 
24
27
  Each load balancer requires an entry in the file in the form:
25
28
 
26
- netscaler.loadbalancer.somecompany.com
29
+ netscaler.loadbalancer.somecompany.com:
27
30
  username: 'some.username'
28
31
  password: 'super!duper!secret!'
32
+ alias: prod
29
33
 
30
- Multiple entries can be in the file; the password setting is not required. If it is not given in the file, the tool will ask you for it.
34
+ Multiple entries can be in the file; the password and the alias settings are not required. An alias can be used as a shortcut name on the command line for a particular netscaler server. However, if no password is given in the file for a given configuration, the tool will ask you for it.
data/Rakefile CHANGED
@@ -28,11 +28,11 @@ begin
28
28
  gem.homepage = 'http://github.com/gabemc/netscaler-cli'
29
29
  gem.files = FileList["[A-Z]*", "{bin,lib,spec}/**/*"]
30
30
 
31
- gem.add_dependency 'highline', '>=1.5.2'
32
- gem.add_dependency 'log4r', '>=1.1.7'
31
+ gem.add_dependency 'log4r', '>=1.1.9'
33
32
  gem.add_dependency 'savon', '>=0.7.9'
33
+ gem.add_dependency 'highline', '>=1.6'
34
34
 
35
- gem.add_development_dependency 'rspec', '>=2.0.1'
35
+ gem.add_development_dependency 'rspec', '>=2.2.0'
36
36
  end
37
37
  rescue LoadError
38
38
  puts "Jeweler or dependencies are not available. Install it with: sudo gem install jeweler"
@@ -4,7 +4,7 @@ module Netscaler
4
4
  class BaseExecutor
5
5
  include Netscaler::Logging
6
6
 
7
- attr_reader :host, :client
7
+ attr_reader :host, :client, :json
8
8
 
9
9
  def initialize(host, client)
10
10
  @host = host
@@ -32,16 +32,14 @@ module Netscaler
32
32
  log.debug(result)
33
33
 
34
34
  response = result.to_hash["#{name.to_s}_response".to_sym]
35
- if block_given?
35
+ msg = response[:return][:message]
36
+ if msg !~ /^Done$/
37
+ log.error(response[:return][:message])
38
+ exit(1)
39
+ elsif block_given?
36
40
  yield response
37
- else
38
- msg = response[:return][:message]
39
- if msg !~ /^Done$/
40
- log.error(response[:return][:message])
41
- exit(1)
42
- else
43
- log.debug(msg)
44
- end
41
+ else
42
+ log.debug(msg)
45
43
  end
46
44
 
47
45
  result
@@ -78,6 +78,10 @@ module Netscaler
78
78
  "Prints extra debug information") do |d|
79
79
  options[:debug] = d
80
80
  end
81
+ opts.on('--json',
82
+ "Prints out JSON data instead of textual output.") do |j|
83
+ options[:json] = j
84
+ end
81
85
  opts.on('-v', '--version',
82
86
  "Show the version information") do |v|
83
87
  puts "#{File.basename($0)} version: #{Netscaler::Version.to_s}"
@@ -10,17 +10,22 @@ module Netscaler
10
10
  @servers = read_config_file(file)
11
11
  end
12
12
 
13
- def [](host)
14
- found = @servers[host]
15
- if found.nil?
16
- raise Netscaler::ConfigurationError.new("The specified Netscaler host was not found")
13
+ def [](name)
14
+ # First, try the aliases
15
+ @servers.each_key do |lbname|
16
+ found = @servers[lbname]
17
+ if found['alias'] == name
18
+ return create_config(lbname, found)
19
+ end
17
20
  end
18
21
 
19
- if found['username'].nil?
20
- raise Netscaler::ConfigurationError.new("No username was specified for the given Netscaler host")
22
+ # Next, check the actual server names
23
+ found = @servers[name]
24
+ if found.nil?
25
+ raise Netscaler::ConfigurationError.new("The specified Netscaler host was not found")
21
26
  end
22
27
 
23
- Configuration.new(host, found['username'], found['password'])
28
+ return create_config(name, found)
24
29
  end
25
30
 
26
31
  def load_balancers
@@ -28,6 +33,14 @@ module Netscaler
28
33
  end
29
34
 
30
35
  private
36
+ def create_config(lbname, yaml)
37
+ if yaml['username'].nil?
38
+ raise Netscaler::ConfigurationError.new("No username was specified for the given Netscaler host")
39
+ end
40
+
41
+ Configuration.new(lbname, yaml['username'], yaml['password'], yaml['alias'])
42
+ end
43
+
31
44
  def read_config_file(file)
32
45
  if file.nil?
33
46
  file = File.expand_path(".netscaler-cli.yml", Etc.getpwuid.dir)
@@ -47,12 +60,13 @@ module Netscaler
47
60
  end
48
61
 
49
62
  class Configuration
50
- attr_reader :host, :username, :password
63
+ attr_reader :host, :username, :password, :alias
51
64
 
52
- def initialize(host, username, password=nil)
65
+ def initialize(host, username, password=nil, nalias=nil)
53
66
  @host = host
54
67
  @username = username
55
68
  @password = password
69
+ @alias = nalias
56
70
 
57
71
  query_password
58
72
  end
@@ -17,11 +17,59 @@ module Netscaler::Server
17
17
 
18
18
  def status(options)
19
19
  send_request('getserver', @params) do |response|
20
- info = response[:return][:list][:item]
21
- puts "Name: #{info[:name]}"
22
- puts "IP Address: #{info[:ipaddress]}"
23
- puts "State: #{info[:state]}"
20
+ resp = Response.new(response)
21
+ if options[:json]
22
+ puts resp.to_json
23
+ else
24
+ puts resp.to_s
25
+ end
24
26
  end
25
27
  end
26
28
  end
29
+
30
+ class Response
31
+ attr_reader :raw_response, :info
32
+
33
+ def initialize(raw_response)
34
+ @raw_response = raw_response
35
+ @info = raw_response[:return][:list][:item]
36
+ end
37
+
38
+ def name
39
+ info[:name]
40
+ end
41
+
42
+ def ip_address
43
+ info[:ipaddress]
44
+ end
45
+
46
+ def state
47
+ info[:state]
48
+ end
49
+
50
+ def services
51
+ info[:servicename][:item]
52
+ end
53
+
54
+ def to_s
55
+ base = "Name:\t#{name}\nIP Address:\t#{ip_address}\nState:\t#{state}\nServices:\n"
56
+ services.each do |service|
57
+ base << "\t#{service}\n"
58
+ end
59
+ base
60
+ end
61
+
62
+ def to_json
63
+ base = "{ 'name': '#{name}', 'ip_address': '#{ip_address}', 'state': '#{state}', 'services': ["
64
+
65
+ services.each_with_index do |service, i|
66
+ base << "'#{service}'"
67
+ if i != services.length - 1
68
+ base << ", "
69
+ end
70
+ end
71
+
72
+ base << "] }"
73
+ end
74
+ end
27
75
  end
@@ -19,25 +19,12 @@ module Netscaler::Service
19
19
  send_request('disableservice', params)
20
20
  end
21
21
 
22
- def status(options)
23
- send_request('getservice', @params) do |response|
24
- info = response[:return][:list][:item]
25
- puts "Name: #{info[:name]}"
26
- puts "IP Address: #{info[:ipaddress]}"
27
- puts "Port: #{info[:port]}"
28
- puts "State: #{info[:svrstate]}"
29
- end
30
- end
31
-
32
22
  def bind(options)
33
23
  params = {
34
24
  :name => options[:vserver],
35
25
  :servicename => host
36
26
  }
37
- send_request('bindlbvserver_service', params) do |response|
38
- #require 'pp'
39
- #pp response
40
- end
27
+ send_request('bindlbvserver_service', params)
41
28
  end
42
29
 
43
30
  def unbind(options)
@@ -45,10 +32,51 @@ module Netscaler::Service
45
32
  :name => options[:vserver],
46
33
  :servicename => host
47
34
  }
48
- send_request('unbindlbvserver_service', params) do |response|
49
- #require 'pp'
50
- #pp response
35
+ send_request('unbindlbvserver_service', params)
36
+ end
37
+
38
+ def status(options)
39
+ send_request('getservice', @params) do |response|
40
+ resp = Response.new(response)
41
+ if options[:json]
42
+ puts resp.to_json
43
+ else
44
+ puts resp.to_s
45
+ end
51
46
  end
52
47
  end
53
48
  end
49
+
50
+ class Response
51
+ attr_reader :raw_response, :info
52
+
53
+ def initialize(raw_response)
54
+ @raw_response = raw_response
55
+ @info = raw_response[:return][:list][:item]
56
+ end
57
+
58
+ def name
59
+ info[:name]
60
+ end
61
+
62
+ def ip_address
63
+ info[:ipaddress]
64
+ end
65
+
66
+ def state
67
+ info[:svrstate]
68
+ end
69
+
70
+ def port
71
+ info[:port]
72
+ end
73
+
74
+ def to_s
75
+ "Name:\t#{name}\nIP:\t#{ip_address}\nState:\t#{state}\nPort:\t#{port}"
76
+ end
77
+
78
+ def to_json
79
+ "{ 'name': '#{name}', 'ip_address': '#{ip_address}', 'state': '#{state}', 'port': #{port} }"
80
+ end
81
+ end
54
82
  end
@@ -2,7 +2,7 @@ require 'scanf'
2
2
 
3
3
  module Netscaler
4
4
  class Version
5
- CURRENT = File.read(File.dirname(__FILE__) + '/../VERSION')
5
+ CURRENT = File.read(File.join(File.dirname(__FILE__), '..', '..', 'etc', 'Version'))
6
6
  MAJOR, MINOR, TINY = CURRENT.scanf('%d.%d.%d')
7
7
 
8
8
  def self.to_s
@@ -21,13 +21,15 @@ module Netscaler::VServer
21
21
  def status(options)
22
22
  send_request('getlbvserver', @params) do |response|
23
23
  begin
24
- info = response[:return][:list][:item]
25
- puts "Name: #{info[:name]}"
26
- puts "IP Address: #{info[:svcipaddress][:item]}"
27
- puts "Port: #{info[:svcport][:item]}"
28
- puts "State: #{info[:svcstate][:item]}"
24
+ resp = Response.new(response)
25
+ if options[:json]
26
+ puts resp.to_json
27
+ else
28
+ puts resp.to_s
29
+ end
29
30
  rescue Exception => e
30
31
  log.fatal "Unable to lookup any information for host: #{host}"
32
+ puts e
31
33
  exit(1)
32
34
  end
33
35
  end
@@ -54,4 +56,104 @@ module Netscaler::VServer
54
56
  send_request('unbindlbvserver_policy', params)
55
57
  end
56
58
  end
59
+
60
+ class Response
61
+ attr_reader :raw_response, :info
62
+
63
+ def initialize(raw_response)
64
+ @raw_response = raw_response
65
+ @info = raw_response[:return][:list][:item]
66
+ end
67
+
68
+ def name
69
+ info[:name]
70
+ end
71
+
72
+ def ip_address
73
+ if info[:ipaddress] =~ /0\.0\.0\.0/
74
+ info[:ipaddress2]
75
+ else
76
+ info[:ipaddress]
77
+ end
78
+ end
79
+
80
+ def type
81
+ info[:servicetype]
82
+ end
83
+
84
+ def port
85
+ info[:port]
86
+ end
87
+
88
+ def state
89
+ info[:state]
90
+ end
91
+
92
+ def servers
93
+ @parsed_servers ||= []
94
+ if !@parsed_servers.empty?
95
+ return @parsed_servers
96
+ end
97
+
98
+ info[:servicename][:item].each do |name|
99
+ srv = ServerInfo.new
100
+ srv.name = name
101
+ @parsed_servers << srv
102
+ end
103
+
104
+ info[:svcstate][:item].each_with_index do |state, i|
105
+ @parsed_servers[i].state = state
106
+ end
107
+
108
+ info[:svcport][:item].each_with_index do |port, i|
109
+ @parsed_servers[i].port = port
110
+ end
111
+
112
+ info[:svcipaddress][:item].each_with_index do |ip_address, i|
113
+ @parsed_servers[i].ip_address = ip_address
114
+ end
115
+
116
+ info[:svctype][:item].each_with_index do |type, i|
117
+ @parsed_servers[i].type = type
118
+ end
119
+
120
+ @parsed_servers
121
+ end
122
+
123
+ def to_s
124
+ base = "Name:\t#{name}\nIP:\t#{ip_address}\nState:\t#{state}\nPort:\t#{port}\nType:\t#{type}\nServers:\n"
125
+ servers.each do |server|
126
+ base << server.to_s
127
+ base << "\n\n"
128
+ end
129
+ base
130
+ end
131
+
132
+ def to_json
133
+ base = "{ 'name': '#{name}', 'ip_address': '#{ip_address}', 'state': '#{state}', 'port': '#{port}', 'type': #{type}, 'servers': [\n "
134
+
135
+ servers.each_with_index do |server, i|
136
+ base << server.to_json
137
+ if i != servers.length - 1
138
+ base << ",\n "
139
+ else
140
+ base << "\n"
141
+ end
142
+ end
143
+
144
+ base << "] }"
145
+ end
146
+ end
147
+
148
+ class ServerInfo
149
+ attr_accessor :name, :ip_address, :state, :port, :type
150
+
151
+ def to_s
152
+ "\tName:\t#{name}\n\tIP:\t#{ip_address}\n\tState:\t#{state}\n\tPort:\t#{port}\n\tType:\t#{type}"
153
+ end
154
+
155
+ def to_json
156
+ "{ 'name': '#{name}', 'ip_address': '#{ip_address}', 'state': '#{state}', 'port': #{port}, 'type': '#{type}' }"
157
+ end
158
+ end
57
159
  end
data/spec/config_spec.rb CHANGED
@@ -16,7 +16,7 @@ module Netscaler
16
16
 
17
17
  describe "when reading an existing file" do
18
18
  it "should be able to load the basic config file" do
19
- reading('simple-config.yml').load_balancers.length.should eql(1)
19
+ reading('simple-config.yml').load_balancers.length.should eql(2)
20
20
  end
21
21
 
22
22
  it "should set the username and password correctly when set in the file." do
@@ -24,6 +24,12 @@ module Netscaler
24
24
  config.username.should eql('some_user')
25
25
  config.password.should eql('somepass')
26
26
  end
27
+
28
+ it "should load via an alias" do
29
+ config = reading('simple-config.yml')['else']
30
+ config.alias.should eql('else')
31
+ config.username.should eql('here')
32
+ end
27
33
  end
28
34
 
29
35
  describe "when reading a non-existent or bad file" do
@@ -1,3 +1,7 @@
1
1
  something.goes.here:
2
2
  username: some_user
3
- password: somepass
3
+ password: somepass
4
+ something.else:
5
+ username: here
6
+ alias: else
7
+ password: blah
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: netscaler-cli
3
3
  version: !ruby/object:Gem::Version
4
- hash: 17
4
+ hash: 19
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 2
9
8
  - 3
10
- version: 0.2.3
9
+ - 0
10
+ version: 0.3.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Gabe McArthur
@@ -15,45 +15,74 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-11-09 00:00:00 -08:00
18
+ date: 2010-12-03 00:00:00 -08:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
- name: highline
22
+ name: log4r
23
23
  prerelease: false
24
24
  requirement: &id001 !ruby/object:Gem::Requirement
25
25
  none: false
26
26
  requirements:
27
- - - ">="
27
+ - - ~>
28
28
  - !ruby/object:Gem::Version
29
- hash: 7
29
+ hash: 13
30
30
  segments:
31
31
  - 1
32
- - 5
33
- - 2
34
- version: 1.5.2
32
+ - 1
33
+ version: "1.1"
35
34
  type: :runtime
36
35
  version_requirements: *id001
37
36
  - !ruby/object:Gem::Dependency
38
- name: log4r
37
+ name: savon
39
38
  prerelease: false
40
39
  requirement: &id002 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ~>
43
+ - !ruby/object:Gem::Version
44
+ hash: 5
45
+ segments:
46
+ - 0
47
+ - 7
48
+ version: "0.7"
49
+ type: :runtime
50
+ version_requirements: *id002
51
+ - !ruby/object:Gem::Dependency
52
+ name: highline
53
+ prerelease: false
54
+ requirement: &id003 !ruby/object:Gem::Requirement
41
55
  none: false
42
56
  requirements:
43
57
  - - ">="
44
58
  - !ruby/object:Gem::Version
45
- hash: 29
59
+ hash: 3
46
60
  segments:
47
61
  - 1
62
+ - 6
63
+ version: "1.6"
64
+ type: :runtime
65
+ version_requirements: *id003
66
+ - !ruby/object:Gem::Dependency
67
+ name: log4r
68
+ prerelease: false
69
+ requirement: &id004 !ruby/object:Gem::Requirement
70
+ none: false
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ hash: 1
75
+ segments:
48
76
  - 1
49
- - 7
50
- version: 1.1.7
77
+ - 1
78
+ - 9
79
+ version: 1.1.9
51
80
  type: :runtime
52
- version_requirements: *id002
81
+ version_requirements: *id004
53
82
  - !ruby/object:Gem::Dependency
54
83
  name: savon
55
84
  prerelease: false
56
- requirement: &id003 !ruby/object:Gem::Requirement
85
+ requirement: &id005 !ruby/object:Gem::Requirement
57
86
  none: false
58
87
  requirements:
59
88
  - - ">="
@@ -65,23 +94,38 @@ dependencies:
65
94
  - 9
66
95
  version: 0.7.9
67
96
  type: :runtime
68
- version_requirements: *id003
97
+ version_requirements: *id005
98
+ - !ruby/object:Gem::Dependency
99
+ name: highline
100
+ prerelease: false
101
+ requirement: &id006 !ruby/object:Gem::Requirement
102
+ none: false
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ hash: 3
107
+ segments:
108
+ - 1
109
+ - 6
110
+ version: "1.6"
111
+ type: :runtime
112
+ version_requirements: *id006
69
113
  - !ruby/object:Gem::Dependency
70
114
  name: rspec
71
115
  prerelease: false
72
- requirement: &id004 !ruby/object:Gem::Requirement
116
+ requirement: &id007 !ruby/object:Gem::Requirement
73
117
  none: false
74
118
  requirements:
75
119
  - - ">="
76
120
  - !ruby/object:Gem::Version
77
- hash: 13
121
+ hash: 7
78
122
  segments:
79
123
  - 2
124
+ - 2
80
125
  - 0
81
- - 1
82
- version: 2.0.1
126
+ version: 2.2.0
83
127
  type: :development
84
- version_requirements: *id004
128
+ version_requirements: *id007
85
129
  description: This gem installs several simple command line utilities locally. It uses the NSConfig.wsdl SOAP interface for remote access.
86
130
  email:
87
131
  - madeonamac@gmail.com
@@ -94,12 +138,13 @@ extensions: []
94
138
  extra_rdoc_files:
95
139
  - README.markdown
96
140
  files:
141
+ - Gemfile
142
+ - Gemfile.lock
97
143
  - README.markdown
98
144
  - Rakefile
99
145
  - bin/netscaler-server
100
146
  - bin/netscaler-service
101
147
  - bin/netscaler-vserver
102
- - lib/VERSION
103
148
  - lib/netscaler/baseexecutor.rb
104
149
  - lib/netscaler/clitemplate.rb
105
150
  - lib/netscaler/config.rb
@@ -126,8 +171,8 @@ homepage: http://github.com/gabemc/netscaler-cli
126
171
  licenses: []
127
172
 
128
173
  post_install_message:
129
- rdoc_options:
130
- - --charset=UTF-8
174
+ rdoc_options: []
175
+
131
176
  require_paths:
132
177
  - lib
133
178
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -156,8 +201,8 @@ signing_key:
156
201
  specification_version: 3
157
202
  summary: Simple command line utilities for interacting remotely with a Netscaler load balancer.
158
203
  test_files:
159
- - spec/vserver/cli_spec.rb
204
+ - spec/config_spec.rb
160
205
  - spec/helpers.rb
161
206
  - spec/server/cli_spec.rb
162
207
  - spec/service/cli_spec.rb
163
- - spec/config_spec.rb
208
+ - spec/vserver/cli_spec.rb
data/lib/VERSION DELETED
@@ -1 +0,0 @@
1
- 0.2.3