Skip to content
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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ jobs:

./scripts/create-extractor-pack.sh

gh codeql resolve languages --format=json --search-path ./extractor-pack

- name: "Run Tests"
if: steps.changes.outputs.src == 'true'
run: |
Expand Down
60 changes: 26 additions & 34 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 10 additions & 6 deletions codeql-extractor.yml
Original file line number Diff line number Diff line change
@@ -1,29 +1,33 @@
name: "iac"
display_name: "IAC"
version: 0.0.3
version: 0.0.4
column_kind: "utf8"
legacy_qltest_extraction: true
github_api_languages:
- HCL
- Docker
- Bicep
scc_languages:
- HCL
- Docker
- Bicep

# File types
file_types:
- name: hcl
display_name: HCL
extensions:
- .tf
- .ftvars
- .tfvars
- .hcl
- name: json
display_name: JSON
extensions:
- .json

- name: dockerfile
display_name: Dockerfile
extensions:
- .Dockerfile
- .Containerfile

- name: bicep
display_name: Bicep
extensions:
- .bicep
3 changes: 2 additions & 1 deletion docs/languages-and-frameworks.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ The `codeql-extractor-iac` extractor supports the following languages:
| JSON | `.json`, `.jsonl`, `.jsonc` |
| YAML | `.yaml`, `.yml` |
| Container files | `*Dockerfile`, `*Containerfile` |
| Bicep | `.bicep` |

All of these files will be extracted and stored inside the IaC CodeQL Database.

Expand All @@ -30,7 +31,7 @@ The following table lists the supported frameworks and technologies:
| Docker / Container file(s) | 2 | extractor and library |
| GitHub Actions | 2 | extractor and library |
| OpenAPI / Swagger | 2 | extractor and library |
| Azure Bicep | 0 | currently unsupported |
| Azure Bicep | 2 | extractor and library |

_levels grades are based on completeness, higher the grade the better its supported._

Expand Down
1 change: 1 addition & 0 deletions extractor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ flate2 = "1.0"
tree-sitter = ">= 0.20, < 0.21"
tree-sitter-hcl = { git = "https://github.com/GeekMasher/tree-sitter-hcl", rev = "5e045dd1ff7852511c249c4c5d919d9556751d98" }
tree-sitter-dockerfile = { git = "https://github.com/GeekMasher/tree-sitter-dockerfile", rev = "c0a9d694d9bf8ab79a919f5f9c7bc9c169caf321" }
tree-sitter-bicep = { git = "https://github.com/GeekMasher/tree-sitter-bicep", rev = "3604d8c961ab129d2bfc6dfca56419c236ccdb83" }
clap = { version = "4.4", features = ["derive"] }
tracing = "0.1"
tracing-subscriber = { version = "0.3.17", features = ["env-filter"] }
Expand Down
1 change: 1 addition & 0 deletions extractor/src/autobuilder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub fn run(_: Options) -> std::io::Result<()> {
".tf",
".ftvars", // Terraform / HCL files
".Dockerfile", // Docker files
".bicep", // Bicep files
])
.include_globs(&[
"**/Dockerfile",
Expand Down
6 changes: 6 additions & 0 deletions extractor/src/extractor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ pub fn run(options: Options) -> std::io::Result<()> {
node_types: tree_sitter_dockerfile::NODE_TYPES,
file_globs: vec!["*Dockerfile".into(), "*Containerfile".into()],
},
simple::LanguageSpec {
prefix: "bicep",
ts_language: tree_sitter_bicep::language(),
node_types: tree_sitter_bicep::NODE_TYPES,
file_globs: vec!["*.bicep".into()],
},
],
trap_dir: options.output_dir,
trap_compression: trap::Compression::from_env("CODEQL_IAC_TRAP_COMPRESSION"),
Expand Down
4 changes: 4 additions & 0 deletions extractor/src/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ pub fn run(options: Options) -> std::io::Result<()> {
name: "DOCKERFILE".to_owned(),
node_types: tree_sitter_dockerfile::NODE_TYPES,
},
Language {
name: "BICEP".to_owned(),
node_types: tree_sitter_bicep::NODE_TYPES,
},
];

generate(languages, options.dbscheme, options.library)
Expand Down
6 changes: 6 additions & 0 deletions ql/lib/bicep.qll
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import codeql.Locations
import codeql.files.FileSystem
import codeql.bicep.AST
// Resources
import codeql.bicep.microsoft.Compute
import codeql.bicep.microsoft.Storage
4 changes: 4 additions & 0 deletions ql/lib/codeql/bicep/AST.qll
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import codeql.bicep.ast.AstNodes
import codeql.bicep.ast.Expr
import codeql.bicep.ast.Literal
import codeql.bicep.ast.Resources
67 changes: 67 additions & 0 deletions ql/lib/codeql/bicep/ast/AstNodes.qll
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
private import codeql.Locations
private import codeql.files.FileSystem
private import codeql.iac.ast.internal.Bicep

/** An AST node of a Bicep program */
class BicepAstNode extends TBicepAstNode {
string toString() { result = this.getAPrimaryQlClass() }

/** Gets the location of the AST node. */
cached
Location getLocation() { result = this.getFullLocation() } // overridden in some subclasses

/** Gets the file containing this AST node. */
cached
File getFile() { result = this.getFullLocation().getFile() }

/** Gets the location that spans the entire AST node. */
cached
final Location getFullLocation() { result = toBicepTreeSitter(this).getLocation() }

predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
if exists(this.getLocation())
then this.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
else (
filepath = "" and
startline = 0 and
startcolumn = 0 and
endline = 0 and
endcolumn = 0
)
}

/**
* Gets the parent in the AST for this node.
*/
cached
BicepAstNode getParent() { result.getAChild(_) = this }

/**
* Gets a child of this node, which can also be retrieved using a predicate
* named `pred`.
*/
cached
BicepAstNode getAChild(string pred) { none() }

/** Gets any child of this node. */
BicepAstNode getAChild() { result = this.getAChild(_) }

/**
* Gets the primary QL class for the ast node.
*/
string getAPrimaryQlClass() { result = "???" }
}

class Comment extends BicepAstNode, TComment {
override string getAPrimaryQlClass() { result = "Comment" }
}

class Infrastructure extends BicepAstNode, TInfrastructure {
private BICEP::Infrastructure infrastructure;

override string getAPrimaryQlClass() { result = "Infrastructure" }

Infrastructure() { this = TInfrastructure(infrastructure) }
}
Loading