lib/resources/apt.rb in inspec-2.1.81 vs lib/resources/apt.rb in inspec-2.1.83

- old
+ new

@@ -1,149 +1,149 @@ -# encoding: utf-8 - -# 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' - supports platform: 'unix' - 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 - # or : deb [trusted=yes] http://archive.ubuntu.com/ubuntu/ wily main restricted - parse_repo = /^\s*(\S+)\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 +# encoding: utf-8 + +# 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' + supports platform: 'unix' + 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 + # or : deb [trusted=yes] http://archive.ubuntu.com/ubuntu/ wily main restricted + parse_repo = /^\s*(\S+)\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