mirror of
https://github.com/coder/coder.git
synced 2025-07-15 22:20:27 +00:00
feat: Update CLI to handle managed variables (#6220)
* WIP * hcl * useManagedVariables * fix * Fix * Fix * fix * go:build * Fix * fix: bool flag * Insert template variables * API * fix * Expose via API * More wiring * CLI for testing purposes * WIP * Delete FIXME * planVars * WIP * WIP * UserVariableValues * no dry run * Dry run * Done FIXME * Fix * Fix: CLI * Fix: migration * API tests * Test info * Tests * More tests * fix: lint * Fix: authz * Address PR comments * Fix * fix * fix * CLI: create * unit tests: create templates with variables * Use last variables * Fix * Fix * Fix * Push tests * fix: variable is required if Default is nil * WIP * Redact sensitive values * Fixes * Fixes * Fix: arg description * Fix * Variable param * Fix: gen * Fix * Fix: goldens
This commit is contained in:
@ -264,9 +264,14 @@ func (server *Server) AcquireJob(ctx context.Context, _ *proto.Empty) (*proto.Ac
|
||||
return nil, failJob(fmt.Sprintf("unmarshal job input %q: %s", job.Input, err))
|
||||
}
|
||||
|
||||
userVariableValues, err := server.includeLastVariableValues(ctx, input.TemplateVersionID, input.UserVariableValues)
|
||||
if err != nil {
|
||||
return nil, failJob(err.Error())
|
||||
}
|
||||
|
||||
protoJob.Type = &proto.AcquiredJob_TemplateImport_{
|
||||
TemplateImport: &proto.AcquiredJob_TemplateImport{
|
||||
UserVariableValues: convertVariableValues(input.UserVariableValues),
|
||||
UserVariableValues: convertVariableValues(userVariableValues),
|
||||
Metadata: &sdkproto.Provision_Metadata{
|
||||
CoderUrl: server.AccessURL.String(),
|
||||
},
|
||||
@ -290,6 +295,58 @@ func (server *Server) AcquireJob(ctx context.Context, _ *proto.Empty) (*proto.Ac
|
||||
return protoJob, err
|
||||
}
|
||||
|
||||
func (server *Server) includeLastVariableValues(ctx context.Context, templateVersionID uuid.UUID, userVariableValues []codersdk.VariableValue) ([]codersdk.VariableValue, error) {
|
||||
var values []codersdk.VariableValue
|
||||
values = append(values, userVariableValues...)
|
||||
|
||||
if templateVersionID == uuid.Nil {
|
||||
return values, nil
|
||||
}
|
||||
|
||||
templateVersion, err := server.Database.GetTemplateVersionByID(ctx, templateVersionID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get template version: %w", err)
|
||||
}
|
||||
|
||||
if templateVersion.TemplateID.UUID == uuid.Nil {
|
||||
return values, nil
|
||||
}
|
||||
|
||||
template, err := server.Database.GetTemplateByID(ctx, templateVersion.TemplateID.UUID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get template: %w", err)
|
||||
}
|
||||
|
||||
if template.ActiveVersionID == uuid.Nil {
|
||||
return values, nil
|
||||
}
|
||||
|
||||
templateVariables, err := server.Database.GetTemplateVersionVariables(ctx, template.ActiveVersionID)
|
||||
if err != nil && !xerrors.Is(err, sql.ErrNoRows) {
|
||||
return nil, fmt.Errorf("get template version variables: %w", err)
|
||||
}
|
||||
|
||||
for _, templateVariable := range templateVariables {
|
||||
var alreadyAdded bool
|
||||
for _, uvv := range userVariableValues {
|
||||
if uvv.Name == templateVariable.Name {
|
||||
alreadyAdded = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if alreadyAdded {
|
||||
continue
|
||||
}
|
||||
|
||||
values = append(values, codersdk.VariableValue{
|
||||
Name: templateVariable.Name,
|
||||
Value: templateVariable.Value,
|
||||
})
|
||||
}
|
||||
return values, nil
|
||||
}
|
||||
|
||||
func (server *Server) CommitQuota(ctx context.Context, request *proto.CommitQuotaRequest) (*proto.CommitQuotaResponse, error) {
|
||||
//nolint:gocritic // Provisionerd has specific authz rules.
|
||||
ctx = dbauthz.AsProvisionerd(ctx)
|
||||
@ -1222,8 +1279,9 @@ func convertVariableValues(variableValues []codersdk.VariableValue) []*sdkproto.
|
||||
protoVariableValues := make([]*sdkproto.VariableValue, len(variableValues))
|
||||
for i, variableValue := range variableValues {
|
||||
protoVariableValues[i] = &sdkproto.VariableValue{
|
||||
Name: variableValue.Name,
|
||||
Value: variableValue.Value,
|
||||
Name: variableValue.Name,
|
||||
Value: variableValue.Value,
|
||||
Sensitive: true, // Without the template variable schema we have to assume that every variable may be sensitive.
|
||||
}
|
||||
}
|
||||
return protoVariableValues
|
||||
|
@ -316,7 +316,7 @@ func TestAcquireJob(t *testing.T) {
|
||||
want, err := json.Marshal(&proto.AcquiredJob_TemplateImport_{
|
||||
TemplateImport: &proto.AcquiredJob_TemplateImport{
|
||||
UserVariableValues: []*sdkproto.VariableValue{
|
||||
{Name: "first", Value: "first_value"},
|
||||
{Name: "first", Sensitive: true, Value: "first_value"},
|
||||
},
|
||||
Metadata: &sdkproto.Provision_Metadata{
|
||||
CoderUrl: srv.AccessURL.String(),
|
||||
|
@ -1531,8 +1531,10 @@ func convertTemplateVersionVariables(dbVariables []database.TemplateVersionVaria
|
||||
return variables
|
||||
}
|
||||
|
||||
const redacted = "*redacted*"
|
||||
|
||||
func convertTemplateVersionVariable(variable database.TemplateVersionVariable) codersdk.TemplateVersionVariable {
|
||||
return codersdk.TemplateVersionVariable{
|
||||
templateVariable := codersdk.TemplateVersionVariable{
|
||||
Name: variable.Name,
|
||||
Description: variable.Description,
|
||||
Type: variable.Type,
|
||||
@ -1541,6 +1543,11 @@ func convertTemplateVersionVariable(variable database.TemplateVersionVariable) c
|
||||
Required: variable.Required,
|
||||
Sensitive: variable.Sensitive,
|
||||
}
|
||||
if templateVariable.Sensitive {
|
||||
templateVariable.Value = redacted
|
||||
templateVariable.DefaultValue = redacted
|
||||
}
|
||||
return templateVariable
|
||||
}
|
||||
|
||||
func watchTemplateChannel(id uuid.UUID) string {
|
||||
|
@ -1132,7 +1132,6 @@ func TestTemplateVersionVariables(t *testing.T) {
|
||||
Description: "This is the first variable",
|
||||
Type: "string",
|
||||
Required: true,
|
||||
Sensitive: true,
|
||||
},
|
||||
}
|
||||
const firstVariableValue = "foobar"
|
||||
@ -1180,7 +1179,6 @@ func TestTemplateVersionVariables(t *testing.T) {
|
||||
Description: "This is the first variable",
|
||||
Type: "string",
|
||||
Required: true,
|
||||
Sensitive: true,
|
||||
},
|
||||
{
|
||||
Name: "second_variable",
|
||||
@ -1218,4 +1216,52 @@ func TestTemplateVersionVariables(t *testing.T) {
|
||||
require.Equal(t, "", actualVariables[0].Value)
|
||||
require.Equal(t, templateVariables[1].DefaultValue, actualVariables[1].Value)
|
||||
})
|
||||
|
||||
t.Run("Redact sensitive variables", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
templateVariables := []*proto.TemplateVariable{
|
||||
{
|
||||
Name: "first_variable",
|
||||
Description: "This is the first variable",
|
||||
Type: "string",
|
||||
Required: true,
|
||||
Sensitive: true,
|
||||
},
|
||||
}
|
||||
const firstVariableValue = "foobar"
|
||||
|
||||
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID,
|
||||
createEchoResponses(templateVariables),
|
||||
func(ctvr *codersdk.CreateTemplateVersionRequest) {
|
||||
ctvr.UserVariableValues = []codersdk.VariableValue{
|
||||
{
|
||||
Name: templateVariables[0].Name,
|
||||
Value: firstVariableValue,
|
||||
},
|
||||
}
|
||||
},
|
||||
)
|
||||
templateVersion := coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
|
||||
// As user passed the value for the first parameter, the job will succeed.
|
||||
require.Empty(t, templateVersion.Job.Error)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitShort)
|
||||
defer cancel()
|
||||
|
||||
actualVariables, err := client.TemplateVersionVariables(ctx, templateVersion.ID)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Len(t, actualVariables, 1)
|
||||
require.Equal(t, templateVariables[0].Name, actualVariables[0].Name)
|
||||
require.Equal(t, templateVariables[0].Description, actualVariables[0].Description)
|
||||
require.Equal(t, templateVariables[0].Type, actualVariables[0].Type)
|
||||
require.Equal(t, templateVariables[0].Required, actualVariables[0].Required)
|
||||
require.Equal(t, templateVariables[0].Sensitive, actualVariables[0].Sensitive)
|
||||
require.Equal(t, "*redacted*", actualVariables[0].DefaultValue)
|
||||
require.Equal(t, "*redacted*", actualVariables[0].Value)
|
||||
})
|
||||
}
|
||||
|
Reference in New Issue
Block a user