Skip to content

Commit c195a31

Browse files
Add user agent detection for direct deployment (#3611)
## Why? We can analyze whether requests use direct deployment or Terraform deployment. ## Tests New acceptance test.
1 parent 408779d commit c195a31

File tree

8 files changed

+81
-25
lines changed

8 files changed

+81
-25
lines changed

acceptance/bundle/user_agent/out.test.toml

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
engine/direct-exp
2+
engine/direct-exp
3+
engine/direct-exp
4+
engine/direct-exp
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
engine/terraform
2+
engine/terraform
3+
engine/terraform
4+
engine/terraform
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
2+
>>> [CLI] bundle validate
3+
Name: test-bundle
4+
Target: default
5+
Workspace:
6+
User: [USERNAME]
7+
Path: /Workspace/Users/[USERNAME]/.bundle/test-bundle/default
8+
9+
Validation OK!
10+
11+
=== API request paths
12+
>>> cat out.requests.txt
13+
"/api/2.0/preview/scim/v2/Me"
14+
"/api/2.0/workspace/get-status"
15+
"/api/2.0/workspace/mkdirs"
16+
"/api/2.0/workspace/get-status"
17+
18+
=== write engine value in user agent to file
19+
>>> cat out.requests.txt
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
trace $CLI bundle validate
2+
3+
title "API request paths"
4+
trace cat out.requests.txt | jq .path
5+
6+
title "write engine value in user agent to file"
7+
trace cat out.requests.txt | jq -r '.headers["User-Agent"][0] | split(" ") | map(select(startswith("engine/"))) | .[0]' > out.user_agent.$DATABRICKS_BUNDLE_ENGINE.txt
8+
9+
rm out.requests.txt
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
RecordRequests = true
2+
Local = true
3+
EnvVaryOutput = "DATABRICKS_BUNDLE_ENGINE"
4+
5+
IncludeRequestHeaders = ["User-Agent"]
6+
7+
[EnvMatrix]
8+
DATABRICKS_BUNDLE_ENGINE = ["terraform", "direct-exp"]

bundle/phases/initialize.go

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package phases
22

33
import (
44
"context"
5-
"fmt"
65

76
"github.com/databricks/cli/bundle/config/mutator/resourcemutator"
87

@@ -18,7 +17,6 @@ import (
1817
"github.com/databricks/cli/bundle/permissions"
1918
"github.com/databricks/cli/bundle/scripts"
2019
"github.com/databricks/cli/bundle/trampoline"
21-
"github.com/databricks/cli/libs/env"
2220
"github.com/databricks/cli/libs/log"
2321
"github.com/databricks/cli/libs/logdiag"
2422
)
@@ -27,16 +25,8 @@ import (
2725
// Interpolation of fields referring to the "bundle" and "workspace" keys
2826
// happens upon completion of this phase.
2927
func Initialize(ctx context.Context, b *bundle.Bundle) {
30-
var err error
31-
3228
log.Info(ctx, "Phase: initialize")
3329

34-
b.DirectDeployment, err = IsDirectDeployment(ctx)
35-
if err != nil {
36-
logdiag.LogError(ctx, err)
37-
return
38-
}
39-
4030
bundle.ApplySeqContext(ctx, b,
4131
// Reads (dynamic): resource.*.*
4232
// Checks that none of resources.<type>.<key> is nil. Raises error otherwise.
@@ -223,18 +213,3 @@ func Initialize(ctx context.Context, b *bundle.Bundle) {
223213
// Executes the post_init script hook defined in the bundle configuration
224214
bundle.ApplyContext(ctx, b, scripts.Execute(config.ScriptPostInit))
225215
}
226-
227-
func IsDirectDeployment(ctx context.Context) (bool, error) {
228-
deployment := env.Get(ctx, "DATABRICKS_BUNDLE_ENGINE")
229-
// We use "direct-exp" while direct backend is not suitable for end users.
230-
// Once we consider it usable we'll change the value to "direct".
231-
// This is to prevent accidentally running direct backend with older CLI versions where it was still considered experimental.
232-
switch deployment {
233-
case "direct-exp":
234-
return true, nil
235-
case "terraform", "":
236-
return false, nil
237-
default:
238-
return false, fmt.Errorf("unexpected setting for DATABRICKS_BUNDLE_ENGINE=%#v (expected 'terraform' or 'direct-exp' or absent/empty which means 'terraform')", deployment)
239-
}
240-
}

cmd/bundle/utils/utils.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,17 @@ package utils
22

33
import (
44
"context"
5+
"fmt"
56

67
"github.com/databricks/cli/bundle"
78
"github.com/databricks/cli/bundle/config/validate"
89
"github.com/databricks/cli/bundle/deployplan"
910
"github.com/databricks/cli/bundle/phases"
1011
"github.com/databricks/cli/cmd/root"
1112
"github.com/databricks/cli/libs/diag"
13+
"github.com/databricks/cli/libs/env"
1214
"github.com/databricks/cli/libs/logdiag"
15+
"github.com/databricks/databricks-sdk-go/useragent"
1316
"github.com/spf13/cobra"
1417
)
1518

@@ -39,9 +42,38 @@ func ConfigureBundleWithVariables(cmd *cobra.Command) *bundle.Bundle {
3942
// Initialize variables by assigning them values passed as command line flags
4043
configureVariables(cmd, b, variables)
4144

45+
engine, err := deploymentEngine(ctx)
46+
if err != nil {
47+
logdiag.LogError(ctx, err)
48+
return b
49+
}
50+
51+
// We use "direct-exp" while direct backend is not suitable for end users.
52+
// Once we consider it usable we'll change the value to "direct".
53+
// This is to prevent accidentally running direct backend with older CLI versions where it was still considered experimental.
54+
b.DirectDeployment = engine == "direct-exp"
55+
56+
// Set the engine in the user agent
57+
ctx = useragent.InContext(ctx, "engine", engine)
58+
cmd.SetContext(ctx)
4259
return b
4360
}
4461

62+
func deploymentEngine(ctx context.Context) (string, error) {
63+
engine := env.Get(ctx, "DATABRICKS_BUNDLE_ENGINE")
64+
65+
// By default, use Terraform
66+
if engine == "" {
67+
return "terraform", nil
68+
}
69+
70+
if engine != "terraform" && engine != "direct-exp" {
71+
return "", fmt.Errorf("unexpected setting for DATABRICKS_BUNDLE_ENGINE=%#v (expected 'terraform' or 'direct-exp' or absent/empty which means 'terraform')", engine)
72+
}
73+
74+
return engine, nil
75+
}
76+
4577
func GetPlan(ctx context.Context, b *bundle.Bundle) (*deployplan.Plan, error) {
4678
phases.Initialize(ctx, b)
4779
if logdiag.HasError(ctx) {

0 commit comments

Comments
 (0)