knife-cisco_asa 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +18 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +5 -0
- data/README.md +68 -0
- data/Rakefile +2 -0
- data/knife-cisco_asa.gemspec +18 -0
- data/lib/chef/knife/BaseCiscoAsaCommand.rb +104 -0
- data/lib/chef/knife/cisco_asa_host_add.rb +100 -0
- data/lib/chef/knife/cisco_asa_host_remove.rb +70 -0
- data/lib/knife-cisco_asa/version.rb +5 -0
- metadata +71 -0
data/.gitignore
ADDED
data/CHANGELOG.md
ADDED
data/README.md
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
# knife-cisco_asa
|
2
|
+
|
3
|
+
A knife plugin for managing Cisco ASA devices.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Uses [cisco rubygem](https://github.com/jtimberman/ruby-cisco) for the backend.
|
8
|
+
|
9
|
+
* `gem install knife-cisco_asa` (if using omnibus install, `/opt/chef/embedded/bin/gem install knife-cisco_asa`)
|
10
|
+
* or... copy `lib/chef/knife/*` files to `~/.chef/plugins/knife`
|
11
|
+
* or... copy `lib/chef/knife/*` files to `path/to/cheforg/.chef/plugins/knife`
|
12
|
+
|
13
|
+
## Usage
|
14
|
+
|
15
|
+
### Common parameters
|
16
|
+
|
17
|
+
Configuration in knife.rb:
|
18
|
+
* `knife[:cisco_asa_enable_password] = "ENABLE_PASSWORD"` - Enable password for Cisco ASA
|
19
|
+
* `knife[:cisco_asa_hostname] = "HOSTNAME"` - Cisco ASA hostname
|
20
|
+
* `knife[:cisco_asa_password] = "PASSWORD"` - Cisco ASA user password
|
21
|
+
* `knife[:cisco_asa_usernamename] = "USERNAME"` - Cisco ASA username
|
22
|
+
|
23
|
+
Otherwise, from the command line:
|
24
|
+
* `--cisco-asa-enable-password ENABLE_PASSWORD` - Enable password for Cisco ASA
|
25
|
+
* `--cisco-asa-hostname HOSTNAME` - Cisco ASA hostname
|
26
|
+
* `--cisco-asa-password PASSWORD` - Cisco ASA user password
|
27
|
+
* `--cisco-asa-username USERNAME` - Cisco ASA username
|
28
|
+
* `--noop` - Perform no modifying operations
|
29
|
+
|
30
|
+
Any missing user or enable password will be prompted at runtime.
|
31
|
+
|
32
|
+
### `knife cicso asa host add NAME IP`
|
33
|
+
|
34
|
+
Adds a host to the device.
|
35
|
+
|
36
|
+
* `--description DESCRIPTION` - optionally set a description for the host
|
37
|
+
* `--groups GROUP1[,GROUP2]` - optionally add host to object groups
|
38
|
+
* `--nat IP` - optionally setup static NAT IP
|
39
|
+
* `--nat-dns` - optionally enable DNS translation for NAT
|
40
|
+
|
41
|
+
### `knife cicso asa host remove NAME`
|
42
|
+
|
43
|
+
Removes a host from the device.
|
44
|
+
|
45
|
+
* `--groups GROUP1[,GROUP2]` - required to remove hosts in groups
|
46
|
+
* `--nat IP` - required to remove hosts with static NAT IP
|
47
|
+
|
48
|
+
## Contributing
|
49
|
+
|
50
|
+
Please use standard Github issues and pull requests.
|
51
|
+
|
52
|
+
## License and Author
|
53
|
+
|
54
|
+
Author:: Brian Flad (<bflad417@gmail.com>)
|
55
|
+
|
56
|
+
Copyright:: 2013
|
57
|
+
|
58
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
59
|
+
you may not use this file except in compliance with the License.
|
60
|
+
You may obtain a copy of the License at
|
61
|
+
|
62
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
63
|
+
|
64
|
+
Unless required by applicable law or agreed to in writing, software
|
65
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
66
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
67
|
+
See the License for the specific language governing permissions and
|
68
|
+
limitations under the License.
|
data/Rakefile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/knife-cisco_asa/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Brian Flad"]
|
6
|
+
gem.email = ["bflad417@gmail.com"]
|
7
|
+
gem.description = %q{A knife plugin for managing Cisco ASA devices.}
|
8
|
+
gem.summary = gem.summary
|
9
|
+
gem.homepage = "https://github.com/bflad/knife-cisco_asa"
|
10
|
+
|
11
|
+
gem.add_runtime_dependency "cisco"
|
12
|
+
|
13
|
+
gem.files = `git ls-files`.split($\)
|
14
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
15
|
+
gem.name = "knife-cisco_asa"
|
16
|
+
gem.require_paths = ["lib"]
|
17
|
+
gem.version = Knife::CiscoAsa::VERSION
|
18
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Brian Flad (<bflad417@gmail.com>)
|
3
|
+
# License:: Apache License, Version 2.0
|
4
|
+
#
|
5
|
+
|
6
|
+
module CiscoAsaKnifePlugin
|
7
|
+
|
8
|
+
require 'chef/knife'
|
9
|
+
require 'cisco'
|
10
|
+
require 'highline/import'
|
11
|
+
|
12
|
+
class BaseCiscoAsaCommand < Chef::Knife
|
13
|
+
|
14
|
+
deps do
|
15
|
+
require 'highline/import'
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.get_common_options
|
19
|
+
unless defined? $default
|
20
|
+
$default = Hash.new
|
21
|
+
end
|
22
|
+
|
23
|
+
option :cisco_asa_enable_password,
|
24
|
+
:short => "-E PASSWORD",
|
25
|
+
:long => "--cisco-asa-enable-password PASSWORD",
|
26
|
+
:description => "Enable password for Cisco ASA"
|
27
|
+
|
28
|
+
ption :cisco_asa_hostname,
|
29
|
+
:short => "-h HOSTNAME",
|
30
|
+
:long => "--cisco-asa-hostname HOSTNAME",
|
31
|
+
:description => "The hostname for Cisco ASA"
|
32
|
+
|
33
|
+
option :cisco_asa_password,
|
34
|
+
:short => "-p PASSWORD",
|
35
|
+
:long => "--cisco-asa-password PASSWORD",
|
36
|
+
:description => "The password for Cisco ASA"
|
37
|
+
|
38
|
+
option :cisco_asa_username,
|
39
|
+
:short => "-u USERNAME",
|
40
|
+
:long => "--cisco-asa-username USERNAME",
|
41
|
+
:description => "The username for Cisco ASA"
|
42
|
+
$default[:cisco_asa_username] = ENV['USER']
|
43
|
+
|
44
|
+
option :noop,
|
45
|
+
:long => "--noop",
|
46
|
+
:description => "Perform no modifying operations",
|
47
|
+
:boolean => false
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
def get_config(key)
|
52
|
+
key = key.to_sym
|
53
|
+
rval = config[key] || Chef::Config[:knife][key] || $default[key]
|
54
|
+
Chef::Log.debug("value for config item #{key}: #{rval}")
|
55
|
+
rval
|
56
|
+
end
|
57
|
+
|
58
|
+
def get_cisco_asa_config
|
59
|
+
config[:cisco_asa_password] = ask("Cisco Password for #{get_config(:cisco_asa_username)}: ") { |q| q.echo = "*" } unless get_config(:cisco_asa_password)
|
60
|
+
config[:cisco_asa_enable_password] = ask("Enable Password for #{get_config(:cisco_asa_host)}: ") { |q| q.echo = "*" } unless get_config(:cisco_asa_enable_password)
|
61
|
+
end
|
62
|
+
|
63
|
+
def run_config_commands(commands)
|
64
|
+
asa = Cisco::Base.new(:host => get_config(:cisco_asa_host), :user => get_config(:cisco_asa_username), :password => get_config(:cisco_asa_password), :transport => :ssh)
|
65
|
+
asa.enable(get_config(:cisco_asa_enable_password))
|
66
|
+
asa.cmd("conf t")
|
67
|
+
commands.each do |command|
|
68
|
+
asa.cmd(command)
|
69
|
+
end
|
70
|
+
asa.cmd("end")
|
71
|
+
asa.cmd("write mem")
|
72
|
+
unless get_config(:noop)
|
73
|
+
output = asa.run
|
74
|
+
output.each do |line|
|
75
|
+
Chef::Log.debug(line)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
output
|
79
|
+
end
|
80
|
+
|
81
|
+
def tcp_test_port(hostname,port)
|
82
|
+
tcp_socket = TCPSocket.new(hostname, port)
|
83
|
+
readable = IO.select([tcp_socket], nil, nil, 5)
|
84
|
+
if readable
|
85
|
+
Chef::Log.debug("sshd accepting connections on #{hostname}, banner is #{tcp_socket.gets}") if port == 22
|
86
|
+
true
|
87
|
+
else
|
88
|
+
false
|
89
|
+
end
|
90
|
+
rescue Errno::ETIMEDOUT
|
91
|
+
false
|
92
|
+
rescue Errno::EPERM
|
93
|
+
false
|
94
|
+
rescue Errno::ECONNREFUSED
|
95
|
+
sleep 2
|
96
|
+
false
|
97
|
+
rescue Errno::EHOSTUNREACH, Errno::ENETUNREACH
|
98
|
+
sleep 2
|
99
|
+
false
|
100
|
+
ensure
|
101
|
+
tcp_socket && tcp_socket.close
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Brian Flad (<bflad417@gmail.com>)
|
3
|
+
# License:: Apache License, Version 2.0
|
4
|
+
#
|
5
|
+
|
6
|
+
module CiscoAsaKnifePlugin
|
7
|
+
|
8
|
+
require 'chef/knife'
|
9
|
+
|
10
|
+
class CiscoAsaHostAdd < BaseCiscoAsaCommand
|
11
|
+
|
12
|
+
banner "knife cisco asa host add NAME IP (options)"
|
13
|
+
category "cisco asa"
|
14
|
+
|
15
|
+
get_common_options
|
16
|
+
|
17
|
+
option :description,
|
18
|
+
:long => "--description DESCRIPTION",
|
19
|
+
:description => "Description of host"
|
20
|
+
|
21
|
+
option :groups,
|
22
|
+
:long => "--groups GROUP1[,GROUP2]",
|
23
|
+
:description => "Groups for host"
|
24
|
+
|
25
|
+
option :nat,
|
26
|
+
:long => "--nat IP",
|
27
|
+
:description => "NAT IP"
|
28
|
+
|
29
|
+
option :nat_dns,
|
30
|
+
:long => "--nat-dns",
|
31
|
+
:description => "Enable NAT DNS translation",
|
32
|
+
:boolean => false
|
33
|
+
|
34
|
+
def run
|
35
|
+
|
36
|
+
hostname = name_args.first
|
37
|
+
|
38
|
+
if hostname.nil?
|
39
|
+
ui.fatal "You need a host name!"
|
40
|
+
show_usage
|
41
|
+
exit 1
|
42
|
+
end
|
43
|
+
|
44
|
+
ip = name_args[1]
|
45
|
+
|
46
|
+
if ip.nil?
|
47
|
+
ui.fatal "You need an IP!"
|
48
|
+
show_usage
|
49
|
+
exit 1
|
50
|
+
end
|
51
|
+
|
52
|
+
args = name_args[2]
|
53
|
+
if args.nil?
|
54
|
+
args = ""
|
55
|
+
end
|
56
|
+
|
57
|
+
get_cisco_asa_config
|
58
|
+
commands = []
|
59
|
+
|
60
|
+
ui.info "Adding host to Cisco ASA:"
|
61
|
+
ui.info "#{ui.color "ASA:", :cyan} #{get_config(:cisco_asa_host)}"
|
62
|
+
ui.info "#{ui.color "Host:", :cyan} #{hostname}"
|
63
|
+
ui.info "#{ui.color "IP:", :cyan} #{ip}"
|
64
|
+
|
65
|
+
commands << "object network #{hostname}"
|
66
|
+
commands << " host #{ip}"
|
67
|
+
|
68
|
+
if get_config(:description)
|
69
|
+
ui.info "#{ui.color "Description:", :cyan} #{get_config(:description)}"
|
70
|
+
commands << " description #{get_config(:description)}"
|
71
|
+
end
|
72
|
+
|
73
|
+
if get_config(:nat)
|
74
|
+
ui.info "#{ui.color "NAT IP:", :cyan} #{get_config(:nat)}"
|
75
|
+
command = " nat static #{get_config(:nat)}"
|
76
|
+
if get_config(:nat_dns)
|
77
|
+
ui.info "#{ui.color "NAT DNS:", :cyan} Enabled"
|
78
|
+
command = command + " dns"
|
79
|
+
end
|
80
|
+
commands << command
|
81
|
+
end
|
82
|
+
|
83
|
+
if get_config(:groups)
|
84
|
+
get_config(:groups).split(",").each do |group|
|
85
|
+
ui.info "#{ui.color "Group:", :cyan} #{group}"
|
86
|
+
commands << "object-group network #{group}"
|
87
|
+
commands << " network-object object #{hostname}"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
if get_config(:noop)
|
92
|
+
ui.info "#{ui.color "Skipping host creation process because --noop specified.", :red}"
|
93
|
+
else
|
94
|
+
run_config_commands(commands)
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Brian Flad (<bflad417@gmail.com>)
|
3
|
+
# License:: Apache License, Version 2.0
|
4
|
+
#
|
5
|
+
|
6
|
+
module CiscoAsaKnifePlugin
|
7
|
+
|
8
|
+
require 'chef/knife'
|
9
|
+
|
10
|
+
class CiscoAsaHostRemove < BaseCiscoAsaCommand
|
11
|
+
|
12
|
+
banner "knife cisco asa host remove NAME (options)"
|
13
|
+
category "cisco asa"
|
14
|
+
|
15
|
+
get_common_options
|
16
|
+
|
17
|
+
option :groups,
|
18
|
+
:long => "--groups GROUP[,GROUP2]",
|
19
|
+
:description => "Groups for host"
|
20
|
+
|
21
|
+
option :nat,
|
22
|
+
:long => "--nat IP",
|
23
|
+
:description => "NAT IP"
|
24
|
+
|
25
|
+
def run
|
26
|
+
|
27
|
+
hostname = name_args.first.upcase
|
28
|
+
|
29
|
+
if hostname.nil?
|
30
|
+
ui.fatal "You need a host name!"
|
31
|
+
show_usage
|
32
|
+
exit 1
|
33
|
+
end
|
34
|
+
|
35
|
+
args = name_args[1]
|
36
|
+
if args.nil?
|
37
|
+
args = ""
|
38
|
+
end
|
39
|
+
|
40
|
+
get_cisco_asa_config
|
41
|
+
commands = []
|
42
|
+
|
43
|
+
ui.info "Removing host from Cisco ASA:"
|
44
|
+
ui.info "#{ui.color "ASA:", :cyan} #{get_config(:cisco_asa_host)}"
|
45
|
+
ui.info "#{ui.color "Host:", :cyan} #{hostname}"
|
46
|
+
ui.info "#{ui.color "NAT IP:", :cyan} #{natip}"
|
47
|
+
|
48
|
+
commands << "object network #{hostname}"
|
49
|
+
commands << " no nat (inside,outside) static #{natip} dns"
|
50
|
+
|
51
|
+
if get_config(:groups)
|
52
|
+
get_config(:groups).split(",").each do |group|
|
53
|
+
ui.info "#{ui.color "Group:", :cyan} #{group}"
|
54
|
+
commands << "object-group network #{group}"
|
55
|
+
commands << " no network-object object #{hostname}"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
commands << "no object network #{hostname}"
|
60
|
+
|
61
|
+
if get_config(:noop)
|
62
|
+
ui.info "#{ui.color "Skipping host removal process because --noop specified.", :red}"
|
63
|
+
else
|
64
|
+
run_config_commands(commands)
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
end
|
metadata
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: knife-cisco_asa
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Brian Flad
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-02-17 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: cisco
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
description: A knife plugin for managing Cisco ASA devices.
|
31
|
+
email:
|
32
|
+
- bflad417@gmail.com
|
33
|
+
executables: []
|
34
|
+
extensions: []
|
35
|
+
extra_rdoc_files: []
|
36
|
+
files:
|
37
|
+
- .gitignore
|
38
|
+
- CHANGELOG.md
|
39
|
+
- Gemfile
|
40
|
+
- README.md
|
41
|
+
- Rakefile
|
42
|
+
- knife-cisco_asa.gemspec
|
43
|
+
- lib/chef/knife/BaseCiscoAsaCommand.rb
|
44
|
+
- lib/chef/knife/cisco_asa_host_add.rb
|
45
|
+
- lib/chef/knife/cisco_asa_host_remove.rb
|
46
|
+
- lib/knife-cisco_asa/version.rb
|
47
|
+
homepage: https://github.com/bflad/knife-cisco_asa
|
48
|
+
licenses: []
|
49
|
+
post_install_message:
|
50
|
+
rdoc_options: []
|
51
|
+
require_paths:
|
52
|
+
- lib
|
53
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - ! '>='
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: '0'
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
|
+
none: false
|
61
|
+
requirements:
|
62
|
+
- - ! '>='
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: '0'
|
65
|
+
requirements: []
|
66
|
+
rubyforge_project:
|
67
|
+
rubygems_version: 1.8.23
|
68
|
+
signing_key:
|
69
|
+
specification_version: 3
|
70
|
+
summary: ''
|
71
|
+
test_files: []
|