inspec/lib/resources/apt.rb
Adam Leff 577688a3a0 Placing all resources in the Inspec::Resources namespace
Many of the resources are named as a top-level class with a fairly generic class name, such as "OS". This causes an issue specifically with kitchen-google which depends on a gem which depends on the "os" gem which itself defines an OS class with a different superclass. This prevents users from using TK, Google Compute, and Inspec without this fix.

Some mocked commands had their digest changed as well due to the new indentation, specifically in the User and RegistryKey classes.

I strongly recommend viewing this diff with `git diff --ignore-space-change`
to see the *real* changes. :)
2016-03-08 13:40:16 -05:00

149 lines
4.1 KiB
Ruby

# encoding: utf-8
# author: Christoph Hartmann
# author: Dominik Richter
# Verifies apt and ppa repositories
#
# Usage:
# describe apt('ubuntu-wine/ppa') do
# it { should exist }
# it { should be_enabled }
# end
#
# it also understands a ppa url
# describe apt('ppa:ubuntu-wine/ppa') do
# it { should exist }
# it { should be_enabled }
# end
#
# The following ppa formats are supported:
# - ubuntu-wine/ppa
# - ppa:ubuntu-wine/ppa
# - http://ppa.launchpad.net/juju/stable/ubuntu
#
# Install a ppa as following:
# apt-get install python-software-properties
# apt-get install software-properties-common
# add-apt-repository ppa:ubuntu-wine/ppa
require 'uri'
module Inspec::Resources
class AptRepository < Inspec.resource(1)
name 'apt'
desc 'Use the apt InSpec audit resource to verify Apt repositories on the Debian and Ubuntu platforms, and also PPA repositories on the Ubuntu platform.'
example "
describe apt('nginx/stable') do
it { should exist }
it { should be_enabled }
end
"
def initialize(ppa_name)
@deb_url = nil
# check if the os is ubuntu or debian
if inspec.os.debian?
@deb_url = determine_ppa_url(ppa_name)
else
# this resource is only supported on ubuntu and debian
skip_resource 'The `apt` resource is not supported on your OS yet.'
end
end
def exists?
find_repo.count > 0
end
def enabled?
return false if find_repo.count == 0
actives = find_repo.map { |repo| repo[:active] }
actives = actives.uniq
actives.size == 1 && actives[0] = true
end
def to_s
"Apt Repository #{@deb_url}"
end
private
def find_repo
read_debs.select { |repo| repo[:url] == @deb_url && repo[:type] == 'deb' }
end
HTTP_URL_RE = /\A#{URI::DEFAULT_PARSER.make_regexp(%w{http https})}\z/
# read
def read_debs
return @repo_cache if defined?(@repo_cache)
# load all lists
cmd = inspec.command("find /etc/apt/ -name \*.list -exec sh -c 'cat {} || echo -n' \\;")
# @see https://help.ubuntu.com/community/Repositories/CommandLine#Explanation_of_the_Repository_Format
@repo_cache = cmd.stdout.chomp.split("\n").each_with_object([]) do |raw_line, lines|
active = true
# detect if the repo is commented out
line = raw_line.gsub(/^(#\s*)*/, '')
active = false if raw_line != line
# eg.: deb http://archive.ubuntu.com/ubuntu/ wily main restricted
parse_repo = /^\s*(\S+)\s+"?([^ "\t\r\n\f]+)"?\s+(\S+)\s+(.*)$/.match(line)
# check if we got any result and the second param is an url
next if parse_repo.nil? || !parse_repo[2] =~ HTTP_URL_RE
# map data
repo = {
type: parse_repo[1],
url: parse_repo[2],
distro: parse_repo[3],
components: parse_repo[4].chomp.split(' '),
active: active,
}
next unless ['deb', 'deb-src'].include? repo[:type]
lines.push(repo)
end
end
# resolves ppa urls
# @see http://bazaar.launchpad.net/~ubuntu-core-dev/software-properties/main/view/head:/softwareproperties/ppa.py
def determine_ppa_url(ppa_url)
# verify if we have the url already, then just return
return ppa_url if ppa_url =~ HTTP_URL_RE
# otherwise start generating the ppa url
# special care if the name stats with :
ppa_url = ppa_url.split(':')[1] if ppa_url.start_with?('ppa:')
# parse ppa owner and repo
ppa_owner, ppa_repo = ppa_url.split('/')
ppa_repo = 'ppa' if ppa_repo.nil?
# construct new ppa url and return it
format('http://ppa.launchpad.net/%s/%s/ubuntu', ppa_owner, ppa_repo)
end
end
# for compatability with serverspec
# this is deprecated syntax and will be removed in future versions
class PpaRepository < AptRepository
name 'ppa'
def exists?
deprecated
super()
end
def enabled?
deprecated
super()
end
def deprecated
warn '[DEPRECATION] `ppa(reponame)` is deprecated. Please use `apt(reponame)` instead.'
end
end
end