Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RESOURCE-547 Switch inspec-azure to chefstyle #705

Merged
merged 7 commits into from
Dec 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
23 changes: 12 additions & 11 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
source 'https://rubygems.org'
source "https://rubygems.org"

gem 'faraday'
gem 'faraday_middleware'
gem 'inspec-bin'
gem 'rake'
gem "faraday"
gem "faraday_middleware"
gem "inspec-bin"
gem "rake"

group :development do
gem 'pry'
gem 'pry-byebug'
gem "pry"
gem "pry-byebug"
end

group :development, :test do
gem 'minitest'
gem 'rubocop', '~> 1.39.0'
gem 'simplecov', '~> 0.21'
gem 'simplecov_json_formatter'
gem "chefstyle", "~> 2.2.2"
gem "minitest"
gem "rubocop", "~> 1.25.1", require: false
gem "simplecov", "~> 0.21"
gem "simplecov_json_formatter"
end
168 changes: 91 additions & 77 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -1,43 +1,57 @@
require 'bundler'
require 'bundler/gem_helper'
require 'rake/testtask'
require 'rubocop/rake_task'
require 'fileutils'
require 'open3'
require "bundler"
require "bundler/gem_helper"
require "rake/testtask"
require "rubocop/rake_task"
require "fileutils"
require "open3"
require "chefstyle"

require_relative 'lib/attribute_file_writer'
require_relative 'lib/environment_file'
require_relative "lib/attribute_file_writer"
require_relative "lib/environment_file"

RuboCop::RakeTask.new

FIXTURE_DIR = "#{Dir.pwd}/test/fixtures".freeze
TERRAFORM_DIR = 'terraform'.freeze
TERRAFORM_DIR = "terraform".freeze
REQUIRED_ENVS = %w{AZURE_CLIENT_ID AZURE_CLIENT_SECRET AZURE_TENANT_ID AZURE_SUBSCRIPTION_ID}.freeze
INTEGRATION_DIR = 'test/integration/verify'.freeze
TF_PLAN_FILE_NAME = 'inspec-azure.plan'.freeze
INTEGRATION_DIR = "test/integration/verify".freeze
TF_PLAN_FILE_NAME = "inspec-azure.plan".freeze
TF_PLAN_FILE = File.join(TERRAFORM_DIR, TF_PLAN_FILE_NAME)
ATTRIBUTES_FILE_NAME = ''.freeze
ATTRIBUTES_FILE_NAME = "".freeze

task default: :test
desc 'Testing tasks'
desc "Testing tasks"
task test: %w{lint test:unit}

desc 'Linting tasks'
task lint: [:rubocop, :'syntax:ruby', :'syntax:inspec']
desc "Linting tasks"
# task lint: [:rubocop, :'syntax:ruby', :'syntax:inspec']

desc "Run rubocop chefstyle linter + unit tests"
task default: [:lint, :test]

# lint the project
# chefstyle
begin
RuboCop::RakeTask.new(:lint) do |task|
task.options += ["--display-cop-names", "--no-color", "--parallel"]
end
rescue LoadError
puts "rubocop is not available. Install the rubocop gem to run the lint tests."
end

task :setup_env do
puts '-> Loading Environment Variables'
ENV['TF_VAR_subscription_id'] = ENV['AZURE_SUBSCRIPTION_ID']
ENV['TF_VAR_tenant_id'] = ENV['AZURE_TENANT_ID']
ENV['TF_VAR_client_id'] = ENV['AZURE_CLIENT_ID']
ENV['TF_VAR_client_secret'] = ENV['AZURE_CLIENT_SECRET']
puts "-> Loading Environment Variables"
ENV["TF_VAR_subscription_id"] = ENV["AZURE_SUBSCRIPTION_ID"]
ENV["TF_VAR_tenant_id"] = ENV["AZURE_TENANT_ID"]
ENV["TF_VAR_client_id"] = ENV["AZURE_CLIENT_ID"]
ENV["TF_VAR_client_secret"] = ENV["AZURE_CLIENT_SECRET"]

puts '-> Ensuring required Environment Variables are set'
puts "-> Ensuring required Environment Variables are set"
missing = REQUIRED_ENVS.reject { |var| ENV.key?(var) }
abort("ENV missing: #{missing.join(', ')}") if missing.any?
abort("ENV missing: #{missing.join(", ")}") if missing.any?

# Notify user which optional components they are using
options = EnvironmentFile.options('.envrc')
options = EnvironmentFile.options(".envrc")
if options.empty?
puts "-> You are not using any optional components. See the README for more information.\n\n"
else
Expand All @@ -50,9 +64,9 @@ task :setup_env do
end

namespace :syntax do
desc 'InSpec syntax check'
desc "InSpec syntax check"
task :inspec do
puts '-> Checking InSpec Control Syntax'
puts "-> Checking InSpec Control Syntax"
stdout, status = Open3.capture2("bundle exec inspec vendor #{INTEGRATION_DIR} --overwrite --chef-license accept-silent &&
bundle exec inspec check #{INTEGRATION_DIR}")
puts stdout
Expand All @@ -64,156 +78,156 @@ namespace :syntax do
status.exitstatus
end

desc 'Ruby syntax check'
desc "Ruby syntax check"
task :ruby do
puts '-> Checking Ruby Syntax'
files = %w{Gemfile Rakefile} + Dir['./lib*/**/*.rb'] + Dir['./test/**/*.rb']
puts "-> Checking Ruby Syntax"
files = %w{Gemfile Rakefile} + Dir["./lib*/**/*.rb"] + Dir["./test/**/*.rb"]

files.each do |file|
sh('ruby', '-c', file) do |ok, res|
sh("ruby", "-c", file) do |ok, res|
next if ok
puts 'Syntax check FAILED'
puts "Syntax check FAILED"
exit res.exitstatus
end
end
end
end

namespace :azure do
desc 'Authenticate with the Azure CLI'
desc "Authenticate with the Azure CLI"
task login: [:setup_env] do
puts '-> Logging into Azure'
puts "-> Logging into Azure"
sh(
'az', 'login',
'--service-principal',
'-u', ENV['AZURE_CLIENT_ID'],
'-p', ENV['AZURE_CLIENT_SECRET'],
'--tenant', ENV['AZURE_TENANT_ID']
"az", "login",
"--service-principal",
"-u", ENV["AZURE_CLIENT_ID"],
"-p", ENV["AZURE_CLIENT_SECRET"],
"--tenant", ENV["AZURE_TENANT_ID"]
)
puts '-> Setting Subscription'
puts "-> Setting Subscription"
sh(
'az', 'account', 'set',
'-s', ENV['AZURE_SUBSCRIPTION_ID']
"az", "account", "set",
"-s", ENV["AZURE_SUBSCRIPTION_ID"]
)
end
end

namespace :test do
# set env
ENV['RAKE_ENV'] = 'test'
ENV["RAKE_ENV"] = "test"
# Minitest
Rake::TestTask.new(:unit) do |t|
t.libs << 'test/unit'
t.libs << 'libraries'
t.libs << "test/unit"
t.libs << "libraries"
t.verbose = true
t.warning = false
t.test_files = FileList['test/unit/**/*_test.rb']
t.test_files = FileList["test/unit/**/*_test.rb"]
end

task :integration, [:controls] => ['tf:write_tf_output_to_file', :setup_env] do |_t, args|
task :integration, [:controls] => ["tf:write_tf_output_to_file", :setup_env] do |_t, args|
cmd = %W( bundle exec inspec exec #{INTEGRATION_DIR}
--input-file terraform/#{ENV['ATTRIBUTES_FILE']}
--input-file terraform/#{ENV["ATTRIBUTES_FILE"]}
--reporter cli
--no-distinct-exit
-t azure://#{ENV['AZURE_SUBSCRIPTION_ID']}
-t azure://#{ENV["AZURE_SUBSCRIPTION_ID"]}
--chef-license accept-silent )

if args[:controls]
sh(*cmd, '--controls', args[:controls], *args.extras)
sh(*cmd, "--controls", args[:controls], *args.extras)
else
sh(*cmd)
end
end
end

namespace :tf do # rubocop:disable Metrics/BlockLength
workspace = ENV['WORKSPACE']
workspace = ENV["WORKSPACE"]

task init: [:'azure:login'] do
abort('$WORKSPACE not set. Please source .envrc.') if workspace.nil?
abort('$WORKSPACE has no content. Check .envrc.') if workspace.empty?
abort("$WORKSPACE not set. Please source .envrc.") if workspace.nil?
abort("$WORKSPACE has no content. Check .envrc.") if workspace.empty?
Dir.chdir(TERRAFORM_DIR) do
sh('terraform', 'init')
sh("terraform", "init")
end
end

task workspace: [:init] do
Dir.chdir(TERRAFORM_DIR) do
sh('terraform', 'workspace', 'select', workspace) do |ok, _|
sh("terraform", "workspace", "select", workspace) do |ok, _|
next if ok
sh('terraform', 'workspace', 'new', workspace)
sh("terraform", "workspace", "new", workspace)
end
end
end

desc 'Creates a Terraform execution plan from the plan file'
desc "Creates a Terraform execution plan from the plan file"
task :plan, [:optionals] => [:workspace] do |_t, args|
if args[:optionals]
ignore_list = Array(args[:optionals]) + args.extras
ignore_list.each do |component|
ENV["TF_VAR_#{component}_count"] = '0'
ENV["TF_VAR_#{component}_count"] = "0"
end
end
Dir.chdir(TERRAFORM_DIR) do
sh('terraform', 'get')
sh('terraform', 'plan', '-out', 'inspec-azure.plan')
sh("terraform", "get")
sh("terraform", "plan", "-out", "inspec-azure.plan")
end

Rake::Task['tf:write_tf_output_to_file'].invoke
Rake::Task["tf:write_tf_output_to_file"].invoke
end

desc 'Executes the Terraform plan'
desc "Executes the Terraform plan"
task :apply, [:optionals] do |_t, args|
if File.exist?(TF_PLAN_FILE)
puts "-> Applying an existing terraform plan: #{TF_PLAN_FILE}"
unless args[:optionals].nil?
puts "These arguments are ignored: #{Array(args[:optionals]) + args.extras}."
end
else
Rake::Task['tf:plan'].invoke(args[:optionals])
Rake::Task["tf:plan"].invoke(args[:optionals])
end
Dir.chdir(TERRAFORM_DIR) do
sh('terraform', 'apply', 'inspec-azure.plan')
sh("terraform", "apply", "inspec-azure.plan")
end
end

desc 'Destroys the Terraform environment'
desc "Destroys the Terraform environment"
task destroy: [:workspace] do
Dir.chdir(TERRAFORM_DIR) do
sh('terraform', 'destroy', '-force')
sh("terraform", "destroy", "-force")
end
end

task write_tf_output_to_file: [:workspace] do
Dir.chdir(TERRAFORM_DIR) do
stdout, stderr, status = Open3.capture3('terraform output -json')
stdout, stderr, status = Open3.capture3("terraform output -json")

abort(stderr) unless status.success?
abort('$ATTRIBUTES_FILE not set. Please source .envrc.') if ENV['ATTRIBUTES_FILE'].nil?
abort('$ATTRIBUTES_FILE has no content. Check .envrc.') if ENV['ATTRIBUTES_FILE'].empty?
abort("$ATTRIBUTES_FILE not set. Please source .envrc.") if ENV["ATTRIBUTES_FILE"].nil?
abort("$ATTRIBUTES_FILE has no content. Check .envrc.") if ENV["ATTRIBUTES_FILE"].empty?

AttributeFileWriter.write_yaml(ENV['ATTRIBUTES_FILE'], stdout)
AttributeFileWriter.write_yaml(ENV["ATTRIBUTES_FILE"], stdout)
end
end
end

namespace :docs do
desc 'Prints markdown links for resource doc files to update the README'
desc "Prints markdown links for resource doc files to update the README"
task :resource_links do
puts "\n"
Dir.entries('docs/resources').sort
.reject { |file| File.directory?(file) }
.collect { |file| "- [#{file.split('.')[0]}](docs/resources/#{file})" }
.map { |link| puts link }
Dir.entries("docs/resources").sort
.reject { |file| File.directory?(file) }
.collect { |file| "- [#{file.split(".")[0]}](docs/resources/#{file})" }
.map { |link| puts link }
puts "\n"
end
end

namespace :attributes do
desc 'Create attributes used for integration testing'
desc "Create attributes used for integration testing"
task :write do
abort('$ATTRIBUTES_FILE not set. Please source .envrc.') if ENV['ATTRIBUTES_FILE'].nil?
abort('$ATTRIBUTES_FILE has no content. Check .envrc.') if ENV['ATTRIBUTES_FILE'].empty?
Rake::Task['tf:write_tf_output_to_file'].invoke
abort("$ATTRIBUTES_FILE not set. Please source .envrc.") if ENV["ATTRIBUTES_FILE"].nil?
abort("$ATTRIBUTES_FILE has no content. Check .envrc.") if ENV["ATTRIBUTES_FILE"].empty?
Rake::Task["tf:write_tf_output_to_file"].invoke
end
end
10 changes: 5 additions & 5 deletions lib/attribute_file_writer.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
require 'yaml'
require 'json'
require "yaml"
require "json" unless defined?(JSON)

class AttributeFileWriter
def self.write_yaml(file, content)
Expand All @@ -20,12 +20,12 @@ def convert_to_yaml(content)
json = JSON.parse(content)
yaml = {}
json.each_key do |key|
yaml[key] = json[key]['value']
yaml[key] = json[key]["value"]
end
File.open(@file, 'w') { |file| file.puts(yaml.to_yaml) }
File.open(@file, "w") { |file| file.puts(yaml.to_yaml) }
end

def append(content)
File.open(@file, 'a') { |file| file.puts(content) }
File.open(@file, "a") { |file| file.puts(content) }
end
end
Loading