diff --git a/cli/deployment/config.go b/cli/deployment/config.go index aaa64d2bea963..3216b22753187 100644 --- a/cli/deployment/config.go +++ b/cli/deployment/config.go @@ -362,12 +362,6 @@ func newConfig() *codersdk.DeploymentConfig { Flag: "ssh-keygen-algorithm", Default: "ed25519", }, - AutoImportTemplates: &codersdk.DeploymentConfigField[[]string]{ - Name: "Auto Import Templates", - Usage: "Templates to auto-import. Available auto-importable templates are: kubernetes", - Flag: "auto-import-template", - Hidden: true, - }, MetricsCacheRefreshInterval: &codersdk.DeploymentConfigField[time.Duration]{ Name: "Metrics Cache Refresh Interval", Usage: "How frequently metrics are refreshed", diff --git a/cli/server.go b/cli/server.go index e04ffc4283cb7..bcb1e41492f27 100644 --- a/cli/server.go +++ b/cli/server.go @@ -371,27 +371,6 @@ func Server(vip *viper.Viper, newAPI func(context.Context, *coderd.Options) (*co return xerrors.Errorf("parse ssh keygen algorithm %s: %w", cfg.SSHKeygenAlgorithm.Value, err) } - // Validate provided auto-import templates. - var ( - validatedAutoImportTemplates = make([]coderd.AutoImportTemplate, len(cfg.AutoImportTemplates.Value)) - seenValidatedAutoImportTemplates = make(map[coderd.AutoImportTemplate]struct{}, len(cfg.AutoImportTemplates.Value)) - ) - for i, autoImportTemplate := range cfg.AutoImportTemplates.Value { - var v coderd.AutoImportTemplate - switch autoImportTemplate { - case "kubernetes": - v = coderd.AutoImportTemplateKubernetes - default: - return xerrors.Errorf("auto import template %q is not supported", autoImportTemplate) - } - - if _, ok := seenValidatedAutoImportTemplates[v]; ok { - return xerrors.Errorf("auto import template %q is specified more than once", v) - } - seenValidatedAutoImportTemplates[v] = struct{}{} - validatedAutoImportTemplates[i] = v - } - defaultRegion := &tailcfg.DERPRegion{ EmbeddedRelay: true, RegionID: cfg.DERP.Server.RegionID.Value, @@ -449,7 +428,6 @@ func Server(vip *viper.Viper, newAPI func(context.Context, *coderd.Options) (*co SSHKeygenAlgorithm: sshKeygenAlgorithm, TracerProvider: tracerProvider, Telemetry: telemetry.NewNoop(), - AutoImportTemplates: validatedAutoImportTemplates, MetricsCacheRefreshInterval: cfg.MetricsCacheRefreshInterval.Value, AgentStatsRefreshInterval: cfg.AgentStatRefreshInterval.Value, DeploymentConfig: cfg, diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index ebd1a8a8e4498..258279b6cb5fa 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -1573,9 +1573,6 @@ const docTemplate = `{ "audit_logging": { "$ref": "#/definitions/codersdk.DeploymentConfigField-bool" }, - "auto_import_templates": { - "$ref": "#/definitions/codersdk.DeploymentConfigField-array_string" - }, "autobuild_poll_interval": { "$ref": "#/definitions/codersdk.DeploymentConfigField-time_Duration" }, diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index 3b3514852255e..22cc73a97c388 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -1393,9 +1393,6 @@ "audit_logging": { "$ref": "#/definitions/codersdk.DeploymentConfigField-bool" }, - "auto_import_templates": { - "$ref": "#/definitions/codersdk.DeploymentConfigField-array_string" - }, "autobuild_poll_interval": { "$ref": "#/definitions/codersdk.DeploymentConfigField-time_Duration" }, diff --git a/coderd/coderd.go b/coderd/coderd.go index 673ba22fb0fc8..1579b50a88f81 100644 --- a/coderd/coderd.go +++ b/coderd/coderd.go @@ -97,7 +97,6 @@ type Options struct { SSHKeygenAlgorithm gitsshkey.Algorithm Telemetry telemetry.Reporter TracerProvider trace.TracerProvider - AutoImportTemplates []AutoImportTemplate GitAuthConfigs []*gitauth.Config RealIPConfig *httpmw.RealIPConfig TrialGenerator func(ctx context.Context, email string) error diff --git a/coderd/coderdtest/coderdtest.go b/coderd/coderdtest/coderdtest.go index 34b44ab883dad..7d357020c2273 100644 --- a/coderd/coderdtest/coderdtest.go +++ b/coderd/coderdtest/coderdtest.go @@ -93,7 +93,6 @@ type Options struct { GoogleTokenValidator *idtoken.Validator SSHKeygenAlgorithm gitsshkey.Algorithm APIRateLimit int - AutoImportTemplates []coderd.AutoImportTemplate AutobuildTicker <-chan time.Time AutobuildStats chan<- executor.Stats Auditor audit.Auditor @@ -294,7 +293,6 @@ func NewOptions(t *testing.T, options *Options) (func(http.Handler), context.Can }, }, }, - AutoImportTemplates: options.AutoImportTemplates, MetricsCacheRefreshInterval: options.MetricsCacheRefreshInterval, AgentStatsRefreshInterval: options.AgentStatsRefreshInterval, DeploymentConfig: options.DeploymentConfig, diff --git a/coderd/templates.go b/coderd/templates.go index 662a3069683c7..9b089b007552b 100644 --- a/coderd/templates.go +++ b/coderd/templates.go @@ -2,9 +2,7 @@ package coderd import ( "context" - "crypto/sha256" "database/sql" - "encoding/hex" "errors" "fmt" "net/http" @@ -13,7 +11,6 @@ import ( "github.com/go-chi/chi/v5" "github.com/google/uuid" - "github.com/moby/moby/pkg/namesgenerator" "golang.org/x/xerrors" "github.com/coder/coder/coderd/audit" @@ -26,14 +23,6 @@ import ( "github.com/coder/coder/examples" ) -// Auto-importable templates. These can be auto-imported after the first user -// has been created. -type AutoImportTemplate string - -const ( - AutoImportTemplateKubernetes AutoImportTemplate = "kubernetes" -) - // @Summary Get template metadata by ID // @ID get-template-metadata-by-id // @Security CoderSessionToken @@ -640,147 +629,6 @@ func (api *API) templateExamples(rw http.ResponseWriter, r *http.Request) { httpapi.Write(ctx, rw, http.StatusOK, ex) } -type autoImportTemplateOpts struct { - name string - archive []byte - params map[string]string - userID uuid.UUID - orgID uuid.UUID -} - -func (api *API) autoImportTemplate(ctx context.Context, opts autoImportTemplateOpts) (database.Template, error) { - var template database.Template - err := api.Database.InTx(func(tx database.Store) error { - // Insert the archive into the files table. - var ( - hash = sha256.Sum256(opts.archive) - now = database.Now() - ) - file, err := tx.InsertFile(ctx, database.InsertFileParams{ - ID: uuid.New(), - Hash: hex.EncodeToString(hash[:]), - CreatedAt: now, - CreatedBy: opts.userID, - Mimetype: "application/x-tar", - Data: opts.archive, - }) - if err != nil { - return xerrors.Errorf("insert auto-imported template archive into files table: %w", err) - } - - jobID := uuid.New() - - // Insert parameters - for key, value := range opts.params { - _, err = tx.InsertParameterValue(ctx, database.InsertParameterValueParams{ - ID: uuid.New(), - Name: key, - CreatedAt: now, - UpdatedAt: now, - Scope: database.ParameterScopeImportJob, - ScopeID: jobID, - SourceScheme: database.ParameterSourceSchemeData, - SourceValue: value, - DestinationScheme: database.ParameterDestinationSchemeProvisionerVariable, - }) - if err != nil { - return xerrors.Errorf("insert job-scoped parameter %q with value %q: %w", key, value, err) - } - } - - // Create provisioner job - job, err := tx.InsertProvisionerJob(ctx, database.InsertProvisionerJobParams{ - ID: jobID, - CreatedAt: now, - UpdatedAt: now, - OrganizationID: opts.orgID, - InitiatorID: opts.userID, - Provisioner: database.ProvisionerTypeTerraform, - StorageMethod: database.ProvisionerStorageMethodFile, - FileID: file.ID, - Type: database.ProvisionerJobTypeTemplateVersionImport, - Input: []byte{'{', '}'}, - }) - if err != nil { - return xerrors.Errorf("insert provisioner job: %w", err) - } - - // Create template version - templateVersion, err := tx.InsertTemplateVersion(ctx, database.InsertTemplateVersionParams{ - ID: uuid.New(), - TemplateID: uuid.NullUUID{ - UUID: uuid.Nil, - Valid: false, - }, - OrganizationID: opts.orgID, - CreatedAt: now, - UpdatedAt: now, - Name: namesgenerator.GetRandomName(1), - Readme: "", - JobID: job.ID, - CreatedBy: opts.userID, - }) - if err != nil { - return xerrors.Errorf("insert template version: %w", err) - } - - // Create template - template, err = tx.InsertTemplate(ctx, database.InsertTemplateParams{ - ID: uuid.New(), - CreatedAt: now, - UpdatedAt: now, - OrganizationID: opts.orgID, - Name: opts.name, - Provisioner: job.Provisioner, - ActiveVersionID: templateVersion.ID, - Description: "This template was auto-imported by Coder.", - DefaultTTL: 0, - CreatedBy: opts.userID, - UserACL: database.TemplateACL{}, - GroupACL: database.TemplateACL{ - opts.orgID.String(): []rbac.Action{rbac.ActionRead}, - }, - }) - if err != nil { - return xerrors.Errorf("insert template: %w", err) - } - - // Update template version with template ID - err = tx.UpdateTemplateVersionByID(ctx, database.UpdateTemplateVersionByIDParams{ - ID: templateVersion.ID, - TemplateID: uuid.NullUUID{ - UUID: template.ID, - Valid: true, - }, - }) - if err != nil { - return xerrors.Errorf("update template version to set template ID: %s", err) - } - - // Insert parameters at the template scope - for key, value := range opts.params { - _, err = tx.InsertParameterValue(ctx, database.InsertParameterValueParams{ - ID: uuid.New(), - Name: key, - CreatedAt: now, - UpdatedAt: now, - Scope: database.ParameterScopeTemplate, - ScopeID: template.ID, - SourceScheme: database.ParameterSourceSchemeData, - SourceValue: value, - DestinationScheme: database.ParameterDestinationSchemeProvisionerVariable, - }) - if err != nil { - return xerrors.Errorf("insert template-scoped parameter %q with value %q: %w", key, value, err) - } - } - - return nil - }, nil) - - return template, err -} - func getCreatedByNamesByTemplateIDs(ctx context.Context, db database.Store, templates []database.Template) (map[string]string, error) { creators := make(map[string]string, len(templates)) for _, template := range templates { diff --git a/coderd/users.go b/coderd/users.go index ea47cd66d4553..e1300d17c6302 100644 --- a/coderd/users.go +++ b/coderd/users.go @@ -1,14 +1,12 @@ package coderd import ( - "bytes" "context" "database/sql" "errors" "fmt" "net/http" "net/url" - "os" "strings" "github.com/go-chi/chi/v5" @@ -27,7 +25,6 @@ import ( "github.com/coder/coder/coderd/userpassword" "github.com/coder/coder/coderd/util/slice" "github.com/coder/coder/codersdk" - "github.com/coder/coder/examples" ) // Returns whether the initial user has been created or not. @@ -132,60 +129,6 @@ func (api *API) postFirstUser(rw http.ResponseWriter, r *http.Request) { return } - // Auto-import any designated templates into the new organization. - for _, template := range api.AutoImportTemplates { - archive, err := examples.Archive(string(template)) - if err != nil { - httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ - Message: "Internal error importing template.", - Detail: xerrors.Errorf("load template archive for %q: %w", template, err).Error(), - }) - return - } - - // Determine which parameter values to use. - parameters := map[string]string{} - switch template { - case AutoImportTemplateKubernetes: - - // Determine the current namespace we're in. - const namespaceFile = "/var/run/secrets/kubernetes.io/serviceaccount/namespace" - namespace, err := os.ReadFile(namespaceFile) - if err != nil { - parameters["use_kubeconfig"] = "true" // use ~/.config/kubeconfig - parameters["namespace"] = "coder-workspaces" - } else { - parameters["use_kubeconfig"] = "false" // use SA auth - parameters["namespace"] = string(bytes.TrimSpace(namespace)) - } - - default: - httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ - Message: "Internal error importing template.", - Detail: fmt.Sprintf("cannot auto-import %q template", template), - }) - return - } - - tpl, err := api.autoImportTemplate(ctx, autoImportTemplateOpts{ - name: string(template), - archive: archive, - params: parameters, - userID: user.ID, - orgID: organizationID, - }) - if err != nil { - api.Logger.Warn(ctx, "failed to auto-import template", slog.F("template", template), slog.F("parameters", parameters), slog.Error(err)) - httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ - Message: "Internal error importing template.", - Detail: xerrors.Errorf("failed to import template %q: %w", template, err).Error(), - }) - return - } - - api.Logger.Info(ctx, "auto-imported template", slog.F("id", tpl.ID), slog.F("template", template), slog.F("parameters", parameters)) - } - httpapi.Write(ctx, rw, http.StatusCreated, codersdk.CreateFirstUserResponse{ UserID: user.ID, OrganizationID: organizationID, diff --git a/coderd/users_test.go b/coderd/users_test.go index 56b891b3301e0..b80ae78797ce4 100644 --- a/coderd/users_test.go +++ b/coderd/users_test.go @@ -14,7 +14,6 @@ import ( "github.com/stretchr/testify/require" "golang.org/x/sync/errgroup" - "github.com/coder/coder/coderd" "github.com/coder/coder/coderd/audit" "github.com/coder/coder/coderd/coderdtest" "github.com/coder/coder/coderd/database" @@ -116,77 +115,6 @@ func TestFirstUser(t *testing.T) { } } }) - - t.Run("AutoImportsTemplates", func(t *testing.T) { - t.Parallel() - - // All available auto import templates should be added to this list, and - // also added to the switch statement below. - autoImportTemplates := []coderd.AutoImportTemplate{ - coderd.AutoImportTemplateKubernetes, - } - client := coderdtest.New(t, &coderdtest.Options{ - AutoImportTemplates: autoImportTemplates, - }) - u := coderdtest.CreateFirstUser(t, client) - - ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong) - defer cancel() - - templates, err := client.TemplatesByOrganization(ctx, u.OrganizationID) - require.NoError(t, err, "list templates") - require.Len(t, templates, len(autoImportTemplates), "listed templates count does not match") - require.ElementsMatch(t, autoImportTemplates, []coderd.AutoImportTemplate{ - coderd.AutoImportTemplate(templates[0].Name), - }, "template names don't match") - - for _, template := range templates { - // Check template parameters. - templateParams, err := client.Parameters(ctx, codersdk.ParameterTemplate, template.ID) - require.NoErrorf(t, err, "get template parameters for %q", template.Name) - - // Ensure all template parameters are present. - expectedParams := map[string]bool{} - switch template.Name { - case "kubernetes": - expectedParams["use_kubeconfig"] = false - expectedParams["namespace"] = false - default: - t.Fatalf("unexpected template name %q", template.Name) - } - for _, v := range templateParams { - if _, ok := expectedParams[v.Name]; !ok { - t.Fatalf("unexpected template parameter %q in template %q", v.Name, template.Name) - } - expectedParams[v.Name] = true - } - for k, v := range expectedParams { - if !v { - t.Fatalf("missing template parameter %q in template %q", k, template.Name) - } - } - - // Ensure template version is legit - templateVersion, err := client.TemplateVersion(ctx, template.ActiveVersionID) - require.NoErrorf(t, err, "get template version for %q", template.Name) - - // Compare job parameters to template parameters. - jobParams, err := client.Parameters(ctx, codersdk.ParameterImportJob, templateVersion.Job.ID) - require.NoErrorf(t, err, "get template import job parameters for %q", template.Name) - for _, v := range jobParams { - if _, ok := expectedParams[v.Name]; !ok { - t.Fatalf("unexpected job parameter %q for template %q", v.Name, template.Name) - } - // Change it back to false so we can reuse the map - expectedParams[v.Name] = false - } - for k, v := range expectedParams { - if v { - t.Fatalf("missing job parameter %q for template %q", k, template.Name) - } - } - } - }) } func TestPostLogin(t *testing.T) { diff --git a/codersdk/deploymentconfig.go b/codersdk/deploymentconfig.go index 8d12426292241..c048e01f78925 100644 --- a/codersdk/deploymentconfig.go +++ b/codersdk/deploymentconfig.go @@ -33,7 +33,6 @@ type DeploymentConfig struct { Trace *TraceConfig `json:"trace" typescript:",notnull"` SecureAuthCookie *DeploymentConfigField[bool] `json:"secure_auth_cookie" typescript:",notnull"` SSHKeygenAlgorithm *DeploymentConfigField[string] `json:"ssh_keygen_algorithm" typescript:",notnull"` - AutoImportTemplates *DeploymentConfigField[[]string] `json:"auto_import_templates" typescript:",notnull"` MetricsCacheRefreshInterval *DeploymentConfigField[time.Duration] `json:"metrics_cache_refresh_interval" typescript:",notnull"` AgentStatRefreshInterval *DeploymentConfigField[time.Duration] `json:"agent_stat_refresh_interval" typescript:",notnull"` AgentFallbackTroubleshootingURL *DeploymentConfigField[string] `json:"agent_fallback_troubleshooting_url" typescript:",notnull"` diff --git a/docs/api/general.md b/docs/api/general.md index d9355f7f1c505..3b307f8c33b3d 100644 --- a/docs/api/general.md +++ b/docs/api/general.md @@ -151,17 +151,6 @@ curl -X GET http://coder-server:8080/api/v2/config/deployment \ "usage": "string", "value": true }, - "auto_import_templates": { - "default": ["string"], - "enterprise": true, - "flag": "string", - "hidden": true, - "name": "string", - "secret": true, - "shorthand": "string", - "usage": "string", - "value": "string" - }, "autobuild_poll_interval": { "default": 0, "enterprise": true, diff --git a/docs/api/schemas.md b/docs/api/schemas.md index 478403c1fc166..7c84208f242ab 100644 --- a/docs/api/schemas.md +++ b/docs/api/schemas.md @@ -735,17 +735,6 @@ CreateParameterRequest is a structure used to create a new parameter value for a "usage": "string", "value": true }, - "auto_import_templates": { - "default": ["string"], - "enterprise": true, - "flag": "string", - "hidden": true, - "name": "string", - "secret": true, - "shorthand": "string", - "usage": "string", - "value": "string" - }, "autobuild_poll_interval": { "default": 0, "enterprise": true, @@ -1522,7 +1511,6 @@ CreateParameterRequest is a structure used to create a new parameter value for a | `agent_stat_refresh_interval` | [codersdk.DeploymentConfigField-time_Duration](#codersdkdeploymentconfigfield-time_duration) | false | | | | `api_rate_limit` | [codersdk.DeploymentConfigField-int](#codersdkdeploymentconfigfield-int) | false | | | | `audit_logging` | [codersdk.DeploymentConfigField-bool](#codersdkdeploymentconfigfield-bool) | false | | | -| `auto_import_templates` | [codersdk.DeploymentConfigField-array_string](#codersdkdeploymentconfigfield-array_string) | false | | | | `autobuild_poll_interval` | [codersdk.DeploymentConfigField-time_Duration](#codersdkdeploymentconfigfield-time_duration) | false | | | | `browser_only` | [codersdk.DeploymentConfigField-bool](#codersdkdeploymentconfigfield-bool) | false | | | | `cache_directory` | [codersdk.DeploymentConfigField-string](#codersdkdeploymentconfigfield-string) | false | | | diff --git a/docs/install/kubernetes.md b/docs/install/kubernetes.md index b35ce69678f9f..456116699a039 100644 --- a/docs/install/kubernetes.md +++ b/docs/install/kubernetes.md @@ -101,12 +101,6 @@ to log in and manage templates. - name: CODER_ACCESS_URL value: "https://coder.example.com" - # This env variable controls whether or not to auto-import the - # "kubernetes" template on first startup. This will not work unless - # coder.serviceAccount.workspacePerms is true. - - name: CODER_AUTO_IMPORT_TEMPLATES - value: "kubernetes" - #tls: # secretNames: # - my-tls-secret-name diff --git a/helm/README.md b/helm/README.md index 53a0d994f0086..5fa85ec5c2347 100644 --- a/helm/README.md +++ b/helm/README.md @@ -44,12 +44,6 @@ coder: name: coder-db-url key: url - # This env variable controls whether or not to auto-import the "kubernetes" - # template on first startup. This will not work unless - # coder.serviceAccount.workspacePerms is true. - - name: CODER_AUTO_IMPORT_TEMPLATES - value: "kubernetes" - # This env enables the Prometheus metrics endpoint. - name: CODER_PROMETHEUS_ADDRESS value: "0.0.0.0:2112" diff --git a/site/src/api/typesGenerated.ts b/site/src/api/typesGenerated.ts index 635ba8cd97eee..fd847b07241f8 100644 --- a/site/src/api/typesGenerated.ts +++ b/site/src/api/typesGenerated.ts @@ -301,7 +301,6 @@ export interface DeploymentConfig { readonly trace: TraceConfig readonly secure_auth_cookie: DeploymentConfigField readonly ssh_keygen_algorithm: DeploymentConfigField - readonly auto_import_templates: DeploymentConfigField readonly metrics_cache_refresh_interval: DeploymentConfigField readonly agent_stat_refresh_interval: DeploymentConfigField readonly agent_fallback_troubleshooting_url: DeploymentConfigField