-
Notifications
You must be signed in to change notification settings - Fork 1
/
check_command_allowlist.rb
83 lines (71 loc) · 2.66 KB
/
check_command_allowlist.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# frozen_string_literal: true
###############################################################################
# The purpose of this script is to ensure that:
# 1) buildkite only clones from repositories coming from panoramaed org
# 2) buildkite can only run commands that have been allowlisted from within one
# of those repositories
###############################################################################
require "yaml"
KNOWN_REPOSITORY_PREFIXES = [
"[email protected]:panorama-ed/",
"https://github.com/panorama-ed/"
].freeze
# This command allows us to upload and process the pipeline file from our
# repositories
DEFAULT_ALLOWED_COMMANDS = [
"buildkite-agent pipeline upload ./buildkite/pipeline.yml"
].freeze
unless KNOWN_REPOSITORY_PREFIXES.any? do |prefix|
ENV["BUILDKITE_REPO"].start_with?(prefix)
end
puts "The requested repository (#{ENV.fetch('BUILDKITE_REPO',
nil)}) cannot be cloned "\
"to this buildkite instance. If you actually need to use this repo "\
"please modify the agent bootstrapping script to allow cloning it."
exit 4
end
# Search for pipeline files in root and subdirectories
pipeline_paths = [File.join(
ENV.fetch("BUILDKITE_BUILD_CHECKOUT_PATH", nil),
"buildkite",
"pipeline.yml"
)] + Dir.glob(File.join(
ENV.fetch("BUILDKITE_BUILD_CHECKOUT_PATH", nil),
"**",
"buildkite",
"pipeline.yml"
))
unless pipeline_paths.any? { |path| File.exist?(path) }
puts "All projects in the repository must have a 'buildkite/pipeline.yml' "\
"file that specifies the commands allowed to run on the buildkite "\
"server!"
exit 1
end
allowed_commands = DEFAULT_ALLOWED_COMMANDS
pipeline_paths.each do |path|
yaml_content = File.read(path)
begin
pipeline = YAML.safe_load(yaml_content, aliases: true)
allowed_commands += pipeline["steps"].
map { |step| step["command"] }.
flatten.
compact.
uniq
rescue Psych::SyntaxError => e
puts "Failed to parse #{path}"
puts "Error message: #{e.message}"
puts "You have an error on line #{e.line}, this is your file:"
yaml_content.split("\n").each_with_index do |line, line_number|
puts "#{line_number + 1}: #{line}"
end
exit 3
end
end
ENV["BUILDKITE_COMMAND"].split("\n").each do |command|
next if allowed_commands.include?(command)
puts "The given command is not in any of the 'buildkite/pipeline.yml' files "\
"and therefore will not be run. Please add it to the allowlist if it "\
"should be allowed."
exit 2
end
exit 0