mirror of
https://github.com/inspec/inspec
synced 2024-11-27 15:10:44 +00:00
577688a3a0
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. :)
149 lines
4.1 KiB
Ruby
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
|