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

update(ngrok): switch to envvars provisioner for ngrok 3.2.1 and higher #222

Merged

Conversation

arunsathiya
Copy link
Contributor

@arunsathiya arunsathiya commented Mar 27, 2023

Fixes #216 and fixes #274

Description

This PR updates the ngrok Shell Plugin to use environment variables to provision credentials when the ngrok CLI is 3.2.1 or higher. We'd retain the config file-based provisioner for older versions.

Testing instructions

  • Make sure there isn't a ngrok config file on your computer at the path depending on your OS. (This is important because as of Be aware of already existing Ngrok config file  #194, we detect such configuration files and merge with 1Password-generated configuration file)
  • Check ngrok version by running ngrok --version. If it's 3.2.1 or higher, any ngrok api command (example ngrok api tunnels list) should succeed. During this run, the credentials are provisioned using the NGROK_AUTH_TOKEN and NGROK_API_KEY environment variables. (Note that only NGROK_API_KEY is new as of 3.2.1, NGROK_AUTH_TOKEN was already supported in previous versions)
  • If the version is 3.1.1 or older, ngrok api tunnels list should still succeed, but this time the provisioning happens with configuration files.

Another way to test

  • Checkout this branch and switch to it.
  • In the file plugins/ngrok/provisioner.go, change return fileProvisioner{} to return provision.EnvVars(defaultEnvVarMapping) (line 64)
  • With ngrok 3.1.1, run ngrok api tunnels list. It should fail with ERROR: API key is missing; either use '--api-key' flag or set it as 'api_key' in the configuration file because at this point the provisioning happens with the env vars NGROK_AUTH_TOKEN and NGROK_API_KEY of which NGROK_API_KEY is not supported on 3.1.1

Download ngrok 3.1.1

To download ngrok 3.1.1, download the binary from one of these two links depending on your system architecture:

https://github.com/ngrok/homebrew-ngrok/blob/668bb053898e0f767916083f3fdeaf4a0f6eac84/Casks/ngrok.rb#L4-L10

And then run sudo unzip ~/Downloads/ngrok-v3-3.1.1-darwin-arm64.zip -d /usr/local/bin

Ensure you are running the ngrok binary that you downloaded now by running which ngrok. You don't want to be testing with another binary, say Homebrew's version if you had it installed previously. which ngrok should read /usr/local/bin/ngrok

@arunsathiya arunsathiya marked this pull request as ready for review March 27, 2023 08:30
@arunsathiya arunsathiya force-pushed the ngrok/switch-to-env-var-provisioners branch from 71c06b5 to 04bef9a Compare March 27, 2023 08:32
@arunsathiya
Copy link
Contributor Author

The CI test is failing with 2023/03/27 08:33:22 exec: "ngrok": executable file not found in $PATH but that's expected I think because ngrok binary isn't available on the machine that runs the test. Testing locally should work as expected.

@AndyTitu
Copy link
Contributor

Thanks for this great addition @arunsathiya ! I really like the logic of using the env var provisioning from versions equal or higher than 3.2.1, and still use the file provisioner based on versions lower than that, so that the shell plugin works for ngrok users regardless of their installed version.

The CI test is failing with 2023/03/27 08:33:22 exec: "ngrok": executable file not found in $PATH but that's expected I think because ngrok binary isn't available on the machine that runs the test.

For this reason, I think an improvement we could make on the OP CLI side is to also provision the tool's version via the ProvisionInput struct. It should not be the plugin's responsibility to detect the tool on the user's machine. Even more so since the CLI handles tool detection already, for now just to detect and error if a user is running a shell-plugin for a tool without having the actual tool in their PATH.
What do you think @SimonBarendse @florisvdg ?

@florisvdg
Copy link
Member

@AndyTitu That fits nicely into a plan I had a while back to make the Provisioner metadata more intelligent, which you can find on this branch.

Copy link
Member

@SimonBarendse SimonBarendse left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be great to pull out the logic for version comparison to make it easier to re-use. Worth exploring if we can go even further than the code on that branch Floris pushed and also take care of parsing the version, and maybe even the comparison func, so all the user needs to do is pass the version number.

In order to support non-standard versioning schemes (i.e. not semver) or with non-standard version command output that requires custom parsing logic, we can make it possible to pass funcs to overwrite the default behavior. but in the most common scenarios the user/plugin should require as little as possible work/code.

I believe making the code re-usable is an additive improvement, and doesn't need to block the improvement in this PR to go out. Can we already release this work from @arunsathiya then we (1Password) can take on the internal changes to add the version meta support in 1Password CLI to make it re-usable for other plugins?

plugins/ngrok/provisioner.go Outdated Show resolved Hide resolved
@arunsathiya
Copy link
Contributor Author

Thanks for the review, all of you! This should be ready for one more look, and hopefully good to merge. 🤞🏼

@hculea
Copy link
Member

hculea commented Mar 31, 2023

I have one concern related to this MR - I think it ingrains too deeply the version comparison functionality in the ngrok provisioner.

The pattern where different versions of a tool would default to different provisioners should not be isolated only to ngrok - but rather should be a core feature of the plugin ecosystem.

For example, I can imagine something along the lines of:

DefaultProvisioner: provision.ExecDependent(
  provision.ForVersion("<=2.3.5", provision.EnvVars(envVarMapping),
  provision.ForVersion(">2.3.5", provision.TempFile(...)
)

together with a validation function that would assert that all versions are covered.

I'd love to hear what y'all think!


An additional question: are there any known limitations to the current temp file approach, when it comes to ngrok?

@florisvdg
Copy link
Member

A helper function to switch provisioners based on certain conditions could be useful indeed, but I agree with Simon that it doesn't have to block this PR.

@arunsathiya
Copy link
Contributor Author

An additional question: are there any known limitations to the current temp file approach, when it comes to ngrok?

As far as I know/remember, the only concern is that the temp file approach requires a "Version" field, without which the ngrok binary doesn't work. At this point, "version: 2" is a valid field, but when in the future ngrok moves to a different version as the required/default version, we'd have to make that change on the Shell Plugins side too. Environment variables-based approach doesn't require that field.

@hculea
Copy link
Member

hculea commented Apr 13, 2023

Very eager to bring versioning to all plugin provisioners!

Before then, I agree, let's not hold this back. 😄

Copy link
Contributor

@AndyTitu AndyTitu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm. I have created an internal issue for tackling the versioning logic discussed here.

@arunsathiya arunsathiya force-pushed the ngrok/switch-to-env-var-provisioners branch from efa1da5 to e4bcfc4 Compare May 25, 2023 08:33
…ovisioner for all plugins that use ngrok credentials
@arunsathiya arunsathiya added in-progress this PR is being worked on/comments are in the process of being addressed by the contributor and removed waiting-on-sec-review labels May 25, 2023
@arunsathiya arunsathiya marked this pull request as draft May 25, 2023 08:38
@arunsathiya arunsathiya self-assigned this May 25, 2023
Copy link
Contributor

@AndyTitu AndyTitu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This generally looks good! I have left a few minor comments.

It would be good to test these changes with the Terraform plugin to make sure using ngrok Credentials with Terraform no longer returns the not supported error.

plugins/ngrok/provisioner.go Outdated Show resolved Hide resolved
plugins/ngrok/provisioner.go Outdated Show resolved Hide resolved
plugins/ngrok/provisioner.go Outdated Show resolved Hide resolved
plugins/ngrok/provisioner.go Outdated Show resolved Hide resolved
go.mod Show resolved Hide resolved
Copy link
Contributor

@AndyTitu AndyTitu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This generally looks good! I have left a few minor comments.

It would be good to test these changes with the Terraform plugin to make sure using ngrok Credentials with Terraform no longer returns the not supported error.

Copy link
Contributor

@AndyTitu AndyTitu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This generally looks good! I have left a few minor comments.

It would be good to test these changes with the Terraform plugin to make sure using ngrok Credentials with Terraform no longer returns the not supported error.

…rovisioner struct and calling Provision method on it
…kProvisioner. The test will use only file provisioner for now. This is because ngrok program is not available on the CI/CD, which in turn means that version checking does not work and defaults to file provisioner
@arunsathiya arunsathiya marked this pull request as ready for review May 26, 2023 08:10
@arunsathiya arunsathiya added waiting-on-reviewer signals that a certain PR is waiting for a review from a 1Password team member and removed in-progress this PR is being worked on/comments are in the process of being addressed by the contributor labels May 26, 2023
@arunsathiya
Copy link
Contributor Author

Thanks for the guidance, @AndyTitu. I have tested with the Terraform plugin and it works as expected.

image

My config file is as below:

terraform {
  required_providers {
    ngrok = {
      source = "ngrok/ngrok"
      version = "0.1.4"
    }
  }
}

# Configure the ngrok provider
provider "ngrok" {}

resource "ngrok_api_key" "example" {
  description = "ad-hoc dev testing"
  metadata = "{\"environment\":\"dev\"}"
}

The resource block is from here:

https://github.com/ngrok/terraform-provider-ngrok/tree/main/examples/resources

@accraw accraw added waiting-on-sec-review and removed waiting-on-reviewer signals that a certain PR is waiting for a review from a 1Password team member labels May 29, 2023
@arunsathiya
Copy link
Contributor Author

Fixes #274

@arunsathiya
Copy link
Contributor Author

Testing instructions:

  • Install ngrok 3.2.1, a higher version, and a lower version (using the original testing instructions here) and see that provisioning credentials work as expected for all of these. 3.2.1 and higher should use environment variables, while smaller ones, like 3.1.1 should use file provisioner.
  • Create a Terraform config file main.tf with the content below.
  • Run terraform init
  • Run op plugin init terraform and choose ngrok credentials.
  • Run terraform plan followed by terraform apply.
  • See that the application goes through as expected.

Terraform config file:

terraform {
  required_providers {
    ngrok = {
      source = "ngrok/ngrok"
      version = "0.1.4"
    }
  }
}

# Configure the ngrok provider
provider "ngrok" {}

resource "ngrok_api_key" "example" {
  description = "ad-hoc dev testing"
  metadata = "{\"environment\":\"dev\"}"
}

Copy link
Contributor

@AndyTitu AndyTitu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-approving to mark that I'm okay with the latest changes.

@AndyTitu AndyTitu merged commit 7911a75 into 1Password:main Jun 1, 2023
2 checks passed
@arunsathiya arunsathiya deleted the ngrok/switch-to-env-var-provisioners branch June 5, 2023 15:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ngrok compatibility with Terraform Switch to env var provisioners for ngrok
6 participants