From 7c9e98d940d535285e53a67e711e7bc13e5f3221 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20De=20Smet?= Date: Mon, 9 Dec 2024 10:11:12 +0000 Subject: [PATCH] [Feature] Allow to filter jobs by name in `databricks_jobs` data source (#3395) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Changes I've added a filter to obtain only job ids if the name contains a certain string. Inspired by the logic applied at databricks_clusters ![image](https://github.com/databricks/terraform-provider-databricks/assets/28486949/8233e9c2-1f5c-47cd-a5fd-a2d2bbfba370) ## Tests - [ ] `make test` run locally - [x] relevant change in `docs/` folder - [ ] covered with integration tests in `internal/acceptance` - [ ] relevant acceptance tests are passing - [ ] using Go SDK --------- Co-authored-by: Frédéric De Smet Co-authored-by: Alex Ott --- docs/data-sources/jobs.md | 8 ++++++++ jobs/data_jobs.go | 37 ++++++++++++++++++++++--------------- jobs/data_jobs_test.go | 38 +++++++++++++++++++++++++++++++++++++- jobs/resource_job.go | 3 +-- 4 files changed, 68 insertions(+), 18 deletions(-) diff --git a/docs/data-sources/jobs.md b/docs/data-sources/jobs.md index c56aaec94b..077b6d3661 100644 --- a/docs/data-sources/jobs.md +++ b/docs/data-sources/jobs.md @@ -16,6 +16,10 @@ Granting view [databricks_permissions](../resources/permissions.md) to all [data ```hcl data "databricks_jobs" "this" {} +data "databricks_jobs" "tests" { + job_name_contains = "test" +} + resource "databricks_permissions" "everyone_can_view_all_jobs" { for_each = data.databricks_jobs.this.ids job_id = each.value @@ -38,6 +42,10 @@ output "x" { } ``` +## Argument Reference + +* `job_name_contains` - (Optional) Only return [databricks_job](../resources/job.md#) ids that match the given name string (case-insensitive). + ## Attribute Reference This data source exports the following attributes: diff --git a/jobs/data_jobs.go b/jobs/data_jobs.go index a3d6a327c5..abc158c121 100644 --- a/jobs/data_jobs.go +++ b/jobs/data_jobs.go @@ -3,29 +3,36 @@ package jobs import ( "context" "fmt" + "strconv" + "strings" + "github.com/databricks/databricks-sdk-go" + "github.com/databricks/databricks-sdk-go/service/jobs" "github.com/databricks/terraform-provider-databricks/common" ) func DataSourceJobs() common.Resource { - type jobsData struct { - Ids map[string]string `json:"ids,omitempty" tf:"computed"` - } - return common.DataResource(jobsData{}, func(ctx context.Context, e any, c *common.DatabricksClient) error { - response := e.(*jobsData) - jobsAPI := NewJobsAPI(ctx, c) - list, err := jobsAPI.List() - if err != nil { - return err - } - response.Ids = map[string]string{} - for _, v := range list { - name := v.Settings.Name - _, duplicateName := response.Ids[name] + return common.WorkspaceData(func(ctx context.Context, data *struct { + Ids map[string]string `json:"ids,omitempty" tf:"computed"` + NameFilter string `json:"job_name_contains,omitempty"` + }, w *databricks.WorkspaceClient) error { + iter := w.Jobs.List(ctx, jobs.ListJobsRequest{ExpandTasks: false, Limit: 100}) + data.Ids = map[string]string{} + nameFilter := strings.ToLower(data.NameFilter) + for iter.HasNext(ctx) { + job, err := iter.Next(ctx) + if err != nil { + return err + } + name := job.Settings.Name + if nameFilter != "" && !strings.Contains(strings.ToLower(name), nameFilter) { + continue + } + _, duplicateName := data.Ids[name] if duplicateName { return fmt.Errorf("duplicate job name detected: %s", name) } - response.Ids[name] = v.ID() + data.Ids[name] = strconv.FormatInt(job.JobId, 10) } return nil }) diff --git a/jobs/data_jobs_test.go b/jobs/data_jobs_test.go index a516832609..327240f2c3 100644 --- a/jobs/data_jobs_test.go +++ b/jobs/data_jobs_test.go @@ -11,7 +11,7 @@ func TestJobsData(t *testing.T) { Fixtures: []qa.HTTPFixture{ { Method: "GET", - Resource: "/api/2.1/jobs/list?expand_tasks=false&limit=25", + Resource: "/api/2.1/jobs/list?limit=100", Response: JobListResponse{ Jobs: []Job{ { @@ -41,3 +41,39 @@ func TestJobsData(t *testing.T) { }, }) } + +func TestJobsDataWithFilter(t *testing.T) { + qa.ResourceFixture{ + Fixtures: []qa.HTTPFixture{ + { + Method: "GET", + Resource: "/api/2.1/jobs/list?limit=100", + Response: JobListResponse{ + Jobs: []Job{ + { + JobID: 123, + Settings: &JobSettings{ + Name: "First", + }, + }, + { + JobID: 234, + Settings: &JobSettings{ + Name: "Second", + }, + }, + }, + }, + }, + }, + Resource: DataSourceJobs(), + Read: true, + NonWritable: true, + ID: "_", + HCL: `job_name_contains = "Sec"`, + }.ApplyAndExpectData(t, map[string]any{ + "ids": map[string]any{ + "Second": "234", + }, + }) +} diff --git a/jobs/resource_job.go b/jobs/resource_job.go index e619ceac49..7b93f295cd 100644 --- a/jobs/resource_job.go +++ b/jobs/resource_job.go @@ -677,8 +677,7 @@ func (a JobsAPI) ListByName(name string, expandTasks bool) ([]Job, error) { // List all jobs func (a JobsAPI) List() (l []Job, err error) { - l, err = a.ListByName("", false) - return + return a.ListByName("", false) } // RunsList returns a job runs list