Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(FM-7602) Implement Resource API transports for bolt and ACE #73

Merged
merged 13 commits into from
Mar 14, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
/convert_report.txt
/update_report.txt
.DS_Store
.project
.vscode/
.envrc
spec/fixtures/acceptance-credentials.conf
spec/fixtures/acceptance-device.conf
spec/fixtures/config-acceptance.xml
Expand Down
3 changes: 3 additions & 0 deletions .pdkignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
/convert_report.txt
/update_report.txt
.DS_Store
.project
.vscode/
.envrc
/appveyor.yml
/.fixtures.yml
/Gemfile
Expand Down
23 changes: 0 additions & 23 deletions .project

This file was deleted.

1 change: 1 addition & 0 deletions .puppet-lint.rc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--relative
7 changes: 4 additions & 3 deletions .sync.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ Gemfile:
git: 'https://github.com/puppetlabs/puppet-strings.git'
ref: 'master'
- gem: 'puppet-resource_api'
git: 'https://github.com/puppetlabs/puppet-resource_api.git'
ref: 'master'
version: '>= 1.8.1'
# git: 'https://github.com/puppetlabs/puppet-resource_api.git'
# ref: 'master'
# required for internal pipelines
- gem: 'beaker-hostgenerator'
# the first version to contain Palo Alto support
Expand Down Expand Up @@ -46,4 +47,4 @@ spec/spec_helper.rb:
appveyor.yml:
delete: true
.gitlab-ci.yml:
delete: true
delete: true
3 changes: 0 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,6 @@ matrix:
-
env: PUPPET_GEM_VERSION="~> 5.0" CHECK=parallel_spec
rvm: 2.4.4
-
env: PUPPET_GEM_VERSION="~> 4.0" CHECK=parallel_spec RUBYGEMS_VERSION=2.7.8
rvm: 2.1.9
branches:
only:
- master
Expand Down
5 changes: 3 additions & 2 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,16 @@ group :development do
gem "fast_gettext", require: false if Gem::Version.new(RUBY_VERSION.dup) >= Gem::Version.new('2.1.0')
gem "json_pure", '<= 2.0.1', require: false if Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('2.0.0')
gem "json", '= 1.8.1', require: false if Gem::Version.new(RUBY_VERSION.dup) == Gem::Version.new('2.1.9')
gem "json", '<= 2.0.4', require: false if Gem::Version.new(RUBY_VERSION.dup) == Gem::Version.new('2.4.4')
gem "json", '= 2.0.4', require: false if Gem::Requirement.create('~> 2.4.2').satisfied_by?(Gem::Version.new(RUBY_VERSION.dup))
gem "json", '= 2.1.0', require: false if Gem::Requirement.create(['>= 2.5.0', '< 2.7.0']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup))
gem "puppet-module-posix-default-r#{minor_version}", require: false, platforms: [:ruby]
gem "puppet-module-posix-dev-r#{minor_version}", require: false, platforms: [:ruby]
gem "puppet-module-win-default-r#{minor_version}", require: false, platforms: [:mswin, :mingw, :x64_mingw]
gem "puppet-module-win-dev-r#{minor_version}", require: false, platforms: [:mswin, :mingw, :x64_mingw]
gem "webmock", require: false
gem "builder", '~> 3.2.2', require: false
gem "puppet-strings", require: false, git: 'https://github.com/puppetlabs/puppet-strings.git', ref: 'master'
gem "puppet-resource_api", require: false, git: 'https://github.com/puppetlabs/puppet-resource_api.git', ref: 'master'
gem "puppet-resource_api", '>= 1.8.1', require: false
gem "beaker-hostgenerator", '~> 1.1.15', require: false
gem "github_changelog_generator", require: false, git: 'https://github.com/skywinder/github-changelog-generator', ref: '20ee04ba1234e9e83eb2ffb5056e23d641c7a018' if Gem::Version.new(RUBY_VERSION.dup) >= Gem::Version.new('2.2.2')
end
Expand Down
22 changes: 18 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

The PANOS module configures Palo Alto firewalls running PANOS 7.1.0 or PANOS 8.1.0.

When committing changes to resources, include `panos_commit` in your manifest, or execute the `commit` task. You must do this before they can be made available to the running configuration.
When committing changes to resources, include `panos_commit` in your manifest, or execute the `commit` task. You must do this before they can be made available to the running configuration.

The module provides a Puppet task to manually `commit`, `store_config` to a file, and `set_config` from a file.

Expand Down Expand Up @@ -70,13 +70,27 @@ __Note:__ v0.1.0 requires `host` instead of `address`

__Note:__ v0.1.0 requires `user` instead of `username`

To obtain an API key for the device, it is possible to use the `panos::apikey` task. The required creditials file should be in the format of (a) above. After which you can discard it. Before running this task, install the module on your machine, along with [Puppet Bolt](https://puppet.com/docs/bolt/0.x/bolt_installing.html). When complete, execute the following command:
To obtain an API key for the device, it is possible to use the `panos::apikey` task. Before running this task, install the module on your machine, along with [Puppet Bolt](https://puppet.com/docs/bolt/latest/bolt_installing.html). When complete, execute the following command:

```
bolt task run panos::apikey --nodes localhost --transport local --modulepath <module_installation_dir> --params @credentials.json
bolt task run panos::apikey --nodes pan --modulepath <module_installation_dir> --inventoryfile <inventory_yaml_path>
```

The `--modulepath` param can be retrieved by typing `puppet config print modulepath`. The credentials file needs to be valid JSON containing host, username and password for the Palo Alto firewall.
The following [inventory file](https://puppet.com/docs/bolt/latest/inventory_file.html) can be used to connect to your firewall.
```yaml
# inventory.yaml
nodes:
- name: firewall.example.com
alias: pan
config:
transport: remote
remote:
remote-transport: panos
user: admin
password: admin
```

The `--modulepath` param can be retrieved by typing `puppet config print modulepath`.

Test your setup and get the certificate signed:

Expand Down
38 changes: 2 additions & 36 deletions REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

**Tasks**

* [`apikey`](#apikey): Retrieve a PAN-OS apikey using PAN-OS host, username and password.
* [`apikey`](#apikey): Retrieve a PAN-OS apikey
* [`commit`](#commit): Commit a candidate configuration to a firewall.
* [`set_config`](#set_config): upload and/or apply a configuration to a firewall.
* [`store_config`](#store_config): Retrieve the configuration running on the firewall.
Expand Down Expand Up @@ -1711,44 +1711,16 @@ The display-name of the zone.

### apikey

Retrieve a PAN-OS apikey using PAN-OS host, username and password.
Retrieve a PAN-OS apikey

**Supports noop?** false

#### Parameters

##### `host`

Data type: `String`

The host to connect to

##### `user`

Data type: `String`

The user name

##### `password`

Data type: `String`

The password

### commit

Commit a candidate configuration to a firewall.

**Supports noop?** false

#### Parameters

##### `credentials_file`

Data type: `String`

The filename of the credentials file (as referenced in device.conf)

### set_config

upload and/or apply a configuration to a firewall.
Expand All @@ -1757,12 +1729,6 @@ upload and/or apply a configuration to a firewall.

#### Parameters

##### `credentials_file`

Data type: `String`

The filename of the credentials file (as referenced in device.conf)

##### `config_file`

Data type: `String`
Expand Down
2 changes: 1 addition & 1 deletion Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ end

def changelog_future_release
return unless Rake.application.top_level_tasks.include? "changelog"
returnVal = JSON.load(File.read('metadata.json'))['version']
returnVal = "v%s" % JSON.load(File.read('metadata.json'))['version']
raise "unable to find the future_release (version) in metadata.json" if returnVal.nil?
puts "GitHubChangelogGenerator future_release:#{returnVal}"
returnVal
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def canonicalize(_context, resources)
def get(context, xpaths = nil)
return [] if xpaths.nil?
results = []
config = context.device.get_config('/config/' + xpaths.first) unless xpaths.first.nil?
config = context.transport.get_config('/config/' + xpaths.first) unless xpaths.first.nil?
if xpaths.first
config.elements.collect('/response/result') do |entry| # rubocop:disable Style/CollectionMethods
xml = str_from_xml(entry.to_s)
Expand All @@ -48,7 +48,7 @@ def create(context, xpath, should)
raise Puppet::ResourceError, parse_exception.message
end

context.device.set_config('/config/' + xpath, should)
context.transport.set_config('/config/' + xpath, should)
end

def update(context, xpath, should)
Expand All @@ -58,11 +58,11 @@ def update(context, xpath, should)
raise Puppet::ResourceError, parse_exception.message
end

context.device.edit_config('/config/' + xpath, should)
context.transport.edit_config('/config/' + xpath, should)
end

def delete(context, xpath)
context.device.delete_config('/config/' + xpath)
context.transport.delete_config('/config/' + xpath)
end

def str_from_xml(xml)
Expand Down
6 changes: 3 additions & 3 deletions lib/puppet/provider/panos_commit/panos_commit.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@ def get(context)
{
name: 'commit',
# return a value that causes an update if the user requested one
commit: !context.device.outstanding_changes?,
commit: !context.transport.outstanding_changes?,
},
]
end

def set(context, changes)
if context.device.outstanding_changes?
if context.transport.outstanding_changes?
if changes['commit'][:should][:commit]
context.updating('commit') do
context.device.commit
context.transport.commit
end
else
context.info('changes detected, but skipping commit as requested')
Expand Down
8 changes: 4 additions & 4 deletions lib/puppet/provider/panos_path_monitor_base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def xml_from_should(name, should)

def get(context)
results = []
config = context.device.get_config(context.type.definition[:base_xpath] + '/entry')
config = context.transport.get_config(context.type.definition[:base_xpath] + '/entry')
config.elements.collect('/response/result/entry') do |entry| # rubocop:disable Style/CollectionMethods
vr_name = REXML::XPath.match(entry, 'string(@name)').first
config.elements.collect("/response/result/entry[@name='#{vr_name}']/routing-table/#{@version_label}/static-route/entry") do |static_route_entry| # rubocop:disable Style/CollectionMethods
Expand All @@ -51,17 +51,17 @@ def get(context)
def create(context, name, should)
paths = name[:route].split('/')
context.type.definition[:base_xpath] = "/config/devices/entry/network/virtual-router/entry[@name='#{paths[0]}']/routing-table/#{@version_label}/static-route/entry[@name='#{paths[1]}']/path-monitor/monitor-destinations" # rubocop:disable Metrics/LineLength
context.device.set_config(context.type.definition[:base_xpath], xml_from_should(name, should))
context.transport.set_config(context.type.definition[:base_xpath], xml_from_should(name, should))
end

def update(context, name, should)
paths = name[:route].split('/')
context.type.definition[:base_xpath] = "/config/devices/entry/network/virtual-router/entry[@name='#{paths[0]}']/routing-table/#{@version_label}/static-route/entry[@name='#{paths[1]}']/path-monitor/monitor-destinations" # rubocop:disable Metrics/LineLength
context.device.set_config(context.type.definition[:base_xpath], xml_from_should(name, should))
context.transport.set_config(context.type.definition[:base_xpath], xml_from_should(name, should))
end

def delete(context, name)
names = name[:route].split('/')
context.device.delete_config(context.type.definition[:base_xpath] + "/entry[@name='#{names[0]}']/routing-table/#{@version_label}/static-route/entry[@name='#{names[1]}']/path-monitor/monitor-destinations/entry[@name='#{name[:path]}']") # rubocop:disable Metrics/LineLength
context.transport.delete_config(context.type.definition[:base_xpath] + "/entry[@name='#{names[0]}']/routing-table/#{@version_label}/static-route/entry[@name='#{names[1]}']/path-monitor/monitor-destinations/entry[@name='#{name[:path]}']") # rubocop:disable Metrics/LineLength
end
end
8 changes: 4 additions & 4 deletions lib/puppet/provider/panos_provider.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ def initialize
end

def get(context)
config = context.device.get_config(context.type.definition[:base_xpath] + '/entry')
config = context.transport.get_config(context.type.definition[:base_xpath] + '/entry')
config.elements.collect('/response/result/entry') do |entry| # rubocop:disable Style/CollectionMethods
result = {}
context.type.attributes.each do |attr_name, attr|
Expand All @@ -21,16 +21,16 @@ def get(context)

def create(context, name, should)
validate_should(should) if defined? validate_should
context.device.set_config(context.type.definition[:base_xpath], xml_from_should(name, should))
context.transport.set_config(context.type.definition[:base_xpath], xml_from_should(name, should))
end

def update(context, name, should)
validate_should(should) if defined? validate_should
context.device.edit_config(context.type.definition[:base_xpath] + "/entry[@name='#{name}']", xml_from_should(name, should))
context.transport.edit_config(context.type.definition[:base_xpath] + "/entry[@name='#{name}']", xml_from_should(name, should))
end

def delete(context, name)
context.device.delete_config(context.type.definition[:base_xpath] + "/entry[@name='#{name}']")
context.transport.delete_config(context.type.definition[:base_xpath] + "/entry[@name='#{name}']")
end

def match(entry, attr, attr_name)
Expand Down
8 changes: 4 additions & 4 deletions lib/puppet/provider/panos_static_route_base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def validate_should(should)
# Overiding the get method, as the base xpath points towards virtual routers, and therefore the base provider's get will only return once for each VR.
def get(context)
results = []
config = context.device.get_config(context.type.definition[:base_xpath] + '/entry')
config = context.transport.get_config(context.type.definition[:base_xpath] + '/entry')
config.elements.collect('/response/result/entry') do |entry| # rubocop:disable Style/CollectionMethods
vr_name = REXML::XPath.match(entry, 'string(@name)').first
# rubocop:disable Style/CollectionMethods
Expand All @@ -84,16 +84,16 @@ def get(context)
def create(context, name, should)
context.type.definition[:base_xpath] = "/config/devices/entry/network/virtual-router/entry[@name='#{name[:vr_name]}']/routing-table/#{@version_label}/static-route"
validate_should(should)
context.device.set_config(context.type.definition[:base_xpath], xml_from_should(name, should))
context.transport.set_config(context.type.definition[:base_xpath], xml_from_should(name, should))
end

def update(context, name, should)
context.type.definition[:base_xpath] = "/config/devices/entry/network/virtual-router/entry[@name='#{name[:vr_name]}']/routing-table/#{@version_label}/static-route"
validate_should(should)
context.device.set_config(context.type.definition[:base_xpath], xml_from_should(name, should))
context.transport.set_config(context.type.definition[:base_xpath], xml_from_should(name, should))
end

def delete(context, name)
context.device.delete_config(context.type.definition[:base_xpath] + "/entry[@name='#{name[:vr_name]}']/routing-table/#{@version_label}/static-route/entry[@name='#{name[:route]}']")
context.transport.delete_config(context.type.definition[:base_xpath] + "/entry[@name='#{name[:vr_name]}']/routing-table/#{@version_label}/static-route/entry[@name='#{name[:route]}']")
end
end
Loading