Skip to content

Commit

Permalink
Merge pull request #15 from aerostitch/add_repo_provider
Browse files Browse the repository at this point in the history
Add repo provider/type
  • Loading branch information
aerostitch authored Aug 22, 2016
2 parents b6b6479 + 1f32526 commit a0deaa2
Show file tree
Hide file tree
Showing 10 changed files with 330 additions and 11 deletions.
60 changes: 52 additions & 8 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
* [Basic example](#basic-example)
* [Enable aptly API endpoint](#enable-aptly-api-endpoint)
* [Create an apt mirror](#create-an-apt-mirror)
* [Create and drop apt repositories](#create-and-drop-apt-repositories)
5. [Reference - An under-the-hood peek at what the module is doing and how](#reference)
* [Public classes and defines](#public-classes-and-defines)
* [Private classes](#private-classes)
Expand All @@ -35,14 +36,14 @@ Need help of want a new feature? File an issue on our github repository: https:/

What is this module capable of doing?

* Install the aptly package in a specific version (or just the latest available)
* Manage a specific user and group (with their corresponding fixed uid/gid) dedicated to the service
* Configure a specific debian repository (optional) where to find the package
* Manage the `/etc/aptly.conf` file
* Enable/start or disable the service
* Enable/start or disable the API
* Manages the init.d service file
* Manage apt mirrors, snapshots, publications
* Installing the aptly package in a specific version (or just the latest available)
* Managing a specific user and group (with their corresponding fixed uid/gid) dedicated to the service
* Configuring a specific debian repository (optional) where to find the package
* Managing the `/etc/aptly.conf` file
* Enabling/starting or disabling the service
* Enabling/starting or disabling the API
* Managing the init.d service file
* Managing apt mirrors, repositories, snapshots and publications

The aptly service will listen on port you configure (example: 80) on every interfaces (configurable)
using the `aptly serve -listen=":80"` command.
Expand Down Expand Up @@ -237,12 +238,33 @@ Exec['debian_stable_key_CBF8D6FD518E17E1']->
Aptly::Mirror['debian_stable']
```

### Create and drop apt repositories

Using the `aptly::repo` is really simple. In this example, we will:
* drop the `my_custom_repo` repository
* create the `tubemogul_apps` repository (with "stable" as default component
for publishing)

Use:
```puppet
# Dropping the 'my_custom_repo' repo
aptly::repo {'my_custom_repo':
ensure => absent,
}
# Making sure that the 'tubemogul_apps' exists with the expected parameters
aptly::repo {'tubemogul_apps':
default_component => 'stable',
}
```

## Reference

### Public classes and defines

* [`aptly`](#class-aptly): Installs and configures the aptly server.
* [`aptly::mirror`](#define-aptlymirror): Manages an aptly mirror.
* [`aptly::repo`](#define-aptlyrepo): Manages an aptly repository.
* [`aptly::snapshot`](#define-aptlysnapshot): Manages an aptly snapshot.
* [`aptly::publish`](#define-aptlypublish): Manages an aptly publication.

Expand All @@ -258,6 +280,7 @@ To manage the aptly resources, this modules embeds the following custom
types and corresponding providers (to be accessed via the public defines):

* `aptly_mirror` to manage an aptly mirror
* `aptly_repo` to manage an aptly repository
* `aptly_snapshot` to manage an aptly snapshot
* `aptly_publish` to manage an aptly publication

Expand Down Expand Up @@ -484,6 +507,27 @@ Download the .udeb packages.

Default: `false`

#### Define aptly::repo

##### `ensure`

Ensures if the repository must be `present` (should exist) or `absent` (or be
destroyed).

Default: `present`

##### `default_distribution`

Default distribution (used only when publishing).

Default: `$::lsbdistcodename`

##### `default_component`

Default component (used only when publishing).

Default: `main`

#### Define aptly::snapshot

##### `source_type`
Expand Down
2 changes: 1 addition & 1 deletion lib/puppet/provider/aptly_publish/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def destroy
def exists?
Puppet.debug("Check if #{name} exists")

[ Puppet_X::Aptly::Cli.execute(object: :publish, action: 'list') ].flatten.include? name
Puppet_X::Aptly::Cli.execute(object: :publish, action: 'list').lines.map(&:chomp).flatten.include? name
end

end
46 changes: 46 additions & 0 deletions lib/puppet/provider/aptly_repo/cli.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
require 'puppet/provider'

module_lib = Pathname.new(__FILE__).parent.parent.parent.parent
require File.join module_lib, 'puppet_x/aptly/cli'

Puppet::Type.type(:aptly_repo).provide(:cli) do

mk_resource_methods

def create
Puppet.info("Creating Aptly Repository #{name}}")

Puppet_X::Aptly::Cli.execute(
object: :repo,
action: 'create',
arguments: [ name ],
flags: {
'component' => resource[:default_component],
'distribution' => resource[:default_distribution],
}
)
end

def destroy
Puppet.info("Destroying Aptly Repository #{name}")

Puppet_X::Aptly::Cli.execute(
object: :repo,
action: 'drop',
arguments: [ name ],
flags: { 'force' => resource[:force] ? 'true' : 'false' },
)
end

def exists?
Puppet.debug("Check if Repository #{name} exists")

Puppet_X::Aptly::Cli.execute(
object: :repo,
action: 'list',
flags: { 'raw' => 'true' },
exceptions: false,
).lines.map(&:chomp).include? name
end

end
38 changes: 38 additions & 0 deletions lib/puppet/type/aptly_repo.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
require 'puppet/parameter/boolean'

Puppet::Type.newtype(:aptly_repo) do
@doc = %q{Creates a new Aptly repo
}

ensurable

newparam(:name, :namevar => true) do
desc "The name of the Aptly repo. Example : frontend_apps"
end

newparam(:force, :boolean => true, :parent => Puppet::Parameter::Boolean) do
desc "Force to drop the Apt repository even if it used as source of some snapshot"
defaultto :true
end

newparam(:default_component) do
desc "Default component when publishing. Example : main"
validate do |value|
unless value.instance_of? String
raise ArgumentError , "%s is not a valid component (should be a string)" % value
end
end
defaultto 'main'
end

newparam(:default_distribution) do
desc "Default distribution when publishing"
validate do |value|
unless value.instance_of? String
raise ArgumentError , "%s is not a valid distribution (should be a string)" % value
end
end
defaultto ''
end

end
20 changes: 20 additions & 0 deletions manifests/repo.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# == Define aptly::repo
#
# Manages an apt repo.
#
define aptly::repo (
$ensure = 'present',
$default_distribution = $::lsbdistcodename,
$default_component = 'main',
) {
validate_string(
$default_distribution,
$default_component
)

aptly_repo { $name:
ensure => $ensure,
default_distribution => $default_distribution,
default_component => $default_component,
}
}
1 change: 1 addition & 0 deletions spec/classes/aptly_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
it { is_expected.to compile.with_all_deps }

it { is_expected.to create_class('aptly') }
it { is_expected.to contain_class('aptly::params') }
it { is_expected.to contain_class('aptly::install').that_comes_before('Class[aptly::config]') }
it { is_expected.to contain_class('aptly::config') }
it { is_expected.to contain_class('aptly::service').that_subscribes_to('Class[aptly::config]') }
Expand Down
18 changes: 18 additions & 0 deletions spec/defines/repo_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
require 'spec_helper'

describe 'aptly::repo' do
context 'basic repo' do
let(:title) { 'my_custom_repo' }
let(:params) {{
:default_component => 'stable',
:default_distribution => 'xenial',
}}

it 'should call the aptly_repo provider' do
is_expected.to contain_aptly_repo('my_custom_repo')\
.with_ensure('present')\
.with_default_component('stable')\
.with_default_distribution('xenial')
end
end
end
4 changes: 2 additions & 2 deletions spec/unit/puppet/provider/aptly_publish_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,14 @@
Puppet_X::Aptly::Cli.stubs(:execute).with(
object: :publish,
action: 'list',
).returns ['foo', 'test-snap', 'bar']
).returns "foo\ntest-snap\nbar"
expect(provider.exists?).to eq(true)
end
it 'should handle empty publications' do
Puppet_X::Aptly::Cli.stubs(:execute).with(
object: :publish,
action: 'list',
).returns nil
).returns ''
expect(provider.exists?).to eq(false)
end
end
Expand Down
70 changes: 70 additions & 0 deletions spec/unit/puppet/provider/aptly_repo_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
require 'spec_helper'
require 'puppet/type/aptly_repo'

describe Puppet::Type.type(:aptly_repo).provider(:cli) do
let(:resource) do
Puppet::Type.type(:aptly_repo).new(
:name => 'foo',
:ensure => 'present',
)
end

let(:provider) do
described_class.new(resource)
end

[:create, :destroy, :exists? ].each do |method|
it "should have a(n) #{method}" do
expect(provider).to respond_to(method)
end
end

describe '#create' do
it 'should create the repo' do
Puppet_X::Aptly::Cli.expects(:execute).with(
object: :repo,
action: 'create',
arguments: [ 'foo' ],
flags: {
'component' => 'main',
'distribution' => '',
}
)
provider.create
end
end

describe '#destroy' do
it 'should drop the repo' do
Puppet_X::Aptly::Cli.expects(:execute).with(
object: :repo,
action: 'drop',
arguments: ['foo'],
flags: { 'force' => 'true' },
)
provider.destroy
end
end

describe '#exists?' do
it 'should check the repo list' do
Puppet_X::Aptly::Cli.stubs(:execute).with(
object: :repo,
action: 'list',
flags: { 'raw' => 'true' },
exceptions: false,
).returns "foo\ntest-snap\nbar"
expect(provider.exists?).to eq(true)
end
it 'should handle without repo' do
Puppet_X::Aptly::Cli.stubs(:execute).with(
object: :repo,
action: 'list',
flags: { 'raw' => 'true' },
exceptions: false,
).returns ''
expect(provider.exists?).to eq(false)
end
end

end
Loading

0 comments on commit a0deaa2

Please sign in to comment.