-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Xray API v2 support for watches and policies - Use of singular key names instead of plural - Use TypeSet instead of TypeList to prevent sorting problems in TF state with multiple elements - HCL changes - #1, #2, #4
- Loading branch information
Showing
35 changed files
with
2,997 additions
and
894 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
# This GitHub action can publish assets for release when a tag is created. | ||
# Currently its setup to run on any tag that matches the pattern "v*" (ie. v0.1.0). | ||
# | ||
# This uses an action (paultyng/ghaction-import-gpg) that assumes you set your | ||
# This uses an action (hashicorp/ghaction-import-gpg) that assumes you set your | ||
# private key in the `GPG_PRIVATE_KEY` secret and passphrase in the `PASSPHRASE` | ||
# secret. If you would rather own your own GPG handling, please fork this action | ||
# or use an alternative one for key handling. | ||
|
@@ -33,7 +33,7 @@ jobs: | |
- | ||
name: Import GPG key | ||
id: import_gpg | ||
uses: paultyng/[email protected] | ||
uses: hashicorp/[email protected] | ||
env: | ||
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} | ||
PASSPHRASE: ${{ secrets.PASSPHRASE }} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,51 +1,51 @@ | ||
# Debugging a TerraForm provider | ||
# Debugging a TerraForm provider | ||
|
||
## Understanding the design | ||
|
||
In order to do it, you first have to understand how Go builds apps, and then how terraform works with it. | ||
|
||
Every terraform provider is a sort of `module`. In order to support an open, modular system, in almost any language, you need to be able to dynamically load modules and interact with them. Terraform is no exception. | ||
|
||
However, the go lang team long ago decided to compile to statically linked applications; | ||
any dependencies you have will be compiled into 1 single binary. Unlike in other native languages (like C, or C++), a | ||
However, the go lang team long ago decided to compile to statically linked applications; | ||
any dependencies you have will be compiled into 1 single binary. Unlike in other native languages (like C, or C++), a | ||
`.dll` or `.so` is not used; there is no dynamic library to load at runtime and thus, modularity becomes a whole other trick. | ||
This is done to avoid the notorious **dll hell** that was so common up until most modern systems included some | ||
This is done to avoid the notorious **dll hell** that was so common up until most modern systems included some | ||
kind of dependency management. And yes, it can still be an issue. | ||
|
||
Every terraform provider is its own mini RPC server. When terraform runs your provider, it actually starts a new process that is your provider, and connects to it through | ||
this RPC channel. Compounding the problem is that the lifetime of your provider process is very much | ||
Every terraform provider is its own mini RPC server. When terraform runs your provider, it actually starts a new process that is your provider, and connects to it through | ||
this RPC channel. Compounding the problem is that the lifetime of your provider process is very much | ||
ephemeral; potentially lasting no more and a few seconds. It's this process you need to connect to with your debugger | ||
|
||
### Normal debugging | ||
Normally, you would directly spin-up your app, and it would load modules into application memory. That's why you can actually | ||
debug it, because your debugger knows how to find the exact memory address for your provider. However, you don't have | ||
this arrangement, and you need to do a _remote_ debug session. | ||
debug it, because your debugger knows how to find the exact memory address for your provider. However, you don't have | ||
this arrangement, and you need to do a _remote_ debug session. | ||
|
||
### The conundrum | ||
So, you don't load terraform directly, and even if you did, your `module` (a.k.a your provider) is in the memory | ||
space of an entirely different process; and that lasts no more than a few seconds, potentially. | ||
So, you don't load terraform directly, and even if you did, your `module` (a.k.a your provider) is in the memory | ||
space of an entirely different process; and that lasts no more than a few seconds, potentially. | ||
|
||
## The solution | ||
|
||
1. You need the debugging tool [delve](https://github.com/go-delve/delve). | ||
2. You are going to have to place a little bit of shim code close to the spot in the code where you want to begin | ||
debugging. We need to stop this provider process from exiting before we can connect. So, put this bit of code in place: | ||
debugging. We need to stop this provider process from exiting before we can connect. So, put this bit of code in place: | ||
```go | ||
connected := false | ||
for !connected { | ||
time.Sleep(time.Second) // set breakpoint here | ||
} | ||
for !connected { | ||
time.Sleep(time.Second) // set breakpoint here | ||
} | ||
``` | ||
This code effectively creates an infinite sleep loop; but that's actually essential to solving the problem. | ||
|
||
3. Place a break point right inside this loop. It won't do anything, yet. | ||
3. Place a break point right inside this loop. It won't do anything, yet. | ||
4. Now run the terraform commands you need to, to engage the code you're desiring to debug. Upon doing so, | ||
terraform will basically stop, as it waits on a response from you provider; because you put an infinite sleep loop in | ||
terraform will basically stop, as it waits on a response from you provider; because you put an infinite sleep loop in | ||
5. You must now tell `delve` to connect to this remote process using it's PID. This isn't as hard as it seems. | ||
Run this commands: | ||
`dlv --listen=:2345 --headless=true --api-version=2 --accept-multiclient attach $(pgrep terraform-provider-xray)` | ||
The last argument gets the `PID` for your provider and supplies it to `delve` to connect. Immediately upon running this | ||
command, you're going to hit your break point. Please make sure to substitute `terraform-provider-xray` for your provider name | ||
6. To exit this infinite loop, use your debugger to set `connected` to `true`. By doing so you change the loop predicate | ||
and it will exit this loop on the next iteration. | ||
Run this commands: | ||
`dlv --listen=:2345 --headless=true --api-version=2 --accept-multiclient attach $(pgrep terraform-provider-xray)` | ||
The last argument gets the `PID` for your provider and supplies it to `delve` to connect. Immediately upon running this | ||
command, you're going to hit your break point. Please make sure to substitute `terraform-provider-xray` for your provider name | ||
6. To exit this infinite loop, use your debugger to set `connected` to `true`. By doing so you change the loop predicate | ||
and it will exit this loop on the next iteration. | ||
7. *DEBUG!* - At this point you can, step, watch, drop the call stack, etc. Your whole arsenel is available |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,181 @@ | ||
--- | ||
layout: "" | ||
page_title: "JFrog Xray Provider" | ||
description: |- | ||
The Xray provider is used to interact with the resources supported by JFrog Xray. | ||
--- | ||
|
||
# JFrog Xray Provider | ||
|
||
The [Xray](https://jfrog.com/xray/) provider is used to interact with the | ||
resources supported by JFrog Xray. Xray is a part of JFrog Artifactory and can't be used separately. | ||
The provider needs to be configured with the proper credentials before it can be used. | ||
Xray API documentation can be found [here](https://www.jfrog.com/confluence/display/JFROG/Xray+REST+API) | ||
|
||
Links to documentation for specific resources can be found in the table of contents to the left. | ||
|
||
This provider requires access to Artifactory and Xray APIs, which are only available in the _licensed_ pro and enterprise editions. | ||
You can determine which license you have by accessing the following URL | ||
`${host}/artifactory/api/system/licenses/` | ||
|
||
You can either access it via api, or web browser - it does require admin level credentials, but it's one of the few APIs that will work without a license (side node: you can also install your license here with a `POST`) | ||
|
||
```bash | ||
curl -sL ${host}/projects/api/system/licenses/ | jq . | ||
{ | ||
"type" : "Enterprise Plus Trial", | ||
"validThrough" : "Jan 29, 2022", | ||
"licensedTo" : "JFrog Ltd" | ||
} | ||
``` | ||
|
||
The following 3 license types (`jq .type`) do **NOT** support APIs: | ||
- Community Edition for C/C++ | ||
- JCR Edition | ||
- OSS | ||
|
||
## Example Usage | ||
|
||
```terraform | ||
# Required for Terraform 0.13 and up (https://www.terraform.io/upgrade-guides/0-13.html) | ||
terraform { | ||
required_providers { | ||
xray = { | ||
source = "registry.terraform.io/jfrog/xray" | ||
version = "0.0.1" | ||
} | ||
} | ||
} | ||
provider "xray" { | ||
url = "artifactory.site.com/xray" | ||
access_token = "abc..xy" | ||
// Also user can supply the following env vars: | ||
// ARTIFACTORY_URL or JFROG_URL | ||
// XRAY_ACCESS_TOKEN or JFROG_ACCESS_TOKEN | ||
} | ||
resource "random_id" "randid" { | ||
byte_length = 2 | ||
} | ||
resource "xray_security_policy" "security_policy" { | ||
name = "test-security-policy-severity-${random_id.randid.dec}" | ||
description = "Security policy description" | ||
type = "security" | ||
rule { | ||
name = "rule-name-severity" | ||
priority = 1 | ||
criteria { | ||
min_severity = "High" | ||
} | ||
actions { | ||
webhooks = [] | ||
mails = ["[email protected]"] | ||
block_release_bundle_distribution = true | ||
fail_build = true | ||
notify_watch_recipients = true | ||
notify_deployer = true | ||
create_ticket_enabled = false // set to true only if Jira integration is enabled | ||
build_failure_grace_period_in_days = 5 // use only if fail_build is enabled | ||
block_download { | ||
unscanned = true | ||
active = true | ||
} | ||
} | ||
} | ||
} | ||
resource "xray_license_policy" "license_policy" { | ||
name = "test-license-policy-allowed-${random_id.randid.dec}" | ||
description = "License policy, allow certain licenses" | ||
type = "license" | ||
rule { | ||
name = "License_rule" | ||
priority = 1 | ||
criteria { | ||
allowed_licenses = ["Apache-1.0", "Apache-2.0"] | ||
allow_unknown = false | ||
multi_license_permissive = true | ||
} | ||
actions { | ||
webhooks = [] | ||
mails = ["[email protected]"] | ||
block_release_bundle_distribution = false | ||
fail_build = true | ||
notify_watch_recipients = true | ||
notify_deployer = true | ||
create_ticket_enabled = false // set to true only if Jira integration is enabled | ||
custom_severity = "High" | ||
build_failure_grace_period_in_days = 5 // use only if fail_build is enabled | ||
block_download { | ||
unscanned = true | ||
active = true | ||
} | ||
} | ||
} | ||
} | ||
resource "xray_watch" "all-repos" { | ||
name = "all-repos-watch-${random_id.randid.dec}" | ||
description = "Watch for all repositories, matching the filter" | ||
active = true | ||
watch_resource { | ||
type = "all-repos" | ||
filter { | ||
type = "regex" | ||
value = ".*" | ||
} | ||
} | ||
assigned_policy { | ||
name = xray_security_policy.security_policy.name | ||
type = "security" | ||
} | ||
assigned_policy { | ||
name = xray_license_policy.license_policy.name | ||
type = "license" | ||
} | ||
watch_recipients = ["[email protected]", "[email protected]"] | ||
} | ||
``` | ||
|
||
## Authentication | ||
|
||
The Xray provider supports one type of authentication using Bearer token. | ||
|
||
### Bearer Token | ||
Artifactory access tokens may be used via the Authorization header by providing the `access_token` field to the provider | ||
block. Getting this value from the environment is supported with the `XRAY_ACCESS_TOKEN`, | ||
or `JFROG_ACCESS_TOKEN` variables. | ||
Set `url` field to provide JFrog Xray URL. Alternatively you can set `ARTIFACTORY_URL`, `JFROG_URL` or `PROJECTS_URL` variables. | ||
|
||
Usage: | ||
```hcl | ||
# Configure the Xray provider | ||
provider "xray" { | ||
url = "artifactory.site.com/xray" | ||
access_token = "abc...xy" | ||
} | ||
``` | ||
|
||
<!-- schema generated by tfplugindocs --> | ||
## Schema | ||
|
||
### Optional | ||
|
||
- **access_token** (String, Sensitive) This is a bearer token that can be given to you by your admin under `Identity and Access` | ||
- **url** (String) URL of Artifactory. This can also be sourced from the `XRAY_URL` or `JFROG_URL` environment variable. Default to 'http://localhost:8081' if not set. |
Empty file.
Oops, something went wrong.