├── .gitattributes ├── .gitignore ├── Gemfile ├── README.md ├── Rakefile ├── files └── download-artifact-from-nexus.sh ├── manifests ├── artifact.pp └── init.pp ├── metadata.json ├── spec ├── spec.opts └── spec_helper.rb └── tests └── init.pp /.gitattributes: -------------------------------------------------------------------------------- 1 | *.sh eol=lf 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .project 2 | .bundle/ 3 | vendor/ 4 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem "rake" 4 | gem "puppet", ENV['PUPPET_VERSION'] || '~> 3.7.0' 5 | gem "rspec-puppet" 6 | gem "metadata-json-lint" 7 | gem "puppet-lint" 8 | gem "puppetlabs_spec_helper" 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Puppet Module for Nexus 2 | ======================= 3 | 4 | This Puppet Module downloads Maven artifacts from a Nexus server. It supports: 5 | 6 | * artifact identification using GAV classifier and packaging 7 | * repository selection 8 | * authentication 9 | 10 | It relies on the Nexus REST service and on curl. 11 | 12 | Getting the module 13 | ------------------ 14 | 15 | * Clone this repository and add it to your _modulepath_ 16 | 17 | 18 | Usage 19 | ----- 20 | 21 | # Initialize Nexus 22 | class {'nexus': 23 | url => "http://edge.spree.de/nexus", 24 | username => "nexus", 25 | password => "********" 26 | } 27 | 28 | nexus::artifact {'commons-io': 29 | gav => "commons-io:commons-io:2.1", 30 | repository => "public", 31 | output => "/tmp/commons-io-2.1.jar" 32 | } 33 | 34 | nexus::artifact {'ipojo': 35 | gav => "org.apache.felix:org.apache.felix.ipojo:1.8.0", 36 | repository => "public", 37 | output => "/tmp/ipojo-1.8.jar" 38 | } 39 | 40 | nexus::artifact {'chameleon web distribution': 41 | gav => "org.ow2.chameleon:distribution-web:0.3.0-SNAPSHOT", 42 | classifier => 'distribution', 43 | packaging => 'zip', 44 | repository => "public-snapshots", 45 | output => "/tmp/distribution-web-0.3.0-SNAPSHOT.zip", 46 | timeout => 600, 47 | owner => 'myuser', 48 | group => 'mygroup', 49 | mode => 0755 50 | } 51 | 52 | License 53 | ------- 54 | 55 | This project is licensed under the Apache Software License 2.0. 56 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'puppet-lint/tasks/puppet-lint' 2 | require 'puppet-syntax/tasks/puppet-syntax' 3 | 4 | exclude_paths = [ 5 | "pkg/**/*", 6 | "vendor/**/*", 7 | "spec/**/*", 8 | ] 9 | 10 | PuppetSyntax.exclude_paths = exclude_paths 11 | 12 | # Puppet-Lint 1.1.0 13 | Rake::Task[:lint].clear 14 | PuppetLint::RakeTask.new :lint do |config| 15 | 16 | # Pattern of files to ignore 17 | config.ignore_paths = exclude_paths 18 | 19 | # List of checks to disable 20 | config.disable_checks = ['documentation', '80chars', 'autoloader_layout'] 21 | 22 | # Should puppet-lint prefix it's output with the file being checked, 23 | # defaults to true 24 | config.with_filename = false 25 | 26 | # Should the task fail if there were any warnings, defaults to false 27 | config.fail_on_warnings = true 28 | 29 | # Format string for puppet-lint's output (see the puppet-lint help output 30 | # for details 31 | config.log_format = '%{path}:%{linenumber}:%{check}:%{KIND}:%{message}' 32 | 33 | # Print out the context for the problem, defaults to false 34 | config.with_context = true 35 | 36 | # Enable automatic fixing of problems, defaults to false 37 | config.fix = true 38 | 39 | # Show ignored problems in the output, defaults to false 40 | config.show_ignored = true 41 | end 42 | 43 | task :metadata do 44 | sh "metadata-json-lint metadata.json" 45 | end 46 | 47 | task :default => [:syntax, :lint, :metadata] 48 | -------------------------------------------------------------------------------- /files/download-artifact-from-nexus.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Define Nexus Configuration 4 | NEXUS_BASE= 5 | REST_PATH=/service/local 6 | ART_REDIR=/artifact/maven/redirect 7 | 8 | usage() 9 | { 10 | cat <&2 94 | usage 95 | exit 96 | ;; 97 | esac 98 | done 99 | 100 | if [[ -z $GROUP_ID ]] || [[ -z $ARTIFACT_ID ]] || [[ -z $VERSION ]] 101 | then 102 | echo "BAD ARGUMENTS: Either groupId, artifactId, or version was not supplied" >&2 103 | usage 104 | exit 1 105 | fi 106 | 107 | # Define default values for optional components 108 | 109 | # If we don't have set a repository and the version requested is a SNAPSHOT use snapshots, otherwise use releases 110 | if [[ "$REPOSITORY" == "" ]] 111 | then 112 | if [[ "$VERSION" == *SNAPSHOT ]] 113 | then 114 | if [[ $VERSION == "LATEST-SNAPSHOT" ]] 115 | then 116 | VERSION=LATEST 117 | fi 118 | : ${REPO:="snapshots"} 119 | else 120 | : ${REPO:="releases"} 121 | fi 122 | fi 123 | # Construct the base URL 124 | REDIRECT_URL=${NEXUS_BASE}${REST_PATH}${ART_REDIR} 125 | 126 | # Generate the list of parameters 127 | PARAM_KEYS=( g a v r p c ) 128 | PARAM_VALUES=( $GROUP_ID $ARTIFACT_ID $VERSION $REPO $PACKAGING $CLASSIFIER ) 129 | PARAMS="" 130 | for index in ${!PARAM_KEYS[*]} 131 | do 132 | if [[ ${PARAM_VALUES[$index]} != "" ]] 133 | then 134 | PARAMS="${PARAMS}${PARAM_KEYS[$index]}=${PARAM_VALUES[$index]}&" 135 | fi 136 | done 137 | 138 | REDIRECT_URL="${REDIRECT_URL}?${PARAMS}" 139 | 140 | # Authentication 141 | AUTHENTICATION= 142 | if [[ "$USERNAME" != "" ]] && [[ "$PASSWORD" != "" ]] 143 | then 144 | AUTHENTICATION="-u $USERNAME:$PASSWORD" 145 | fi 146 | 147 | if [[ "$NETRC" == "1" ]] 148 | then 149 | AUTHENTICATION="-n" 150 | fi 151 | 152 | if [[ "$SNAPSHOT_CHECK" != "" ]] 153 | then 154 | # remove $OUTPUT if nexus has newer version 155 | if [[ -f $OUTPUT ]] && [[ "$(curl -s ${REDIRECT_URL} ${AUTHENTICATION} -I --location-trusted -z $OUTPUT -o /dev/null -w '%{http_code}' )" == "200" ]] 156 | then 157 | echo "Nexus has newer version of $GROUP_ID:$ARTIFACT_ID:$VERSION" 158 | rm $OUTPUT 159 | fi 160 | exit 0 161 | fi 162 | 163 | # Output 164 | OUT= 165 | if [[ "$OUTPUT" != "" ]] 166 | then 167 | OUT="-o $OUTPUT" 168 | fi 169 | 170 | echo "Fetching Artifact from $REDIRECT_URL..." >&2 171 | curl -sS ${REDIRECT_URL} ${OUT} ${AUTHENTICATION} -v -R --location-trusted --fail 172 | -------------------------------------------------------------------------------- /manifests/artifact.pp: -------------------------------------------------------------------------------- 1 | # Resource: nexus::artifact 2 | # 3 | # This resource downloads Maven Artifacts from Nexus 4 | # 5 | # Parameters: 6 | # [*gav*] : The artifact groupid:artifactid:version (mandatory) 7 | # [*packaging*] : The packaging type (jar by default) 8 | # [*classifier*] : The classifier (no classifier by default) 9 | # [*repository*] : The repository such as 'public', 'central'...(mandatory) 10 | # [*output*] : The output file (mandatory) 11 | # [*ensure*] : If 'present' checks the existence of the output file (and downloads it if needed), if 'absent' deletes the output 12 | # file, if not set redownload the artifact 13 | # [*timeout*] : Optional timeout for download exec. 0 disables - see exec for default. 14 | # [*owner*] : Optional user to own the file 15 | # [*group*] : Optional group to own the file 16 | # [*mode*] : Optional mode for file 17 | # 18 | # Actions: 19 | # If ensure is set to 'present' the resource checks the existence of the file and download the artifact if needed. 20 | # If ensure is set to 'absent' the resource deleted the output file. 21 | # If ensure is not set or set to 'update', the artifact is re-downloaded. 22 | # 23 | # Sample Usage: 24 | # class nexus:artifact { 25 | #} 26 | # 27 | define nexus::artifact ( 28 | $gav, 29 | $repository, 30 | $output, 31 | $packaging = 'jar', 32 | $classifier = undef, 33 | $ensure = update, 34 | $timeout = undef, 35 | $owner = undef, 36 | $group = undef, 37 | $mode = undef 38 | ) { 39 | 40 | include nexus 41 | 42 | if($nexus::username and $nexus::password) { 43 | $args = "-u ${nexus::username} -p '${nexus::password}'" 44 | } elsif ($nexus::netrc) { 45 | $args = '-m' 46 | } 47 | 48 | if ($classifier!=undef) { 49 | $includeClass = "-c ${classifier}" 50 | } 51 | 52 | $cmd = "/opt/nexus-script/download-artifact-from-nexus.sh -a ${gav} -e ${packaging} ${$includeClass} -n ${nexus::url} -r ${repository} -o ${output} ${args} -v" 53 | 54 | if (($ensure != absent) and ($gav =~ /-SNAPSHOT/)) { 55 | exec { "Checking ${gav}-${classifier}": 56 | command => "${cmd} -z", 57 | timeout => $timeout, 58 | before => Exec["Download ${name}"], 59 | } 60 | } 61 | 62 | if $ensure == present { 63 | exec { "Download ${name}": 64 | command => $cmd, 65 | creates => $output, 66 | timeout => $timeout, 67 | } 68 | } elsif $ensure == absent { 69 | file { "Remove ${name}": 70 | ensure => absent, 71 | path => $output, 72 | } 73 | } else { 74 | exec { "Download ${name}": 75 | command => $cmd, 76 | timeout => $timeout, 77 | } 78 | } 79 | 80 | if $ensure != absent { 81 | file { $output: 82 | ensure => file, 83 | require => Exec["Download ${name}"], 84 | owner => $owner, 85 | group => $group, 86 | mode => $mode, 87 | } 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /manifests/init.pp: -------------------------------------------------------------------------------- 1 | # Class: nexus 2 | # 3 | # This module downloads Maven Artifacts from Nexus 4 | # 5 | # Parameters: 6 | # [*url*] : The Nexus base url (mandatory) 7 | # [*username*] : The username used to connect to nexus 8 | # [*password*] : The password used to connect to nexus 9 | # [*netrc*] : Use .netrc to connect to nexus 10 | # 11 | # Actions: 12 | # Checks and intialized the Nexus support. 13 | # 14 | # Sample Usage: 15 | # class nexus { 16 | # url => http://edge.spree.de/nexus, 17 | # username => user, 18 | # password => password 19 | #} 20 | # 21 | class nexus ( 22 | $url, 23 | $username = undef, 24 | $password = undef, 25 | $netrc = undef, 26 | ) { 27 | 28 | # Check arguments 29 | $nexus_url = $url 30 | 31 | if((!$username and $password) or ($username and !$password)) { 32 | fail('Cannot initialize the Nexus class - both username and password must be set') 33 | } 34 | 35 | # Install script 36 | file { '/opt/nexus-script/download-artifact-from-nexus.sh': 37 | ensure => file, 38 | owner => 'root', 39 | group => 'root', 40 | mode => '0755', 41 | source => 'puppet:///modules/nexus/download-artifact-from-nexus.sh', 42 | require => File['/opt/nexus-script'] 43 | } 44 | 45 | file { '/opt/nexus-script': ensure => directory } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": "Clement Escoffier, akquinet tech@spree gmbh", 3 | "license": "Apache Software License 2.0", 4 | "name": "cescoffier-nexus", 5 | "summary": "Download Maven Artifacts from Nexus", 6 | "version": "0.0.1", 7 | "project_page": "https://github.com/cescoffier/puppet-nexus", 8 | "source": "https://github.com/cescoffier/puppet-nexus.git", 9 | "tags": ["nexus", "gav", "artifact"], 10 | "operatingsystem_support": [], 11 | "requirements": [], 12 | "dependencies": [] 13 | } 14 | -------------------------------------------------------------------------------- /spec/spec.opts: -------------------------------------------------------------------------------- 1 | --format 2 | s 3 | --colour 4 | --loadby 5 | mtime 6 | --backtrace 7 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | require 'pathname' 2 | dir = Pathname.new(__FILE__).parent 3 | $LOAD_PATH.unshift(dir, dir + 'lib', dir + '../lib') 4 | 5 | require 'mocha' 6 | require 'puppet' 7 | gem 'rspec', '=1.2.9' 8 | require 'spec/autorun' 9 | 10 | Spec::Runner.configure do |config| 11 | config.mock_with :mocha 12 | end 13 | 14 | # We need this because the RAL uses 'should' as a method. This 15 | # allows us the same behaviour but with a different method name. 16 | class Object 17 | alias :must :should 18 | end 19 | -------------------------------------------------------------------------------- /tests/init.pp: -------------------------------------------------------------------------------- 1 | include nexus 2 | --------------------------------------------------------------------------------