diff --git a/.golangci.yml b/.golangci.yml
index e6c5e4a..ff28e33 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -22,4 +22,6 @@ linters:
linters-settings:
varnamelen:
+ ignore-type-assert-ok: true
ignore-map-index-ok: true
+ ignore-chan-recv-ok: true
diff --git a/docs/data-sources/navigator_run.md b/docs/data-sources/navigator_run.md
new file mode 100644
index 0000000..4e9d802
--- /dev/null
+++ b/docs/data-sources/navigator_run.md
@@ -0,0 +1,92 @@
+---
+# generated by https://github.com/hashicorp/terraform-plugin-docs
+page_title: "ansible_navigator_run Data Source - terraform-provider-ansible"
+subcategory: ""
+description: |-
+ Run an Ansible playbook. Recommended to only run playbooks without observable side-effects. Requires ansible-navigator and a container engine to run within an execution environment (EE).
+---
+
+# ansible_navigator_run (Data Source)
+
+Run an Ansible playbook. Recommended to only run playbooks without observable side-effects. Requires `ansible-navigator` and a container engine to run within an execution environment (EE).
+
+
+
+
+## Schema
+
+### Required
+
+- `inventory` (String) Ansible [inventory](https://docs.ansible.com/ansible/latest/getting_started/get_started_inventory.html) contents.
+- `playbook` (String) Ansible [playbook](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_intro.html) contents.
+
+### Optional
+
+- `ansible_navigator_binary` (String) Path to the `ansible-navigator` binary. By default `$PATH` is searched.
+- `ansible_options` (Attributes) Ansible [playbook](https://docs.ansible.com/ansible/latest/cli/ansible-playbook.html) run related configuration. (see [below for nested schema](#nestedatt--ansible_options))
+- `artifact_queries` (Attributes Map) Query the playbook artifact with [JSONPath](https://goessner.net/articles/JsonPath/). The [playbook artifact](https://access.redhat.com/documentation/en-us/red_hat_ansible_automation_platform/2.0-ea/html/ansible_navigator_creator_guide/assembly-troubleshooting-navigator_ansible-navigator#proc-review-artifact_troubleshooting-navigator) contains detailed information about every play and task, as well as the stdout from the playbook run. (see [below for nested schema](#nestedatt--artifact_queries))
+- `execution_environment` (Attributes) [Execution environment](https://ansible.readthedocs.io/en/latest/getting_started_ee/index.html) (EE) related configuration. (see [below for nested schema](#nestedatt--execution_environment))
+- `timeouts` (Attributes) (see [below for nested schema](#nestedatt--timeouts))
+- `timezone` (String) IANA time zone, use `local` for the system time zone. Defaults to `UTC`.
+- `working_directory` (String) Directory which `ansible-navigator` is run from. Recommended to be the root Ansible [content directory](https://docs.ansible.com/ansible/latest/tips_tricks/sample_setup.html#sample-directory-layout) (sometimes called the project directory), which is likely to contain `ansible.cfg`, `roles/`, etc.
+
+### Read-Only
+
+- `command` (String) Generated `ansible-navigator` run command. Useful for troubleshooting.
+- `id` (String) UUID.
+
+
+### Nested Schema for `ansible_options`
+
+Optional:
+
+- `force_handlers` (Boolean) Run handlers even if a task fails.
+- `limit` (List of String) Further limit selected hosts to an additional pattern.
+- `private_keys` (Attributes List) SSH private keys used for authentication in addition to the [automatically mounted](https://ansible.readthedocs.io/projects/navigator/faq/#how-do-i-use-my-ssh-keys-with-an-execution-environment) default named keys and SSH agent socket path. (see [below for nested schema](#nestedatt--ansible_options--private_keys))
+- `skip_tags` (List of String) Only run plays and tasks whose tags do not match these values.
+- `start_at_task` (String) Start the playbook at the task matching this name.
+- `tags` (List of String) Only run plays and tasks tagged with these values.
+
+
+### Nested Schema for `ansible_options.private_keys`
+
+Required:
+
+- `data` (String, Sensitive) Key data.
+- `name` (String) Key name.
+
+
+
+
+### Nested Schema for `artifact_queries`
+
+Required:
+
+- `jsonpath` (String) JSONPath expression.
+
+Read-Only:
+
+- `result` (String) Result of the query. Result may be empty if a field or map key cannot be located.
+
+
+
+### Nested Schema for `execution_environment`
+
+Optional:
+
+- `container_engine` (String) [Container engine](https://ansible.readthedocs.io/projects/navigator/settings/#container-engine) responsible for running the execution environment container image. Options: `podman`, `docker`, `auto`. Defaults to `auto`.
+- `container_options` (List of String) [Extra parameters](https://ansible.readthedocs.io/projects/navigator/settings/#container-options) passed to the container engine command.
+- `enabled` (Boolean) Enable or disable the use of an execution environment. Disabling requires `ansible-playbook` and is only recommended when without a container engine. Defaults to `true`.
+- `environment_variables_pass` (List of String) Existing environment variables to be [passed](https://ansible.readthedocs.io/projects/navigator/settings/#pass-environment-variable) through to and set within the execution environment.
+- `environment_variables_set` (Map of String) Environment variables to be [set](https://ansible.readthedocs.io/projects/navigator/settings/#set-environment-variable) within the execution environment. By default `ANSIBLE_TF_OPERATION` is set to `read`.
+- `image` (String) Name of the execution environment container [image](https://ansible.readthedocs.io/projects/navigator/settings/#execution-environment-image). Defaults to `ghcr.io/ansible/community-ansible-dev-tools:v24.7.2`.
+- `pull_arguments` (List of String) Additional [parameters](https://ansible.readthedocs.io/projects/navigator/settings/#pull-arguments) that should be added to the pull command when pulling an execution environment container image from a container registry.
+- `pull_policy` (String) Container image [pull policy](https://ansible.readthedocs.io/projects/navigator/settings/#pull-policy). Defaults to `tag`.
+
+
+
+### Nested Schema for `timeouts`
+
+Optional:
+
+- `read` (String) A string that can be [parsed as a duration](https://pkg.go.dev/time#ParseDuration) consisting of numbers and unit suffixes, such as "30s" or "2h45m". Valid time units are "s" (seconds), "m" (minutes), "h" (hours).
diff --git a/internal/provider/navigator_run_data_source.go b/internal/provider/navigator_run_data_source.go
new file mode 100644
index 0000000..280ea0c
--- /dev/null
+++ b/internal/provider/navigator_run_data_source.go
@@ -0,0 +1,420 @@
+package provider
+
+import (
+ "context"
+ "fmt"
+ "regexp"
+
+ "github.com/google/uuid"
+ "github.com/hashicorp/terraform-plugin-framework-timeouts/datasource/timeouts"
+ "github.com/hashicorp/terraform-plugin-framework-validators/listvalidator"
+ "github.com/hashicorp/terraform-plugin-framework-validators/mapvalidator"
+ "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
+ "github.com/hashicorp/terraform-plugin-framework/datasource"
+ "github.com/hashicorp/terraform-plugin-framework/datasource/schema"
+ "github.com/hashicorp/terraform-plugin-framework/diag"
+ "github.com/hashicorp/terraform-plugin-framework/schema/validator"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+ "github.com/hashicorp/terraform-plugin-framework/types/basetypes"
+ "github.com/marshallford/terraform-provider-ansible/pkg/ansible"
+)
+
+var (
+ _ datasource.DataSource = &NavigatorRunDataSource{}
+ _ datasource.DataSourceWithConfigure = &NavigatorRunDataSource{}
+)
+
+func NewNavigatorRunDataSource() datasource.DataSource { //nolint:ireturn
+ return &NavigatorRunDataSource{}
+}
+
+type NavigatorRunDataSource struct {
+ opts *providerOptions
+}
+
+type NavigatorRunDataSourceModel struct {
+ Playbook types.String `tfsdk:"playbook"`
+ Inventory types.String `tfsdk:"inventory"`
+ WorkingDirectory types.String `tfsdk:"working_directory"`
+ ExecutionEnvironment types.Object `tfsdk:"execution_environment"`
+ AnsibleNavigatorBinary types.String `tfsdk:"ansible_navigator_binary"`
+ AnsibleOptions types.Object `tfsdk:"ansible_options"`
+ Timezone types.String `tfsdk:"timezone"`
+ ArtifactQueries types.Map `tfsdk:"artifact_queries"`
+ ID types.String `tfsdk:"id"`
+ Command types.String `tfsdk:"command"`
+ Timeouts timeouts.Value `tfsdk:"timeouts"`
+}
+
+func (m NavigatorRunDataSourceModel) Value(ctx context.Context, run *navigatorRun, opts *providerOptions) diag.Diagnostics {
+ var diags diag.Diagnostics
+
+ run.dir = runDir(opts.BaseRunDirectory, m.ID.ValueString(), 0)
+ run.persistDir = opts.PersistRunDirectory
+ run.playbook = m.Playbook.ValueString()
+ run.inventory = m.Inventory.ValueString()
+ run.workingDir = m.WorkingDirectory.ValueString()
+ run.navigatorBinary = m.AnsibleNavigatorBinary.ValueString()
+
+ var eeModel ExecutionEnvironmentModel
+ diags.Append(m.ExecutionEnvironment.As(ctx, &eeModel, basetypes.ObjectAsOptions{})...)
+
+ run.navigatorSettings.Timezone = m.Timezone.ValueString()
+ diags.Append(eeModel.Value(ctx, &run.navigatorSettings)...)
+
+ var optsModel AnsibleOptionsModel
+ diags.Append(m.AnsibleOptions.As(ctx, &optsModel, basetypes.ObjectAsOptions{UnhandledNullAsEmpty: true})...)
+
+ diags.Append(optsModel.Value(ctx, &run.options)...)
+
+ var privateKeysModel []PrivateKeyModel
+ if !optsModel.PrivateKeys.IsNull() {
+ diags.Append(optsModel.PrivateKeys.ElementsAs(ctx, &privateKeysModel, false)...)
+ }
+
+ run.privateKeys = make([]ansible.PrivateKey, 0, len(privateKeysModel))
+ for _, model := range privateKeysModel {
+ var key ansible.PrivateKey
+
+ diags.Append(model.Value(ctx, &key)...)
+ run.privateKeys = append(run.privateKeys, key)
+ }
+
+ var queriesModel map[string]ArtifactQueryModel
+ diags.Append(m.ArtifactQueries.ElementsAs(ctx, &queriesModel, false)...)
+
+ run.artifactQueries = map[string]ansible.ArtifactQuery{}
+ for name, model := range queriesModel {
+ var query ansible.ArtifactQuery
+
+ diags.Append(model.Value(ctx, &query)...)
+ run.artifactQueries[name] = query
+ }
+
+ return diags
+}
+
+func (m *NavigatorRunDataSourceModel) Set(ctx context.Context, run navigatorRun) diag.Diagnostics {
+ var diags diag.Diagnostics
+
+ m.Command = types.StringValue(run.command)
+
+ var queriesModel map[string]ArtifactQueryModel
+ diags.Append(m.ArtifactQueries.ElementsAs(ctx, &queriesModel, false)...)
+
+ for name, model := range queriesModel {
+ diags.Append(model.Set(ctx, run.artifactQueries[name])...)
+ queriesModel[name] = model
+ }
+
+ queriesValue, newDiags := types.MapValueFrom(ctx, types.ObjectType{AttrTypes: ArtifactQueryModel{}.AttrTypes()}, queriesModel)
+ diags.Append(newDiags...)
+ m.ArtifactQueries = queriesValue
+
+ return diags
+}
+
+func (m *NavigatorRunDataSourceModel) SetDefaults(ctx context.Context) diag.Diagnostics {
+ var diags diag.Diagnostics
+
+ if m.WorkingDirectory.IsNull() {
+ m.WorkingDirectory = types.StringValue(defaultNavigatorRunWorkingDir)
+ }
+
+ if m.ExecutionEnvironment.IsNull() {
+ m.ExecutionEnvironment = ExecutionEnvironmentModel{}.Defaults()
+ }
+
+ var eeModel ExecutionEnvironmentModel
+ diags.Append(m.ExecutionEnvironment.As(ctx, &eeModel, basetypes.ObjectAsOptions{})...)
+
+ if eeModel.ContainerEngine.IsNull() {
+ eeModel.ContainerEngine = types.StringValue(defaultNavigatorRunContainerEngine)
+ }
+
+ if eeModel.Enabled.IsNull() {
+ eeModel.Enabled = types.BoolValue(defaultNavigatorRunEEEnabled)
+ }
+
+ if eeModel.Image.IsNull() {
+ eeModel.Image = types.StringValue(defaultNavigatorRunImage)
+ }
+
+ if eeModel.PullPolicy.IsNull() {
+ eeModel.PullPolicy = types.StringValue(defaultNavigatorRunPullPolicy)
+ }
+
+ eeValue, newDiags := types.ObjectValueFrom(ctx, ExecutionEnvironmentModel{}.AttrTypes(), eeModel)
+ diags.Append(newDiags...)
+ m.ExecutionEnvironment = eeValue
+
+ if m.Timezone.IsNull() {
+ m.Timezone = types.StringValue(defaultNavigatorRunTimezone)
+ }
+
+ return diags
+}
+
+func (d *NavigatorRunDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
+ resp.TypeName = fmt.Sprintf("%s_navigator_run", req.ProviderTypeName)
+}
+
+//nolint:dupl
+func (d *NavigatorRunDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
+ resp.Schema = schema.Schema{
+ Description: fmt.Sprintf("Run an Ansible playbook. Recommended to only run playbooks without observable side-effects. Requires '%s' and a container engine to run within an execution environment (EE).", ansible.NavigatorProgram),
+ MarkdownDescription: fmt.Sprintf("Run an Ansible playbook. Recommended to only run playbooks without observable side-effects. Requires `%s` and a container engine to run within an execution environment (EE).", ansible.NavigatorProgram),
+ Attributes: map[string]schema.Attribute{
+ // required
+ "playbook": schema.StringAttribute{
+ Description: "Ansible playbook contents.",
+ MarkdownDescription: "Ansible [playbook](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_intro.html) contents.",
+ Required: true,
+ Validators: []validator.String{
+ stringIsYAML(),
+ },
+ },
+ "inventory": schema.StringAttribute{
+ Description: "Ansible inventory contents.",
+ MarkdownDescription: "Ansible [inventory](https://docs.ansible.com/ansible/latest/getting_started/get_started_inventory.html) contents.",
+ Required: true,
+ Validators: []validator.String{
+ stringvalidator.LengthAtLeast(1),
+ },
+ },
+ // optional
+ "working_directory": schema.StringAttribute{
+ Description: fmt.Sprintf("Directory which '%s' is run from. Recommended to be the root Ansible content directory (sometimes called the project directory), which is likely to contain 'ansible.cfg', 'roles/', etc.", ansible.NavigatorProgram),
+ MarkdownDescription: fmt.Sprintf("Directory which `%s` is run from. Recommended to be the root Ansible [content directory](https://docs.ansible.com/ansible/latest/tips_tricks/sample_setup.html#sample-directory-layout) (sometimes called the project directory), which is likely to contain `ansible.cfg`, `roles/`, etc.", ansible.NavigatorProgram),
+ Optional: true,
+ Computed: true,
+ Validators: []validator.String{
+ stringvalidator.LengthAtLeast(1),
+ },
+ },
+ "execution_environment": schema.SingleNestedAttribute{
+ Description: "Execution environment (EE) related configuration.",
+ MarkdownDescription: "[Execution environment](https://ansible.readthedocs.io/en/latest/getting_started_ee/index.html) (EE) related configuration.",
+ Optional: true,
+ Computed: true,
+ Attributes: map[string]schema.Attribute{
+ "container_engine": schema.StringAttribute{
+ Description: fmt.Sprintf("Container engine responsible for running the execution environment container image. Options: %s. Defaults to '%s'.", wrapElementsJoin(ansible.ContainerEngineOptions(true), "'"), defaultNavigatorRunContainerEngine),
+ MarkdownDescription: fmt.Sprintf("[Container engine](https://ansible.readthedocs.io/projects/navigator/settings/#container-engine) responsible for running the execution environment container image. Options: %s. Defaults to `%s`.", wrapElementsJoin(ansible.ContainerEngineOptions(true), "`"), defaultNavigatorRunContainerEngine),
+ Optional: true,
+ Computed: true,
+ Validators: []validator.String{
+ stringvalidator.OneOf(ansible.ContainerEngineOptions(true)...),
+ },
+ },
+ "enabled": schema.BoolAttribute{
+ Description: fmt.Sprintf("Enable or disable the use of an execution environment. Disabling requires '%s' and is only recommended when without a container engine. Defaults to '%t'.", ansible.PlaybookProgram, defaultNavigatorRunEEEnabled),
+ MarkdownDescription: fmt.Sprintf("Enable or disable the use of an execution environment. Disabling requires `%s` and is only recommended when without a container engine. Defaults to `%t`.", ansible.PlaybookProgram, defaultNavigatorRunEEEnabled),
+ Optional: true,
+ Computed: true,
+ },
+ "environment_variables_pass": schema.ListAttribute{
+ Description: "Existing environment variables to be passed through to and set within the execution environment.",
+ MarkdownDescription: "Existing environment variables to be [passed](https://ansible.readthedocs.io/projects/navigator/settings/#pass-environment-variable) through to and set within the execution environment.",
+ Optional: true,
+ ElementType: types.StringType,
+ Validators: []validator.List{
+ listvalidator.ValueStringsAre(stringIsEnvVarName()),
+ },
+ },
+ "environment_variables_set": schema.MapAttribute{
+ Description: fmt.Sprintf("Environment variables to be set within the execution environment. By default '%s' is set to '%s'.", navigatorRunOperationEnvVar, terraformOperation(terraformOperationRead).String()),
+ MarkdownDescription: fmt.Sprintf("Environment variables to be [set](https://ansible.readthedocs.io/projects/navigator/settings/#set-environment-variable) within the execution environment. By default `%s` is set to `%s`.", navigatorRunOperationEnvVar, terraformOperation(terraformOperationRead).String()),
+ Optional: true,
+ ElementType: types.StringType,
+ Validators: []validator.Map{
+ mapvalidator.KeysAre(stringIsEnvVarName()),
+ },
+ },
+ "image": schema.StringAttribute{
+ Description: fmt.Sprintf("Name of the execution environment container image. Defaults to '%s'.", defaultNavigatorRunImage),
+ MarkdownDescription: fmt.Sprintf("Name of the execution environment container [image](https://ansible.readthedocs.io/projects/navigator/settings/#execution-environment-image). Defaults to `%s`.", defaultNavigatorRunImage),
+ Optional: true,
+ Computed: true,
+ },
+ "pull_arguments": schema.ListAttribute{
+ Description: "Additional parameters that should be added to the pull command when pulling an execution environment container image from a container registry.",
+ MarkdownDescription: "Additional [parameters](https://ansible.readthedocs.io/projects/navigator/settings/#pull-arguments) that should be added to the pull command when pulling an execution environment container image from a container registry.",
+ Optional: true,
+ ElementType: types.StringType,
+ },
+ "pull_policy": schema.StringAttribute{
+ Description: fmt.Sprintf("Container image pull policy. Defaults to '%s'.", defaultNavigatorRunPullPolicy),
+ MarkdownDescription: fmt.Sprintf("Container image [pull policy](https://ansible.readthedocs.io/projects/navigator/settings/#pull-policy). Defaults to `%s`.", defaultNavigatorRunPullPolicy),
+ Optional: true,
+ Computed: true,
+ Validators: []validator.String{
+ stringvalidator.OneOf(ansible.PullPolicyOptions()...),
+ },
+ },
+ "container_options": schema.ListAttribute{
+ Description: "Extra parameters passed to the container engine command.",
+ MarkdownDescription: "[Extra parameters](https://ansible.readthedocs.io/projects/navigator/settings/#container-options) passed to the container engine command.",
+ Optional: true,
+ ElementType: types.StringType,
+ },
+ },
+ },
+ "ansible_navigator_binary": schema.StringAttribute{
+ Description: fmt.Sprintf("Path to the '%s' binary. By default '$PATH' is searched.", ansible.NavigatorProgram),
+ MarkdownDescription: fmt.Sprintf("Path to the `%s` binary. By default `$PATH` is searched.", ansible.NavigatorProgram),
+ Optional: true,
+ Validators: []validator.String{
+ stringvalidator.LengthAtLeast(1),
+ },
+ },
+ "ansible_options": schema.SingleNestedAttribute{
+ Description: "Ansible playbook run related configuration.",
+ MarkdownDescription: "Ansible [playbook](https://docs.ansible.com/ansible/latest/cli/ansible-playbook.html) run related configuration.",
+ Optional: true,
+ Attributes: map[string]schema.Attribute{
+ "force_handlers": schema.BoolAttribute{
+ Description: "Run handlers even if a task fails.",
+ Optional: true,
+ },
+ "skip_tags": schema.ListAttribute{
+ Description: "Only run plays and tasks whose tags do not match these values.",
+ Optional: true,
+ ElementType: types.StringType,
+ },
+ "start_at_task": schema.StringAttribute{
+ Description: "Start the playbook at the task matching this name.",
+ Optional: true,
+ },
+ "limit": schema.ListAttribute{
+ Description: "Further limit selected hosts to an additional pattern.",
+ Optional: true,
+ ElementType: types.StringType,
+ },
+ "tags": schema.ListAttribute{
+ Description: "Only run plays and tasks tagged with these values.",
+ Optional: true,
+ ElementType: types.StringType,
+ },
+ "private_keys": schema.ListNestedAttribute{
+ Description: "SSH private keys used for authentication in addition to the automatically mounted default named keys and SSH agent socket path.",
+ MarkdownDescription: "SSH private keys used for authentication in addition to the [automatically mounted](https://ansible.readthedocs.io/projects/navigator/faq/#how-do-i-use-my-ssh-keys-with-an-execution-environment) default named keys and SSH agent socket path.",
+ Optional: true,
+ NestedObject: schema.NestedAttributeObject{
+ Attributes: map[string]schema.Attribute{
+ "name": schema.StringAttribute{
+ Description: "Key name.",
+ Required: true,
+ Validators: []validator.String{
+ stringvalidator.RegexMatches(
+ regexp.MustCompile(`^[a-zA-Z0-9]*$`),
+ "Must only contain only alphanumeric characters",
+ ),
+ },
+ },
+ "data": schema.StringAttribute{
+ Description: "Key data.",
+ Required: true,
+ Sensitive: true,
+ Validators: []validator.String{
+ stringIsSSHPrivateKey(),
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ "timezone": schema.StringAttribute{
+ Description: fmt.Sprintf("IANA time zone, use 'local' for the system time zone. Defaults to '%s'.", defaultNavigatorRunTimezone),
+ MarkdownDescription: fmt.Sprintf("IANA time zone, use `local` for the system time zone. Defaults to `%s`.", defaultNavigatorRunTimezone),
+ Optional: true,
+ Computed: true,
+ Validators: []validator.String{
+ stringIsIANATimezone(),
+ },
+ },
+ "artifact_queries": schema.MapNestedAttribute{
+ Description: "Query the playbook artifact with JSONPath. The playbook artifact contains detailed information about every play and task, as well as the stdout from the playbook run.",
+ MarkdownDescription: "Query the playbook artifact with [JSONPath](https://goessner.net/articles/JsonPath/). The [playbook artifact](https://access.redhat.com/documentation/en-us/red_hat_ansible_automation_platform/2.0-ea/html/ansible_navigator_creator_guide/assembly-troubleshooting-navigator_ansible-navigator#proc-review-artifact_troubleshooting-navigator) contains detailed information about every play and task, as well as the stdout from the playbook run.",
+ Optional: true,
+ NestedObject: schema.NestedAttributeObject{
+ Attributes: map[string]schema.Attribute{
+ "jsonpath": schema.StringAttribute{
+ Description: "JSONPath expression.",
+ Required: true,
+ Validators: []validator.String{
+ stringIsIsJSONPathExpression(),
+ },
+ },
+ "result": schema.StringAttribute{
+ Description: "Result of the query. Result may be empty if a field or map key cannot be located.",
+ Computed: true,
+ },
+ },
+ },
+ },
+ // computed
+ "id": schema.StringAttribute{
+ Description: "UUID.",
+ Computed: true,
+ },
+ "command": schema.StringAttribute{
+ Description: fmt.Sprintf("Generated '%s' run command. Useful for troubleshooting.", ansible.NavigatorProgram),
+ MarkdownDescription: fmt.Sprintf("Generated `%s` run command. Useful for troubleshooting.", ansible.NavigatorProgram),
+ Computed: true,
+ },
+ // timeouts
+ // TODO include defaultNavigatorRunTimeout in description
+ "timeouts": timeouts.Attributes(ctx),
+ },
+ }
+}
+
+func (d *NavigatorRunDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
+ opts, ok := configureDataSourceClient(req, resp)
+ if !ok {
+ return
+ }
+
+ d.opts = opts
+}
+
+func (d *NavigatorRunDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
+ var data *NavigatorRunDataSourceModel
+
+ resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
+ resp.Diagnostics.Append(data.SetDefaults(ctx)...)
+
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ timeout, newDiags := terraformOperationDataSourceTimeout(ctx, data.Timeouts, defaultNavigatorRunTimeout)
+ resp.Diagnostics.Append(newDiags...)
+
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ ctx, cancel := context.WithTimeout(ctx, timeout)
+ defer cancel()
+
+ data.ID = types.StringValue(uuid.New().String())
+
+ var navigatorRun navigatorRun
+ resp.Diagnostics.Append(data.Value(ctx, &navigatorRun, d.opts)...)
+
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ run(ctx, &resp.Diagnostics, timeout, terraformOperationRead, &navigatorRun)
+ resp.Diagnostics.Append(data.Set(ctx, navigatorRun)...)
+
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
+}
diff --git a/internal/provider/navigator_run_data_source_errors_test.go b/internal/provider/navigator_run_data_source_errors_test.go
new file mode 100644
index 0000000..afd928a
--- /dev/null
+++ b/internal/provider/navigator_run_data_source_errors_test.go
@@ -0,0 +1,48 @@
+package provider_test
+
+import (
+ "path/filepath"
+ "regexp"
+ "testing"
+
+ "github.com/hashicorp/terraform-plugin-testing/config"
+ "github.com/hashicorp/terraform-plugin-testing/helper/resource"
+)
+
+func TestAccNavigatorRunDataSource_errors(t *testing.T) {
+ t.Parallel()
+
+ tests := []struct {
+ name string
+ variables func(*testing.T) config.Variables
+ expected *regexp.Regexp
+ }{
+ {
+ name: "playbook",
+ expected: regexp.MustCompile("Ansible navigator run failed"),
+ },
+ }
+
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ t.Parallel()
+
+ variables := config.Variables{}
+ if test.variables != nil {
+ variables = test.variables(t)
+ }
+
+ resource.Test(t, resource.TestCase{
+ PreCheck: func() { testPreCheck(t) },
+ ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
+ Steps: []resource.TestStep{
+ {
+ Config: testTerraformFile(t, filepath.Join("navigator_run_data_source", "errors", test.name)),
+ ConfigVariables: testConfigVariables(t, variables),
+ ExpectError: test.expected,
+ },
+ },
+ })
+ })
+ }
+}
diff --git a/internal/provider/navigator_run_data_source_test.go b/internal/provider/navigator_run_data_source_test.go
new file mode 100644
index 0000000..b3cdbf3
--- /dev/null
+++ b/internal/provider/navigator_run_data_source_test.go
@@ -0,0 +1,196 @@
+package provider_test
+
+import (
+ "path/filepath"
+ "regexp"
+ "testing"
+
+ "github.com/hashicorp/terraform-plugin-testing/config"
+ "github.com/hashicorp/terraform-plugin-testing/helper/resource"
+ "github.com/hashicorp/terraform-plugin-testing/knownvalue"
+ "github.com/hashicorp/terraform-plugin-testing/plancheck"
+ "github.com/hashicorp/terraform-plugin-testing/statecheck"
+)
+
+const (
+ navigatorRunDataSource = "data.ansible_navigator_run.test"
+)
+
+func TestAccNavigatorRunDataSource_artifact_queries(t *testing.T) {
+ t.Parallel()
+
+ fileContents := "acc"
+ fileContentsUpdate := "acc_update"
+ var dataSourceCommand, dataSourceCommandUpdate string
+
+ resource.Test(t, resource.TestCase{
+ PreCheck: func() { testPreCheck(t) },
+ ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
+ Steps: []resource.TestStep{
+ {
+ Config: testTerraformFile(t, filepath.Join("navigator_run_data_source", "artifact_queries")),
+ ConfigVariables: testConfigVariables(t, config.Variables{
+ "file_contents": config.StringVariable(fileContents),
+ }),
+ Check: resource.ComposeAggregateTestCheckFunc(
+ resource.TestMatchResourceAttr(navigatorRunDataSource, "artifact_queries.stdout.result", regexp.MustCompile("ok=3")),
+ testExtractResourceAttr(navigatorRunDataSource, "command", &dataSourceCommand),
+ ),
+ ConfigStateChecks: []statecheck.StateCheck{
+ statecheck.ExpectKnownOutputValue("file_contents", knownvalue.StringExact(fileContents)),
+ },
+ },
+ {
+ Config: testTerraformFile(t, filepath.Join("navigator_run_data_source", "artifact_queries")),
+ ConfigVariables: testConfigVariables(t, config.Variables{
+ "file_contents": config.StringVariable(fileContentsUpdate),
+ }),
+ ConfigPlanChecks: resource.ConfigPlanChecks{
+ PreApply: []plancheck.PlanCheck{
+ plancheck.ExpectNonEmptyPlan(),
+ },
+ },
+ Check: resource.ComposeAggregateTestCheckFunc(
+ resource.TestMatchResourceAttr(navigatorRunDataSource, "artifact_queries.stdout.result", regexp.MustCompile("ok=3")),
+ testExtractResourceAttr(navigatorRunDataSource, "command", &dataSourceCommandUpdate),
+ testCheckAttributeValuesDiffer(&dataSourceCommand, &dataSourceCommandUpdate),
+ ),
+ ConfigStateChecks: []statecheck.StateCheck{
+ statecheck.ExpectKnownOutputValue("file_contents", knownvalue.StringExact(fileContentsUpdate)),
+ },
+ },
+ },
+ })
+}
+
+func TestAccNavigatorRunDataSource_basic(t *testing.T) {
+ t.Parallel()
+
+ resource.Test(t, resource.TestCase{
+ PreCheck: func() { testPreCheck(t) },
+ ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
+ Steps: []resource.TestStep{
+ {
+ Config: testTerraformFile(t, filepath.Join("navigator_run_data_source", "basic")),
+ ConfigVariables: testDefaultConfigVariables(t),
+ Check: resource.ComposeAggregateTestCheckFunc(
+ resource.TestCheckResourceAttrSet(navigatorRunDataSource, "playbook"),
+ resource.TestCheckResourceAttrSet(navigatorRunDataSource, "inventory"),
+ resource.TestCheckResourceAttrSet(navigatorRunDataSource, "working_directory"),
+ // resource.TestCheckResourceAttrSet(navigatorRunDataSource, "execution_environment"), TODO check elements
+ resource.TestCheckResourceAttrSet(navigatorRunDataSource, "ansible_navigator_binary"),
+ resource.TestCheckNoResourceAttr(navigatorRunDataSource, "ansible_options"),
+ resource.TestCheckResourceAttrSet(navigatorRunDataSource, "timezone"),
+ resource.TestCheckNoResourceAttr(navigatorRunDataSource, "triggers"),
+ resource.TestCheckNoResourceAttr(navigatorRunDataSource, "replacement_triggers"),
+ resource.TestCheckNoResourceAttr(navigatorRunDataSource, "artifact_queries"),
+ resource.TestCheckResourceAttrSet(navigatorRunDataSource, "id"),
+ resource.TestCheckResourceAttrSet(navigatorRunDataSource, "command"),
+ resource.TestCheckNoResourceAttr(navigatorRunDataSource, "timeouts"),
+ ),
+ },
+ },
+ })
+}
+
+func TestAccNavigatorRunDataSource_ee_defaults(t *testing.T) {
+ t.Parallel()
+
+ resource.Test(t, resource.TestCase{
+ PreCheck: func() { testPreCheck(t) },
+ ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
+ Steps: []resource.TestStep{
+ {
+ Config: testTerraformFile(t, filepath.Join("navigator_run_data_source", "ee_defaults")),
+ ConfigVariables: testDefaultConfigVariables(t),
+ Check: resource.ComposeAggregateTestCheckFunc(
+ resource.TestCheckResourceAttrSet(navigatorRunDataSource, "id"),
+ resource.TestCheckResourceAttrSet(navigatorRunDataSource, "command"),
+ ),
+ },
+ },
+ })
+}
+
+func TestAccNavigatorRunDataSource_env_vars(t *testing.T) {
+ t.Parallel()
+
+ resource.Test(t, resource.TestCase{
+ PreCheck: func() { testPreCheck(t) },
+ ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
+ Steps: []resource.TestStep{
+ {
+ Config: testTerraformFile(t, filepath.Join("navigator_run_data_source", "env_vars")),
+ ConfigVariables: testDefaultConfigVariables(t),
+ Check: resource.ComposeAggregateTestCheckFunc(
+ resource.TestCheckResourceAttrSet(navigatorRunDataSource, "id"),
+ resource.TestCheckResourceAttrSet(navigatorRunDataSource, "command"),
+ ),
+ },
+ },
+ })
+}
+
+//nolint:dupl //TODO fix
+func TestAccNavigatorRunDataSource_private_keys(t *testing.T) { //nolint:paralleltest
+ tests := []struct {
+ name string
+ variables func(*testing.T) config.Variables
+ setup func(*testing.T)
+ }{
+ {
+ name: "ee_enabled",
+ variables: func(t *testing.T) config.Variables { //nolint:thelper
+ return config.Variables{
+ "ee_enabled": config.BoolVariable(true),
+ }
+ },
+ setup: func(t *testing.T) { //nolint:thelper
+ t.Parallel()
+ },
+ },
+ {
+ name: "ee_disabled",
+ variables: func(t *testing.T) config.Variables { //nolint:thelper
+ return config.Variables{
+ "ee_enabled": config.BoolVariable(false),
+ }
+ },
+ setup: func(t *testing.T) { //nolint:thelper
+ testPrependPlaybookToPath(t)
+ },
+ },
+ }
+
+ for _, test := range tests { //nolint:paralleltest
+ t.Run(test.name, func(t *testing.T) {
+ test.setup(t)
+
+ variables := config.Variables{}
+ if test.variables != nil {
+ variables = test.variables(t)
+ }
+
+ publicKey, privateKey := testSSHKeygen(t)
+ port := testSSHServer(t, publicKey)
+
+ variables["private_key_data"] = config.StringVariable(privateKey)
+ variables["ssh_port"] = config.IntegerVariable(port)
+
+ resource.Test(t, resource.TestCase{
+ PreCheck: func() { testPreCheck(t) },
+ ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
+ Steps: []resource.TestStep{
+ {
+ Config: testTerraformFile(t, filepath.Join("navigator_run_data_source", "private_keys")),
+ ConfigVariables: testConfigVariables(t, variables),
+ Check: resource.ComposeAggregateTestCheckFunc(
+ resource.TestCheckResourceAttrSet(navigatorRunDataSource, "id"),
+ resource.TestCheckResourceAttrSet(navigatorRunDataSource, "command"),
+ ),
+ },
+ },
+ })
+ })
+ }
+}
diff --git a/internal/provider/navigator_run_resource.go b/internal/provider/navigator_run_resource.go
index d65bfe3..d575e50 100644
--- a/internal/provider/navigator_run_resource.go
+++ b/internal/provider/navigator_run_resource.go
@@ -100,6 +100,22 @@ func (ExecutionEnvironmentModel) AttrTypes() map[string]attr.Type {
}
}
+func (m ExecutionEnvironmentModel) Defaults() basetypes.ObjectValue {
+ return types.ObjectValueMust(
+ ExecutionEnvironmentModel{}.AttrTypes(),
+ map[string]attr.Value{
+ "container_engine": types.StringValue(defaultNavigatorRunContainerEngine),
+ "enabled": types.BoolValue(defaultNavigatorRunEEEnabled),
+ "environment_variables_pass": types.ListNull(types.StringType),
+ "environment_variables_set": types.MapNull(types.StringType),
+ "image": types.StringValue(defaultNavigatorRunImage),
+ "pull_arguments": types.ListNull(types.StringType),
+ "pull_policy": types.StringValue(defaultNavigatorRunPullPolicy),
+ "container_options": types.ListNull(types.StringType),
+ },
+ )
+}
+
func (m ExecutionEnvironmentModel) Value(ctx context.Context, settings *ansible.NavigatorSettings) diag.Diagnostics {
var diags diag.Diagnostics
@@ -285,6 +301,7 @@ func (r *NavigatorRunResource) Metadata(ctx context.Context, req resource.Metada
resp.TypeName = fmt.Sprintf("%s_navigator_run", req.ProviderTypeName)
}
+//nolint:dupl
func (r *NavigatorRunResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
resp.Schema = schema.Schema{
Description: fmt.Sprintf("Run an Ansible playbook. Requires '%s' and a container engine to run within an execution environment (EE).", ansible.NavigatorProgram),
@@ -313,7 +330,7 @@ func (r *NavigatorRunResource) Schema(ctx context.Context, req resource.SchemaRe
MarkdownDescription: fmt.Sprintf("Directory which `%s` is run from. Recommended to be the root Ansible [content directory](https://docs.ansible.com/ansible/latest/tips_tricks/sample_setup.html#sample-directory-layout) (sometimes called the project directory), which is likely to contain `ansible.cfg`, `roles/`, etc.", ansible.NavigatorProgram),
Optional: true,
Computed: true,
- Default: stringdefault.StaticString("."),
+ Default: stringdefault.StaticString(defaultNavigatorRunWorkingDir),
Validators: []validator.String{
stringvalidator.LengthAtLeast(1),
},
@@ -323,19 +340,7 @@ func (r *NavigatorRunResource) Schema(ctx context.Context, req resource.SchemaRe
MarkdownDescription: "[Execution environment](https://ansible.readthedocs.io/en/latest/getting_started_ee/index.html) (EE) related configuration.",
Optional: true,
Computed: true,
- Default: objectdefault.StaticValue(types.ObjectValueMust(
- ExecutionEnvironmentModel{}.AttrTypes(),
- map[string]attr.Value{
- "container_engine": types.StringValue(defaultNavigatorRunContainerEngine),
- "enabled": types.BoolValue(defaultNavigatorRunEEEnabled),
- "environment_variables_pass": types.ListNull(types.StringType),
- "environment_variables_set": types.MapNull(types.StringType),
- "image": types.StringValue(defaultNavigatorRunImage),
- "pull_arguments": types.ListNull(types.StringType),
- "pull_policy": types.StringValue(defaultNavigatorRunPullPolicy),
- "container_options": types.ListNull(types.StringType),
- },
- )),
+ Default: objectdefault.StaticValue(ExecutionEnvironmentModel{}.Defaults()),
Attributes: map[string]schema.Attribute{
"container_engine": schema.StringAttribute{
Description: fmt.Sprintf("Container engine responsible for running the execution environment container image. Options: %s. Defaults to '%s'.", wrapElementsJoin(ansible.ContainerEngineOptions(true), "'"), defaultNavigatorRunContainerEngine),
@@ -347,7 +352,7 @@ func (r *NavigatorRunResource) Schema(ctx context.Context, req resource.SchemaRe
stringvalidator.OneOf(ansible.ContainerEngineOptions(true)...),
},
},
- "enabled": schema.BoolAttribute{ // TODO update docs/readme/repo to reflect this option
+ "enabled": schema.BoolAttribute{
Description: fmt.Sprintf("Enable or disable the use of an execution environment. Disabling requires '%s' and is only recommended when without a container engine. Defaults to '%t'.", ansible.PlaybookProgram, defaultNavigatorRunEEEnabled),
MarkdownDescription: fmt.Sprintf("Enable or disable the use of an execution environment. Disabling requires `%s` and is only recommended when without a container engine. Defaults to `%t`.", ansible.PlaybookProgram, defaultNavigatorRunEEEnabled),
Optional: true,
@@ -364,8 +369,8 @@ func (r *NavigatorRunResource) Schema(ctx context.Context, req resource.SchemaRe
},
},
"environment_variables_set": schema.MapAttribute{
- Description: fmt.Sprintf("Environment variables to be set within the execution environment. By default '%s' is set to the current CRUD operation (%s).", navigatorRunOperationEnvVar, wrapElementsJoin(terraformOperations, "'")),
- MarkdownDescription: fmt.Sprintf("Environment variables to be [set](https://ansible.readthedocs.io/projects/navigator/settings/#set-environment-variable) within the execution environment. By default `%s` is set to the current CRUD operation (%s).", navigatorRunOperationEnvVar, wrapElementsJoin(terraformOperations, "`")),
+ Description: fmt.Sprintf("Environment variables to be set within the execution environment. By default '%s' is set to the current CRUD operation (%s).", navigatorRunOperationEnvVar, wrapElementsJoin(remove(terraformOperations, "read"), "'")),
+ MarkdownDescription: fmt.Sprintf("Environment variables to be [set](https://ansible.readthedocs.io/projects/navigator/settings/#set-environment-variable) within the execution environment. By default `%s` is set to the current CRUD operation (%s).", navigatorRunOperationEnvVar, wrapElementsJoin(remove(terraformOperations, "read"), "`")),
Optional: true,
ElementType: types.StringType,
Validators: []validator.Map{
@@ -647,7 +652,7 @@ func (r *NavigatorRunResource) Create(ctx context.Context, req resource.CreateRe
tflog.SetField(ctx, "runs", runs)
- timeout, newDiags := terraformOperationTimeout(ctx, terraformOperationCreate, data.Timeouts, defaultNavigatorRunTimeout)
+ timeout, newDiags := terraformOperationResourceTimeout(ctx, terraformOperationCreate, data.Timeouts, defaultNavigatorRunTimeout)
resp.Diagnostics.Append(newDiags...)
if resp.Diagnostics.HasError() {
@@ -709,7 +714,7 @@ func (r *NavigatorRunResource) Update(ctx context.Context, req resource.UpdateRe
tflog.SetField(ctx, "runs", runs)
- timeout, newDiags := terraformOperationTimeout(ctx, terraformOperationUpdate, data.Timeouts, defaultNavigatorRunTimeout)
+ timeout, newDiags := terraformOperationResourceTimeout(ctx, terraformOperationUpdate, data.Timeouts, defaultNavigatorRunTimeout)
resp.Diagnostics.Append(newDiags...)
if resp.Diagnostics.HasError() {
@@ -757,7 +762,7 @@ func (r *NavigatorRunResource) Delete(ctx context.Context, req resource.DeleteRe
tflog.SetField(ctx, "runs", runs)
- timeout, newDiags := terraformOperationTimeout(ctx, terraformOperationDelete, data.Timeouts, defaultNavigatorRunTimeout)
+ timeout, newDiags := terraformOperationResourceTimeout(ctx, terraformOperationDelete, data.Timeouts, defaultNavigatorRunTimeout)
resp.Diagnostics.Append(newDiags...)
if resp.Diagnostics.HasError() {
diff --git a/internal/provider/navigator_run_resource_errors_test.go b/internal/provider/navigator_run_resource_errors_test.go
index db19109..5ee65ad 100644
--- a/internal/provider/navigator_run_resource_errors_test.go
+++ b/internal/provider/navigator_run_resource_errors_test.go
@@ -9,7 +9,7 @@ import (
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
)
-func TestAccNavigatorRun_errors(t *testing.T) {
+func TestAccNavigatorRunResource_errors(t *testing.T) {
t.Parallel()
tests := []struct {
@@ -79,7 +79,7 @@ func TestAccNavigatorRun_errors(t *testing.T) {
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
- Config: testTerraformFile(t, filepath.Join("navigator_run", "errors", test.name)),
+ Config: testTerraformFile(t, filepath.Join("navigator_run_resource", "errors", test.name)),
ConfigVariables: testConfigVariables(t, variables),
ExpectError: test.expected,
},
diff --git a/internal/provider/navigator_run_resource_test.go b/internal/provider/navigator_run_resource_test.go
index ad37344..25d4803 100644
--- a/internal/provider/navigator_run_resource_test.go
+++ b/internal/provider/navigator_run_resource_test.go
@@ -18,7 +18,7 @@ const (
navigatorRunResource = "ansible_navigator_run.test"
)
-func TestAccNavigatorRun_ansible_options(t *testing.T) {
+func TestAccNavigatorRunResource_ansible_options(t *testing.T) {
t.Parallel()
resource.Test(t, resource.TestCase{
@@ -26,7 +26,7 @@ func TestAccNavigatorRun_ansible_options(t *testing.T) {
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
- Config: testTerraformFile(t, filepath.Join("navigator_run", "ansible_options")),
+ Config: testTerraformFile(t, filepath.Join("navigator_run_resource", "ansible_options")),
ConfigVariables: testDefaultConfigVariables(t),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestMatchResourceAttr(navigatorRunResource, "command", regexp.MustCompile("--force-handlers --skip-tags tag1,tag2 --start-at-task task name --limit host1,host2 --tags tag3,tag4")),
@@ -36,9 +36,11 @@ func TestAccNavigatorRun_ansible_options(t *testing.T) {
})
}
-func TestAccNavigatorRun_artifact_queries(t *testing.T) {
+func TestAccNavigatorRunResource_artifact_queries(t *testing.T) {
t.Parallel()
+ fileContents := "acc"
+ fileContentsUpdate := "acc_update"
var resourceCommand, resourceCommandUpdate string
resource.Test(t, resource.TestCase{
@@ -46,19 +48,23 @@ func TestAccNavigatorRun_artifact_queries(t *testing.T) {
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
- Config: testTerraformFile(t, filepath.Join("navigator_run", "artifact_queries")),
- ConfigVariables: testDefaultConfigVariables(t),
+ Config: testTerraformFile(t, filepath.Join("navigator_run_resource", "artifact_queries")),
+ ConfigVariables: testConfigVariables(t, config.Variables{
+ "file_contents": config.StringVariable(fileContents),
+ }),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestMatchResourceAttr(navigatorRunResource, "artifact_queries.stdout.result", regexp.MustCompile("ok=3")),
testExtractResourceAttr(navigatorRunResource, "command", &resourceCommand),
),
ConfigStateChecks: []statecheck.StateCheck{
- statecheck.ExpectKnownOutputValue("file_contents", knownvalue.StringExact("acc")),
+ statecheck.ExpectKnownOutputValue("file_contents", knownvalue.StringExact(fileContents)),
},
},
{
- Config: testTerraformFile(t, filepath.Join("navigator_run", "artifact_queries_update")),
- ConfigVariables: testDefaultConfigVariables(t),
+ Config: testTerraformFile(t, filepath.Join("navigator_run_resource", "artifact_queries")),
+ ConfigVariables: testConfigVariables(t, config.Variables{
+ "file_contents": config.StringVariable(fileContentsUpdate),
+ }),
ConfigPlanChecks: resource.ConfigPlanChecks{
PreApply: []plancheck.PlanCheck{
plancheck.ExpectNonEmptyPlan(),
@@ -72,14 +78,14 @@ func TestAccNavigatorRun_artifact_queries(t *testing.T) {
testCheckAttributeValuesDiffer(&resourceCommand, &resourceCommandUpdate),
),
ConfigStateChecks: []statecheck.StateCheck{
- statecheck.ExpectKnownOutputValue("file_contents", knownvalue.StringExact("acc_update")),
+ statecheck.ExpectKnownOutputValue("file_contents", knownvalue.StringExact(fileContentsUpdate)),
},
},
},
})
}
-func TestAccNavigatorRun_basic(t *testing.T) {
+func TestAccNavigatorRunResource_basic(t *testing.T) {
t.Parallel()
resource.Test(t, resource.TestCase{
@@ -87,7 +93,7 @@ func TestAccNavigatorRun_basic(t *testing.T) {
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
- Config: testTerraformFile(t, filepath.Join("navigator_run", "basic")),
+ Config: testTerraformFile(t, filepath.Join("navigator_run_resource", "basic")),
ConfigVariables: testDefaultConfigVariables(t),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttrSet(navigatorRunResource, "playbook"),
@@ -107,7 +113,7 @@ func TestAccNavigatorRun_basic(t *testing.T) {
),
},
{
- Config: testTerraformFile(t, filepath.Join("navigator_run", "basic")),
+ Config: testTerraformFile(t, filepath.Join("navigator_run_resource", "basic")),
ConfigVariables: testDefaultConfigVariables(t),
ConfigPlanChecks: resource.ConfigPlanChecks{
PreApply: []plancheck.PlanCheck{
@@ -119,7 +125,7 @@ func TestAccNavigatorRun_basic(t *testing.T) {
})
}
-func TestAccNavigatorRun_binary_in_path(t *testing.T) { //nolint:paralleltest
+func TestAccNavigatorRunResource_binary_in_path(t *testing.T) { //nolint:paralleltest
testPrependNavigatorToPath(t)
resource.Test(t, resource.TestCase{
@@ -127,7 +133,7 @@ func TestAccNavigatorRun_binary_in_path(t *testing.T) { //nolint:paralleltest
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
- Config: testTerraformFile(t, filepath.Join("navigator_run", "binary_in_path")),
+ Config: testTerraformFile(t, filepath.Join("navigator_run_resource", "binary_in_path")),
ConfigVariables: testDefaultConfigVariables(t),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttrSet(navigatorRunResource, "id"),
@@ -138,7 +144,7 @@ func TestAccNavigatorRun_binary_in_path(t *testing.T) { //nolint:paralleltest
})
}
-func TestAccNavigatorRun_ee_disabled(t *testing.T) { //nolint:paralleltest
+func TestAccNavigatorRunResource_ee_disabled(t *testing.T) { //nolint:paralleltest
testPrependPlaybookToPath(t)
resource.Test(t, resource.TestCase{
@@ -146,7 +152,7 @@ func TestAccNavigatorRun_ee_disabled(t *testing.T) { //nolint:paralleltest
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
- Config: testTerraformFile(t, filepath.Join("navigator_run", "ee_disabled")),
+ Config: testTerraformFile(t, filepath.Join("navigator_run_resource", "ee_disabled")),
ConfigVariables: testDefaultConfigVariables(t),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttrSet(navigatorRunResource, "id"),
@@ -157,7 +163,7 @@ func TestAccNavigatorRun_ee_disabled(t *testing.T) { //nolint:paralleltest
})
}
-func TestAccNavigatorRun_env_vars(t *testing.T) {
+func TestAccNavigatorRunResource_env_vars(t *testing.T) {
t.Parallel()
resource.Test(t, resource.TestCase{
@@ -165,16 +171,20 @@ func TestAccNavigatorRun_env_vars(t *testing.T) {
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
- Config: testTerraformFile(t, filepath.Join("navigator_run", "env_vars")),
- ConfigVariables: testDefaultConfigVariables(t),
+ Config: testTerraformFile(t, filepath.Join("navigator_run_resource", "env_vars")),
+ ConfigVariables: testConfigVariables(t, config.Variables{
+ "operation": config.StringVariable("create"),
+ }),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttrSet(navigatorRunResource, "id"),
resource.TestCheckResourceAttrSet(navigatorRunResource, "command"),
),
},
{
- Config: testTerraformFile(t, filepath.Join("navigator_run", "env_vars_update")),
- ConfigVariables: testDefaultConfigVariables(t),
+ Config: testTerraformFile(t, filepath.Join("navigator_run_resource", "env_vars")),
+ ConfigVariables: testConfigVariables(t, config.Variables{
+ "operation": config.StringVariable("update"),
+ }),
ConfigPlanChecks: resource.ConfigPlanChecks{
PreApply: []plancheck.PlanCheck{
plancheck.ExpectNonEmptyPlan(),
@@ -185,59 +195,71 @@ func TestAccNavigatorRun_env_vars(t *testing.T) {
})
}
-func TestAccNavigatorRun_private_keys_ee_disabled(t *testing.T) { //nolint:paralleltest
- testPrependPlaybookToPath(t)
-
- publicKey, privateKey := testSSHKeygen(t)
- port := testSSHServer(t, publicKey)
-
- resource.Test(t, resource.TestCase{
- PreCheck: func() { testPreCheck(t) },
- ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
- Steps: []resource.TestStep{
- {
- Config: testTerraformFile(t, filepath.Join("navigator_run", "private_keys")),
- ConfigVariables: testConfigVariables(t, config.Variables{
- "ee_enabled": config.BoolVariable(false),
- "private_key_data": config.StringVariable(privateKey),
- "ssh_port": config.IntegerVariable(port),
- }),
- Check: resource.ComposeAggregateTestCheckFunc(
- resource.TestCheckResourceAttrSet(navigatorRunResource, "id"),
- resource.TestCheckResourceAttrSet(navigatorRunResource, "command"),
- ),
+//nolint:dupl //TODO fix
+func TestAccNavigatorRunResource_private_keys(t *testing.T) { //nolint:paralleltest
+ tests := []struct {
+ name string
+ variables func(*testing.T) config.Variables
+ setup func(*testing.T)
+ }{
+ {
+ name: "ee_enabled",
+ variables: func(t *testing.T) config.Variables { //nolint:thelper
+ return config.Variables{
+ "ee_enabled": config.BoolVariable(true),
+ }
+ },
+ setup: func(t *testing.T) { //nolint:thelper
+ t.Parallel()
},
},
- })
-}
-
-func TestAccNavigatorRun_private_keys(t *testing.T) {
- t.Parallel()
-
- publicKey, privateKey := testSSHKeygen(t)
- port := testSSHServer(t, publicKey)
-
- resource.Test(t, resource.TestCase{
- PreCheck: func() { testPreCheck(t) },
- ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
- Steps: []resource.TestStep{
- {
- Config: testTerraformFile(t, filepath.Join("navigator_run", "private_keys")),
- ConfigVariables: testConfigVariables(t, config.Variables{
- "ee_enabled": config.BoolVariable(true),
- "private_key_data": config.StringVariable(privateKey),
- "ssh_port": config.IntegerVariable(port),
- }),
- Check: resource.ComposeAggregateTestCheckFunc(
- resource.TestCheckResourceAttrSet(navigatorRunResource, "id"),
- resource.TestCheckResourceAttrSet(navigatorRunResource, "command"),
- ),
+ {
+ name: "ee_disabled",
+ variables: func(t *testing.T) config.Variables { //nolint:thelper
+ return config.Variables{
+ "ee_enabled": config.BoolVariable(false),
+ }
+ },
+ setup: func(t *testing.T) { //nolint:thelper
+ testPrependPlaybookToPath(t)
},
},
- })
+ }
+
+ for _, test := range tests { //nolint:paralleltest
+ t.Run(test.name, func(t *testing.T) {
+ test.setup(t)
+
+ variables := config.Variables{}
+ if test.variables != nil {
+ variables = test.variables(t)
+ }
+
+ publicKey, privateKey := testSSHKeygen(t)
+ port := testSSHServer(t, publicKey)
+
+ variables["private_key_data"] = config.StringVariable(privateKey)
+ variables["ssh_port"] = config.IntegerVariable(port)
+
+ resource.Test(t, resource.TestCase{
+ PreCheck: func() { testPreCheck(t) },
+ ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
+ Steps: []resource.TestStep{
+ {
+ Config: testTerraformFile(t, filepath.Join("navigator_run_resource", "private_keys")),
+ ConfigVariables: testConfigVariables(t, variables),
+ Check: resource.ComposeAggregateTestCheckFunc(
+ resource.TestCheckResourceAttrSet(navigatorRunResource, "id"),
+ resource.TestCheckResourceAttrSet(navigatorRunResource, "command"),
+ ),
+ },
+ },
+ })
+ })
+ }
}
-func TestAccNavigatorRun_pull_args(t *testing.T) {
+func TestAccNavigatorRunResource_pull_args(t *testing.T) {
t.Parallel()
arg := "--tls-verify=true"
@@ -247,7 +269,7 @@ func TestAccNavigatorRun_pull_args(t *testing.T) {
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
- Config: testTerraformFile(t, filepath.Join("navigator_run", "pull_args")),
+ Config: testTerraformFile(t, filepath.Join("navigator_run_resource", "pull_args")),
ConfigVariables: testConfigVariables(t, config.Variables{
"pull_arguments": config.ListVariable(config.StringVariable(arg)),
}),
@@ -259,7 +281,7 @@ func TestAccNavigatorRun_pull_args(t *testing.T) {
})
}
-func TestAccNavigatorRun_relative_binary(t *testing.T) {
+func TestAccNavigatorRunResource_relative_binary(t *testing.T) {
t.Parallel()
resource.Test(t, resource.TestCase{
@@ -267,7 +289,7 @@ func TestAccNavigatorRun_relative_binary(t *testing.T) {
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
- Config: testTerraformFile(t, filepath.Join("navigator_run", "relative_binary")),
+ Config: testTerraformFile(t, filepath.Join("navigator_run_resource", "relative_binary")),
ConfigVariables: testConfigVariables(t, config.Variables{
"working_directory": config.StringVariable(t.TempDir()),
}),
@@ -280,7 +302,7 @@ func TestAccNavigatorRun_relative_binary(t *testing.T) {
})
}
-func TestAccNavigatorRun_role(t *testing.T) {
+func TestAccNavigatorRunResource_role(t *testing.T) {
t.Parallel()
resource.Test(t, resource.TestCase{
@@ -288,10 +310,10 @@ func TestAccNavigatorRun_role(t *testing.T) {
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
- Config: testTerraformFile(t, filepath.Join("navigator_run", "role")),
+ Config: testTerraformFile(t, filepath.Join("navigator_run_resource", "role")),
ConfigVariables: testConfigVariables(t, config.Variables{
// https://github.com/hashicorp/terraform-plugin-testing/issues/277
- "working_directory": config.StringVariable(filepath.Join("testdata", "navigator_run", "role-working-dir")),
+ "working_directory": config.StringVariable(filepath.Join("testdata", "navigator_run_resource", "role-working-dir")),
}),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttrSet(navigatorRunResource, "id"),
@@ -302,7 +324,7 @@ func TestAccNavigatorRun_role(t *testing.T) {
})
}
-func TestAccNavigatorRun_skip_run(t *testing.T) {
+func TestAccNavigatorRunResource_skip_run(t *testing.T) {
t.Parallel()
var resourceCommand, resourceCommandUpdate string
@@ -312,7 +334,7 @@ func TestAccNavigatorRun_skip_run(t *testing.T) {
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
- Config: testTerraformFile(t, filepath.Join("navigator_run", "skip_run")),
+ Config: testTerraformFile(t, filepath.Join("navigator_run_resource", "skip_run")),
ConfigVariables: testDefaultConfigVariables(t),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttrSet(navigatorRunResource, "id"),
@@ -321,7 +343,7 @@ func TestAccNavigatorRun_skip_run(t *testing.T) {
),
},
{
- Config: testTerraformFile(t, filepath.Join("navigator_run", "skip_run_update")),
+ Config: testTerraformFile(t, filepath.Join("navigator_run_resource", "skip_run_update")),
ConfigVariables: testConfigVariables(t, config.Variables{
"ansible_navigator_binary": config.StringVariable(acctest.RandString(8)),
}),
diff --git a/internal/provider/provider.go b/internal/provider/provider.go
index 2097bf1..5b094c8 100644
--- a/internal/provider/provider.go
+++ b/internal/provider/provider.go
@@ -108,7 +108,9 @@ func (p *AnsibleProvider) Resources(ctx context.Context) []func() resource.Resou
}
func (p *AnsibleProvider) DataSources(ctx context.Context) []func() datasource.DataSource {
- return []func() datasource.DataSource{}
+ return []func() datasource.DataSource{
+ NewNavigatorRunDataSource,
+ }
}
func New(version string) func() provider.Provider {
diff --git a/internal/provider/provider_utils.go b/internal/provider/provider_utils.go
index c96f0fc..0ce47ce 100644
--- a/internal/provider/provider_utils.go
+++ b/internal/provider/provider_utils.go
@@ -6,7 +6,9 @@ import (
"strings"
"time"
- "github.com/hashicorp/terraform-plugin-framework-timeouts/resource/timeouts"
+ dataSourceTimeouts "github.com/hashicorp/terraform-plugin-framework-timeouts/datasource/timeouts"
+ resourceTimeouts "github.com/hashicorp/terraform-plugin-framework-timeouts/resource/timeouts"
+ "github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
@@ -14,6 +16,7 @@ import (
const (
terraformOperationCreate = iota
+ terraformOperationRead = iota
terraformOperationUpdate = iota
terraformOperationDelete = iota
diagDetailPrefix = "Underlying error details"
@@ -26,16 +29,18 @@ type providerOptions struct {
type terraformOperation int
-var terraformOperations = []string{"create", "update", "delete"} //nolint:gochecknoglobals
+var terraformOperations = []string{"create", "read", "update", "delete"} //nolint:gochecknoglobals
func (op terraformOperation) String() string {
return terraformOperations[op]
}
-func terraformOperationTimeout(ctx context.Context, operation terraformOperation, value timeouts.Value, defaultTimeout time.Duration) (time.Duration, diag.Diagnostics) {
+func terraformOperationResourceTimeout(ctx context.Context, operation terraformOperation, value resourceTimeouts.Value, defaultTimeout time.Duration) (time.Duration, diag.Diagnostics) {
switch operation {
case terraformOperationCreate:
return value.Create(ctx, defaultTimeout)
+ case terraformOperationRead:
+ return value.Read(ctx, defaultTimeout)
case terraformOperationUpdate:
return value.Update(ctx, defaultTimeout)
case terraformOperationDelete:
@@ -45,6 +50,10 @@ func terraformOperationTimeout(ctx context.Context, operation terraformOperation
}
}
+func terraformOperationDataSourceTimeout(ctx context.Context, value dataSourceTimeouts.Value, defaultTimeout time.Duration) (time.Duration, diag.Diagnostics) {
+ return value.Read(ctx, defaultTimeout)
+}
+
func unknownProviderValue(value path.Path) (string, string) {
return fmt.Sprintf("Unknown configuration value '%s'", value),
fmt.Sprintf("The provider cannot be configured as there is an unknown configuration value for '%s'. ", value) +
@@ -56,27 +65,27 @@ func unexpectedConfigureType(value string, providerData any) (string, string) {
fmt.Sprintf("Expected *providerOptions, got: %T. Please report this issue to the provider developers.", providerData)
}
-// func configureDataSourceClient(req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) (*providerOptions, bool) {
-// if req.ProviderData == nil {
-// return nil, false
-// }
+func configureDataSourceClient(req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) (*providerOptions, bool) {
+ if req.ProviderData == nil {
+ return nil, false
+ }
-// opts, ok := req.ProviderData.(*providerOptions)
+ opts, ok := req.ProviderData.(*providerOptions)
-// if !ok {
-// summary, detail := unexpectedConfigureType("Data Source", req.ProviderData)
-// resp.Diagnostics.AddError(summary, detail)
-// }
+ if !ok {
+ summary, detail := unexpectedConfigureType("Data Source", req.ProviderData)
+ resp.Diagnostics.AddError(summary, detail)
+ }
-// return opts, ok
-// }
+ return opts, ok
+}
func configureResourceClient(req resource.ConfigureRequest, resp *resource.ConfigureResponse) (*providerOptions, bool) {
if req.ProviderData == nil {
return nil, false
}
- opts, ok := req.ProviderData.(*providerOptions) //nolint:varnamelen
+ opts, ok := req.ProviderData.(*providerOptions)
if !ok {
summary, detail := unexpectedConfigureType("Resource", req.ProviderData)
@@ -128,3 +137,14 @@ func wrapElements(input []string, wrap string) []string {
func wrapElementsJoin(input []string, wrap string) string {
return strings.Join(wrapElements(input, wrap), ", ")
}
+
+func remove[T comparable](l []T, item T) []T {
+ out := make([]T, 0)
+ for _, element := range l {
+ if element != item {
+ out = append(out, element)
+ }
+ }
+
+ return out
+}
diff --git a/internal/provider/run.go b/internal/provider/run.go
index daea48e..5d6ddd8 100644
--- a/internal/provider/run.go
+++ b/internal/provider/run.go
@@ -16,6 +16,7 @@ import (
const (
navigatorRunDir = "tf-ansible-navigator-run"
navigatorRunOperationEnvVar = "ANSIBLE_TF_OPERATION"
+ defaultNavigatorRunWorkingDir = "."
defaultNavigatorRunTimeout = 10 * time.Minute
defaultNavigatorRunContainerEngine = ansible.ContainerEngineAuto
defaultNavigatorRunEEEnabled = true
diff --git a/internal/provider/testdata/navigator_run/artifact_queries_update.tf b/internal/provider/testdata/navigator_run_data_source/artifact_queries.tf
similarity index 73%
rename from internal/provider/testdata/navigator_run/artifact_queries_update.tf
rename to internal/provider/testdata/navigator_run_data_source/artifact_queries.tf
index 3f4543b..e14d4d8 100644
--- a/internal/provider/testdata/navigator_run/artifact_queries_update.tf
+++ b/internal/provider/testdata/navigator_run_data_source/artifact_queries.tf
@@ -1,4 +1,4 @@
-resource "ansible_navigator_run" "test" {
+data "ansible_navigator_run" "test" {
ansible_navigator_binary = var.ansible_navigator_binary
playbook = <<-EOT
- name: Test
@@ -8,7 +8,7 @@ resource "ansible_navigator_run" "test" {
- name: write file
ansible.builtin.copy:
dest: /tmp/test
- content: acc_update
+ content: ${var.file_contents}
- name: get file
ansible.builtin.slurp:
src: /tmp/test
@@ -25,10 +25,15 @@ resource "ansible_navigator_run" "test" {
}
output "file_contents" {
- value = base64decode(ansible_navigator_run.test.artifact_queries.file_contents.result)
+ value = base64decode(data.ansible_navigator_run.test.artifact_queries.file_contents.result)
}
variable "ansible_navigator_binary" {
type = string
nullable = false
}
+
+variable "file_contents" {
+ type = string
+ nullable = false
+}
diff --git a/internal/provider/testdata/navigator_run_data_source/basic.tf b/internal/provider/testdata/navigator_run_data_source/basic.tf
new file mode 100644
index 0000000..8fe1d40
--- /dev/null
+++ b/internal/provider/testdata/navigator_run_data_source/basic.tf
@@ -0,0 +1,29 @@
+data "ansible_navigator_run" "test" {
+ ansible_navigator_binary = var.ansible_navigator_binary
+ playbook = <<-EOT
+ - hosts: some_group
+ become: false
+ tasks:
+ - ansible.builtin.debug:
+ msg: "{{ some_var }}"
+ EOT
+ inventory = yamlencode({
+ all = {
+ children = {
+ some_group = {
+ hosts = {
+ local_container = {
+ ansible_connection = "local"
+ some_var = "hello world!"
+ }
+ }
+ }
+ }
+ }
+ })
+}
+
+variable "ansible_navigator_binary" {
+ type = string
+ nullable = false
+}
diff --git a/internal/provider/testdata/navigator_run_data_source/ee_defaults.tf b/internal/provider/testdata/navigator_run_data_source/ee_defaults.tf
new file mode 100644
index 0000000..f7c171e
--- /dev/null
+++ b/internal/provider/testdata/navigator_run_data_source/ee_defaults.tf
@@ -0,0 +1,14 @@
+data "ansible_navigator_run" "test" {
+ ansible_navigator_binary = var.ansible_navigator_binary
+ playbook = <<-EOT
+ - hosts: localhost
+ become: false
+ EOT
+ inventory = "# localhost"
+ execution_environment = {}
+}
+
+variable "ansible_navigator_binary" {
+ type = string
+ nullable = false
+}
diff --git a/internal/provider/testdata/navigator_run/env_vars.tf b/internal/provider/testdata/navigator_run_data_source/env_vars.tf
similarity index 92%
rename from internal/provider/testdata/navigator_run/env_vars.tf
rename to internal/provider/testdata/navigator_run_data_source/env_vars.tf
index e0f205b..1dcf960 100644
--- a/internal/provider/testdata/navigator_run/env_vars.tf
+++ b/internal/provider/testdata/navigator_run_data_source/env_vars.tf
@@ -1,4 +1,4 @@
-resource "ansible_navigator_run" "test" {
+data "ansible_navigator_run" "test" {
ansible_navigator_binary = var.ansible_navigator_binary
playbook = <<-EOT
- hosts: localhost
@@ -6,7 +6,7 @@ resource "ansible_navigator_run" "test" {
tasks:
- ansible.builtin.assert:
that:
- - lookup('ansible.builtin.env', 'ANSIBLE_TF_OPERATION') == 'create'
+ - lookup('ansible.builtin.env', 'ANSIBLE_TF_OPERATION') == 'read'
- lookup('ansible.builtin.env', 'TF_ACC') == '1'
- lookup('ansible.builtin.env', 'TESTING') == 'abc'
EOT
diff --git a/internal/provider/testdata/navigator_run_data_source/errors/playbook.tf b/internal/provider/testdata/navigator_run_data_source/errors/playbook.tf
new file mode 100644
index 0000000..f5e3ebb
--- /dev/null
+++ b/internal/provider/testdata/navigator_run_data_source/errors/playbook.tf
@@ -0,0 +1,16 @@
+data "ansible_navigator_run" "test" {
+ ansible_navigator_binary = var.ansible_navigator_binary
+ playbook = <<-EOT
+ - hosts: localhost
+ become: false
+ tasks:
+ - ansible.builtin.fail:
+ msg: test
+ EOT
+ inventory = "# localhost"
+}
+
+variable "ansible_navigator_binary" {
+ type = string
+ nullable = false
+}
diff --git a/internal/provider/testdata/navigator_run_data_source/private_keys.tf b/internal/provider/testdata/navigator_run_data_source/private_keys.tf
new file mode 100644
index 0000000..a0bc410
--- /dev/null
+++ b/internal/provider/testdata/navigator_run_data_source/private_keys.tf
@@ -0,0 +1,58 @@
+data "ansible_navigator_run" "test" {
+ ansible_navigator_binary = var.ansible_navigator_binary
+ playbook = <<-EOT
+ - hosts: test
+ gather_facts: false
+ become: false
+ tasks:
+ - ansible.builtin.raw: test
+ register: connect
+ - ansible.builtin.assert:
+ that: connect.stdout == 'hello world!'
+ EOT
+ inventory = yamlencode({
+ all = {
+ hosts = {
+ test = {
+ ansible_host = "127.0.0.1"
+ ansible_port = var.ssh_port
+ ansible_ssh_common_args = "-o UserKnownHostsFile=/dev/null"
+ }
+ }
+ }
+ })
+ execution_environment = {
+ enabled = var.ee_enabled
+ container_options = [
+ "--net=host",
+ ]
+ }
+ ansible_options = {
+ private_keys = [
+ {
+ name = "test"
+ data = var.private_key_data
+ }
+ ]
+ }
+}
+
+variable "ansible_navigator_binary" {
+ type = string
+ nullable = false
+}
+
+variable "ee_enabled" {
+ type = bool
+ nullable = false
+}
+
+variable "private_key_data" {
+ type = string
+ nullable = false
+}
+
+variable "ssh_port" {
+ type = number
+ nullable = false
+}
diff --git a/internal/provider/testdata/navigator_run/ansible_options.tf b/internal/provider/testdata/navigator_run_resource/ansible_options.tf
similarity index 100%
rename from internal/provider/testdata/navigator_run/ansible_options.tf
rename to internal/provider/testdata/navigator_run_resource/ansible_options.tf
diff --git a/internal/provider/testdata/navigator_run/artifact_queries.tf b/internal/provider/testdata/navigator_run_resource/artifact_queries.tf
similarity index 88%
rename from internal/provider/testdata/navigator_run/artifact_queries.tf
rename to internal/provider/testdata/navigator_run_resource/artifact_queries.tf
index 95e22f4..be7b551 100644
--- a/internal/provider/testdata/navigator_run/artifact_queries.tf
+++ b/internal/provider/testdata/navigator_run_resource/artifact_queries.tf
@@ -8,7 +8,7 @@ resource "ansible_navigator_run" "test" {
- name: write file
ansible.builtin.copy:
dest: /tmp/test
- content: acc
+ content: ${var.file_contents}
- name: get file
ansible.builtin.slurp:
src: /tmp/test
@@ -32,3 +32,8 @@ variable "ansible_navigator_binary" {
type = string
nullable = false
}
+
+variable "file_contents" {
+ type = string
+ nullable = false
+}
diff --git a/internal/provider/testdata/navigator_run/basic.tf b/internal/provider/testdata/navigator_run_resource/basic.tf
similarity index 100%
rename from internal/provider/testdata/navigator_run/basic.tf
rename to internal/provider/testdata/navigator_run_resource/basic.tf
diff --git a/internal/provider/testdata/navigator_run/binary_in_path.tf b/internal/provider/testdata/navigator_run_resource/binary_in_path.tf
similarity index 100%
rename from internal/provider/testdata/navigator_run/binary_in_path.tf
rename to internal/provider/testdata/navigator_run_resource/binary_in_path.tf
diff --git a/internal/provider/testdata/navigator_run/ee_disabled.tf b/internal/provider/testdata/navigator_run_resource/ee_disabled.tf
similarity index 100%
rename from internal/provider/testdata/navigator_run/ee_disabled.tf
rename to internal/provider/testdata/navigator_run_resource/ee_disabled.tf
diff --git a/internal/provider/testdata/navigator_run/env_vars_update.tf b/internal/provider/testdata/navigator_run_resource/env_vars.tf
similarity index 78%
rename from internal/provider/testdata/navigator_run/env_vars_update.tf
rename to internal/provider/testdata/navigator_run_resource/env_vars.tf
index 559d818..a0e8a39 100644
--- a/internal/provider/testdata/navigator_run/env_vars_update.tf
+++ b/internal/provider/testdata/navigator_run_resource/env_vars.tf
@@ -6,9 +6,10 @@ resource "ansible_navigator_run" "test" {
tasks:
- ansible.builtin.assert:
that:
- - lookup('ansible.builtin.env', 'ANSIBLE_TF_OPERATION') == 'update'
+ - lookup('ansible.builtin.env', 'ANSIBLE_TF_OPERATION') == '${var.operation}'
- lookup('ansible.builtin.env', 'TF_ACC') == '1'
- lookup('ansible.builtin.env', 'TESTING') == 'abc'
+ when: lookup('ansible.builtin.env', 'ANSIBLE_TF_OPERATION') != 'delete'
EOT
inventory = "# localhost"
execution_environment = {
@@ -19,9 +20,15 @@ resource "ansible_navigator_run" "test" {
"TESTING" = "abc"
}
}
+ run_on_destroy = true
}
variable "ansible_navigator_binary" {
type = string
nullable = false
}
+
+variable "operation" {
+ type = string
+ nullable = false
+}
diff --git a/internal/provider/testdata/navigator_run/errors/artifact_query.tf b/internal/provider/testdata/navigator_run_resource/errors/artifact_query.tf
similarity index 100%
rename from internal/provider/testdata/navigator_run/errors/artifact_query.tf
rename to internal/provider/testdata/navigator_run_resource/errors/artifact_query.tf
diff --git a/internal/provider/testdata/navigator_run/errors/env_var_name.tf b/internal/provider/testdata/navigator_run_resource/errors/env_var_name.tf
similarity index 100%
rename from internal/provider/testdata/navigator_run/errors/env_var_name.tf
rename to internal/provider/testdata/navigator_run_resource/errors/env_var_name.tf
diff --git a/internal/provider/testdata/navigator_run/errors/navigator_preflight.tf b/internal/provider/testdata/navigator_run_resource/errors/navigator_preflight.tf
similarity index 100%
rename from internal/provider/testdata/navigator_run/errors/navigator_preflight.tf
rename to internal/provider/testdata/navigator_run_resource/errors/navigator_preflight.tf
diff --git a/internal/provider/testdata/navigator_run/errors/playbook.tf b/internal/provider/testdata/navigator_run_resource/errors/playbook.tf
similarity index 100%
rename from internal/provider/testdata/navigator_run/errors/playbook.tf
rename to internal/provider/testdata/navigator_run_resource/errors/playbook.tf
diff --git a/internal/provider/testdata/navigator_run/errors/playbook_yaml.tf b/internal/provider/testdata/navigator_run_resource/errors/playbook_yaml.tf
similarity index 100%
rename from internal/provider/testdata/navigator_run/errors/playbook_yaml.tf
rename to internal/provider/testdata/navigator_run_resource/errors/playbook_yaml.tf
diff --git a/internal/provider/testdata/navigator_run/errors/private_keys.tf b/internal/provider/testdata/navigator_run_resource/errors/private_keys.tf
similarity index 100%
rename from internal/provider/testdata/navigator_run/errors/private_keys.tf
rename to internal/provider/testdata/navigator_run_resource/errors/private_keys.tf
diff --git a/internal/provider/testdata/navigator_run/errors/timeout.tf b/internal/provider/testdata/navigator_run_resource/errors/timeout.tf
similarity index 100%
rename from internal/provider/testdata/navigator_run/errors/timeout.tf
rename to internal/provider/testdata/navigator_run_resource/errors/timeout.tf
diff --git a/internal/provider/testdata/navigator_run/errors/timezone.tf b/internal/provider/testdata/navigator_run_resource/errors/timezone.tf
similarity index 100%
rename from internal/provider/testdata/navigator_run/errors/timezone.tf
rename to internal/provider/testdata/navigator_run_resource/errors/timezone.tf
diff --git a/internal/provider/testdata/navigator_run/errors/working_directory.tf b/internal/provider/testdata/navigator_run_resource/errors/working_directory.tf
similarity index 100%
rename from internal/provider/testdata/navigator_run/errors/working_directory.tf
rename to internal/provider/testdata/navigator_run_resource/errors/working_directory.tf
diff --git a/internal/provider/testdata/navigator_run/private_keys.tf b/internal/provider/testdata/navigator_run_resource/private_keys.tf
similarity index 100%
rename from internal/provider/testdata/navigator_run/private_keys.tf
rename to internal/provider/testdata/navigator_run_resource/private_keys.tf
diff --git a/internal/provider/testdata/navigator_run/pull_args.tf b/internal/provider/testdata/navigator_run_resource/pull_args.tf
similarity index 100%
rename from internal/provider/testdata/navigator_run/pull_args.tf
rename to internal/provider/testdata/navigator_run_resource/pull_args.tf
diff --git a/internal/provider/testdata/navigator_run/relative_binary.tf b/internal/provider/testdata/navigator_run_resource/relative_binary.tf
similarity index 100%
rename from internal/provider/testdata/navigator_run/relative_binary.tf
rename to internal/provider/testdata/navigator_run_resource/relative_binary.tf
diff --git a/internal/provider/testdata/navigator_run/role-working-dir/ansible.cfg b/internal/provider/testdata/navigator_run_resource/role-working-dir/ansible.cfg
similarity index 100%
rename from internal/provider/testdata/navigator_run/role-working-dir/ansible.cfg
rename to internal/provider/testdata/navigator_run_resource/role-working-dir/ansible.cfg
diff --git a/internal/provider/testdata/navigator_run/role-working-dir/roles/test_role/tasks/main.yaml b/internal/provider/testdata/navigator_run_resource/role-working-dir/roles/test_role/tasks/main.yaml
similarity index 100%
rename from internal/provider/testdata/navigator_run/role-working-dir/roles/test_role/tasks/main.yaml
rename to internal/provider/testdata/navigator_run_resource/role-working-dir/roles/test_role/tasks/main.yaml
diff --git a/internal/provider/testdata/navigator_run/role.tf b/internal/provider/testdata/navigator_run_resource/role.tf
similarity index 100%
rename from internal/provider/testdata/navigator_run/role.tf
rename to internal/provider/testdata/navigator_run_resource/role.tf
diff --git a/internal/provider/testdata/navigator_run/skip_run.tf b/internal/provider/testdata/navigator_run_resource/skip_run.tf
similarity index 100%
rename from internal/provider/testdata/navigator_run/skip_run.tf
rename to internal/provider/testdata/navigator_run_resource/skip_run.tf
diff --git a/internal/provider/testdata/navigator_run/skip_run_update.tf b/internal/provider/testdata/navigator_run_resource/skip_run_update.tf
similarity index 100%
rename from internal/provider/testdata/navigator_run/skip_run_update.tf
rename to internal/provider/testdata/navigator_run_resource/skip_run_update.tf