1
+ #!/usr/bin/env ruby
2
+ # TODO: Include parser Directive options (e.g. changing comment characters) https://docs.docker.com/engine/reference/builder/#parser-directives
3
+
4
+
5
+
6
+ class DockerfileAnalyzer
7
+ VERSION = '0.0.1'
8
+
9
+ def initialize ( commandlineopts )
10
+ require 'logger'
11
+
12
+ @options = commandlineopts
13
+ @base_dir = @options . report_directory
14
+ @scan_dir = @options . scan_directory
15
+ if !File . exists? ( @base_dir )
16
+ Dir . mkdir ( @base_dir )
17
+ end
18
+
19
+ if @options . logger
20
+ @log = Logger . new ( @base_dir + '/' + @options . logger )
21
+ else
22
+ @log = Logger . new ( STDOUT )
23
+ end
24
+ #Change before release
25
+ @log . level = Logger . DEBUG
26
+
27
+ @log . debug ( "Log created at " + Time . now . to_s )
28
+ @log . debug ( "Scan type is : " + @options . scan_type )
29
+ @log . debug ( "Directory being scanned is : " + @options . scan_directory ) if @options . scan_type == :directory
30
+ @log . debug ( "File being scanned is : " + @options . scan_file ) if @options . scan_type == :file
31
+ end
32
+
33
+ def run
34
+ case @options . scan_type
35
+ when :directory
36
+ scan_dirs
37
+ parse_files
38
+ analyze_files
39
+ report
40
+ when :file
41
+ @scan_files = Array . new
42
+ @scan_files << @options . scan_file
43
+ parse_files
44
+ analyze_files
45
+ report
46
+ end
47
+
48
+ def scan_dirs
49
+ end
50
+
51
+ def parse_files
52
+ @parsed_dockerfiles = Array . new
53
+ @log . debug ( "Files to be looked at : " + @scan_files . join ( ', ' ) )
54
+ @scan_files . each do |file |
55
+ results = Hash . new
56
+ file_contents = File . open ( file , 'r' ) . readlines
57
+ #Get rid of the line endings
58
+ file_contents . each { |line | line . chomp! }
59
+ #Remove Blank Lines
60
+ file_contents . delete_if { |line | line . length ==0 }
61
+ #Get all the continued lines onto a single line
62
+ file_contents . each_index do |i |
63
+ while file_contents [ i ] =~ /\\ $/
64
+ file_contents [ i ] . sub! ( /\\ $/ , '' )
65
+ file_contents [ i ] = file_contents [ i ] + file_contents [ i +1 ] . lstrip
66
+ file_contents . delete_at ( i +1 )
67
+ end
68
+ end
69
+
70
+ #To Store CMD and Entrypoints
71
+ results [ :command ] = Array . new
72
+ #To Store FROMs
73
+ results [ :from ] = Array . new
74
+ #To Store comments
75
+ results [ :comments ] = Array . new
76
+ #To Store Labels
77
+ results [ :labels ] = Array . new
78
+ #To Store Runs
79
+ results [ :runs ] = Array . new
80
+ #To Store Workdirs
81
+ results [ :workdirs ] = Array . new
82
+
83
+
84
+ #Populate the Results Hash
85
+ file_contents . each do |line |
86
+
87
+ end
88
+
89
+
90
+ end
91
+ end
92
+
93
+ def analyze_files
94
+ end
95
+
96
+ def report
97
+ end
98
+ end
99
+
100
+ if __FILE__ == $0
101
+ require 'ostruct'
102
+ require 'optparse'
103
+ options = OpenStruct . new
104
+
105
+ options . report_directory = Dir . pwd
106
+ options . report_file = "docker-analysis-report"
107
+ options . scan_directory = Dir . pwd
108
+ options . scan_file = ''
109
+ options . scan_type = :notset
110
+ options . recursive = false
111
+
112
+ opts = OptionParser . new do |opts |
113
+ opts . banner = "Dockerfile Analyzer #{ DockerfileAnalyzer ::VERSION } "
114
+ opts . on ( "-d" , "--directory [DIRECTORY]" , "Directory to scan for Dockerfiles" ) do |dir |
115
+ options . scan_directory = dir
116
+ options . scan_type = :directory
117
+ end
118
+
119
+ opts . on ( "--recursive" , "scan for Dockerfiles recursively" ) do |recurse |
120
+ options . recursive = true
121
+ end
122
+
123
+ opts . on ( "-f" , "--file" , "File to scan for issues" ) do |file |
124
+ options . scan_file = file
125
+ options . scan_type = :file
126
+ end
127
+
128
+ opts . on ( "--reportDirectory [REPORTDIRECTORY" , "Directory for the report" ) do |repdir |
129
+ options . report_directory = repdir
130
+ end
131
+
132
+ opts . on ( "-l" , "--logger [LOGGER]" , "Log debugging messages to a file" ) do |logger |
133
+ options . logger = logger
134
+ end
135
+
136
+ opts . on ( "-h" , "--help" , "-?" , "--?" , "Get Help" ) do |help |
137
+ puts opts
138
+ exit
139
+ end
140
+
141
+ opts . on ( "-v" , "--version" , "Get Version" ) do |ver |
142
+ puts "Dockerfile Analyzer Version #{ DockerfileAnalyzer ::VERSION } "
143
+ end
144
+ end
145
+
146
+ opts . parse! ( ARGV )
147
+
148
+ unless ( options . scan_type == :file || options . scan_type == :directory )
149
+ puts "Didn't get any arguments or missing scan type"
150
+ puts opts
151
+ exit
152
+ end
153
+
154
+ analysis = DockerfileAnalyzer . new ( options )
155
+ analysis . run
156
+
157
+ end
0 commit comments