diff --git a/agent/agent.go b/agent/agent.go index 377dec7492..5c6bc40986 100644 --- a/agent/agent.go +++ b/agent/agent.go @@ -677,7 +677,7 @@ func (a *agent) fetchServiceBannerLoop(ctx context.Context, aAPI proto.DRPCAgent a.logger.Error(ctx, "failed to update service banner", slog.Error(err)) return err } - serviceBanner := proto.SDKServiceBannerFromProto(sbp) + serviceBanner := agentsdk.ServiceBannerFromProto(sbp) a.serviceBanner.Store(&serviceBanner) } } @@ -710,7 +710,7 @@ func (a *agent) run(ctx context.Context) error { if err != nil { return xerrors.Errorf("fetch service banner: %w", err) } - serviceBanner := proto.SDKServiceBannerFromProto(sbp) + serviceBanner := agentsdk.ServiceBannerFromProto(sbp) a.serviceBanner.Store(&serviceBanner) manifest, err := a.client.Manifest(ctx) diff --git a/agent/agenttest/client.go b/agent/agenttest/client.go index 2eaa11156c..e2278d5685 100644 --- a/agent/agenttest/client.go +++ b/agent/agenttest/client.go @@ -277,7 +277,7 @@ func (f *FakeAgentAPI) GetServiceBanner(context.Context, *agentproto.GetServiceB if err != nil { return nil, err } - return agentproto.ServiceBannerFromSDK(sb), nil + return agentsdk.ProtoFromServiceBanner(sb), nil } func (*FakeAgentAPI) UpdateStats(context.Context, *agentproto.UpdateStatsRequest) (*agentproto.UpdateStatsResponse, error) { diff --git a/agent/proto/convert.go b/agent/proto/convert.go deleted file mode 100644 index 67578caabe..0000000000 --- a/agent/proto/convert.go +++ /dev/null @@ -1,122 +0,0 @@ -package proto - -import ( - "strings" - - "github.com/google/uuid" - "golang.org/x/xerrors" - - "github.com/coder/coder/v2/codersdk" -) - -func SDKAgentMetadataDescriptionsFromProto(descriptions []*WorkspaceAgentMetadata_Description) []codersdk.WorkspaceAgentMetadataDescription { - ret := make([]codersdk.WorkspaceAgentMetadataDescription, len(descriptions)) - for i, description := range descriptions { - ret[i] = SDKAgentMetadataDescriptionFromProto(description) - } - return ret -} - -func SDKAgentMetadataDescriptionFromProto(description *WorkspaceAgentMetadata_Description) codersdk.WorkspaceAgentMetadataDescription { - return codersdk.WorkspaceAgentMetadataDescription{ - DisplayName: description.DisplayName, - Key: description.Key, - Script: description.Script, - Interval: int64(description.Interval.AsDuration()), - Timeout: int64(description.Timeout.AsDuration()), - } -} - -func SDKAgentScriptsFromProto(protoScripts []*WorkspaceAgentScript) ([]codersdk.WorkspaceAgentScript, error) { - ret := make([]codersdk.WorkspaceAgentScript, len(protoScripts)) - for i, protoScript := range protoScripts { - app, err := SDKAgentScriptFromProto(protoScript) - if err != nil { - return nil, xerrors.Errorf("parse script %v: %w", i, err) - } - ret[i] = app - } - return ret, nil -} - -func SDKAgentScriptFromProto(protoScript *WorkspaceAgentScript) (codersdk.WorkspaceAgentScript, error) { - id, err := uuid.FromBytes(protoScript.LogSourceId) - if err != nil { - return codersdk.WorkspaceAgentScript{}, xerrors.Errorf("parse id: %w", err) - } - - return codersdk.WorkspaceAgentScript{ - LogSourceID: id, - LogPath: protoScript.LogPath, - Script: protoScript.Script, - Cron: protoScript.Cron, - RunOnStart: protoScript.RunOnStart, - RunOnStop: protoScript.RunOnStop, - StartBlocksLogin: protoScript.StartBlocksLogin, - Timeout: protoScript.Timeout.AsDuration(), - }, nil -} - -func SDKAppsFromProto(protoApps []*WorkspaceApp) ([]codersdk.WorkspaceApp, error) { - ret := make([]codersdk.WorkspaceApp, len(protoApps)) - for i, protoApp := range protoApps { - app, err := SDKAppFromProto(protoApp) - if err != nil { - return nil, xerrors.Errorf("parse app %v (%q): %w", i, protoApp.Slug, err) - } - ret[i] = app - } - return ret, nil -} - -func SDKAppFromProto(protoApp *WorkspaceApp) (codersdk.WorkspaceApp, error) { - id, err := uuid.FromBytes(protoApp.Id) - if err != nil { - return codersdk.WorkspaceApp{}, xerrors.Errorf("parse id: %w", err) - } - - var sharingLevel codersdk.WorkspaceAppSharingLevel = codersdk.WorkspaceAppSharingLevel(strings.ToLower(protoApp.SharingLevel.String())) - if _, ok := codersdk.MapWorkspaceAppSharingLevels[sharingLevel]; !ok { - return codersdk.WorkspaceApp{}, xerrors.Errorf("unknown app sharing level: %v (%q)", protoApp.SharingLevel, protoApp.SharingLevel.String()) - } - - var health codersdk.WorkspaceAppHealth = codersdk.WorkspaceAppHealth(strings.ToLower(protoApp.Health.String())) - if _, ok := codersdk.MapWorkspaceAppHealths[health]; !ok { - return codersdk.WorkspaceApp{}, xerrors.Errorf("unknown app health: %v (%q)", protoApp.Health, protoApp.Health.String()) - } - - return codersdk.WorkspaceApp{ - ID: id, - URL: protoApp.Url, - External: protoApp.External, - Slug: protoApp.Slug, - DisplayName: protoApp.DisplayName, - Command: protoApp.Command, - Icon: protoApp.Icon, - Subdomain: protoApp.Subdomain, - SubdomainName: protoApp.SubdomainName, - SharingLevel: sharingLevel, - Healthcheck: codersdk.Healthcheck{ - URL: protoApp.Healthcheck.Url, - Interval: int32(protoApp.Healthcheck.Interval.AsDuration().Seconds()), - Threshold: protoApp.Healthcheck.Threshold, - }, - Health: health, - }, nil -} - -func SDKServiceBannerFromProto(sbp *ServiceBanner) codersdk.ServiceBannerConfig { - return codersdk.ServiceBannerConfig{ - Enabled: sbp.GetEnabled(), - Message: sbp.GetMessage(), - BackgroundColor: sbp.GetBackgroundColor(), - } -} - -func ServiceBannerFromSDK(sb codersdk.ServiceBannerConfig) *ServiceBanner { - return &ServiceBanner{ - Enabled: sb.Enabled, - Message: sb.Message, - BackgroundColor: sb.BackgroundColor, - } -} diff --git a/coderd/agentapi/servicebanner.go b/coderd/agentapi/servicebanner.go index a4bc1f457d..2e835003c7 100644 --- a/coderd/agentapi/servicebanner.go +++ b/coderd/agentapi/servicebanner.go @@ -8,6 +8,7 @@ import ( "github.com/coder/coder/v2/agent/proto" "github.com/coder/coder/v2/coderd/appearance" + "github.com/coder/coder/v2/codersdk/agentsdk" ) type ServiceBannerAPI struct { @@ -19,5 +20,5 @@ func (a *ServiceBannerAPI) GetServiceBanner(ctx context.Context, _ *proto.GetSer if err != nil { return nil, xerrors.Errorf("fetch appearance: %w", err) } - return proto.ServiceBannerFromSDK(cfg.ServiceBanner), nil + return agentsdk.ProtoFromServiceBanner(cfg.ServiceBanner), nil } diff --git a/coderd/workspaceagents.go b/coderd/workspaceagents.go index dca1a02489..29c15056b4 100644 --- a/coderd/workspaceagents.go +++ b/coderd/workspaceagents.go @@ -179,60 +179,16 @@ func (api *API) workspaceAgentManifest(rw http.ResponseWriter, r *http.Request) }) return } - - apps, err := agentproto.SDKAppsFromProto(manifest.Apps) + sdkManifest, err := agentsdk.ManifestFromProto(manifest) if err != nil { httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ - Message: "Internal error converting workspace agent apps.", + Message: "Internal error converting manifest.", Detail: err.Error(), }) return } - scripts, err := agentproto.SDKAgentScriptsFromProto(manifest.Scripts) - if err != nil { - httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ - Message: "Internal error converting workspace agent scripts.", - Detail: err.Error(), - }) - return - } - - agentID, err := uuid.FromBytes(manifest.AgentId) - if err != nil { - httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ - Message: "Internal error converting workspace agent ID.", - Detail: err.Error(), - }) - return - } - workspaceID, err := uuid.FromBytes(manifest.WorkspaceId) - if err != nil { - httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ - Message: "Internal error converting workspace ID.", - Detail: err.Error(), - }) - return - } - - httpapi.Write(ctx, rw, http.StatusOK, agentsdk.Manifest{ - AgentID: agentID, - AgentName: manifest.AgentName, - OwnerName: manifest.OwnerUsername, - WorkspaceID: workspaceID, - WorkspaceName: manifest.WorkspaceName, - Apps: apps, - Scripts: scripts, - DERPMap: tailnet.DERPMapFromProto(manifest.DerpMap), - DERPForceWebSockets: manifest.DerpForceWebsockets, - GitAuthConfigs: int(manifest.GitAuthConfigs), - EnvironmentVariables: manifest.EnvironmentVariables, - Directory: manifest.Directory, - VSCodePortProxyURI: manifest.VsCodePortProxyUri, - MOTDFile: manifest.MotdPath, - DisableDirectConnections: manifest.DisableDirectConnections, - Metadata: agentproto.SDKAgentMetadataDescriptionsFromProto(manifest.Metadata), - }) + httpapi.Write(ctx, rw, http.StatusOK, sdkManifest) } const AgentAPIVersionREST = "1.0" diff --git a/codersdk/agentsdk/convert.go b/codersdk/agentsdk/convert.go new file mode 100644 index 0000000000..2a20cf5d0c --- /dev/null +++ b/codersdk/agentsdk/convert.go @@ -0,0 +1,268 @@ +package agentsdk + +import ( + "strings" + "time" + + "github.com/google/uuid" + "golang.org/x/xerrors" + "google.golang.org/protobuf/types/known/durationpb" + + "github.com/coder/coder/v2/agent/proto" + "github.com/coder/coder/v2/codersdk" + "github.com/coder/coder/v2/tailnet" +) + +func ManifestFromProto(manifest *proto.Manifest) (Manifest, error) { + apps, err := AppsFromProto(manifest.Apps) + if err != nil { + return Manifest{}, xerrors.Errorf("error converting workspace agent apps: %w", err) + } + scripts, err := AgentScriptsFromProto(manifest.Scripts) + if err != nil { + return Manifest{}, xerrors.Errorf("error converting workspace agent scripts: %w", err) + } + agentID, err := uuid.FromBytes(manifest.AgentId) + if err != nil { + return Manifest{}, xerrors.Errorf("error converting workspace agent ID: %w", err) + } + workspaceID, err := uuid.FromBytes(manifest.WorkspaceId) + if err != nil { + return Manifest{}, xerrors.Errorf("error converting workspace ID: %w", err) + } + return Manifest{ + AgentID: agentID, + AgentName: manifest.AgentName, + OwnerName: manifest.OwnerUsername, + WorkspaceID: workspaceID, + WorkspaceName: manifest.WorkspaceName, + Apps: apps, + Scripts: scripts, + DERPMap: tailnet.DERPMapFromProto(manifest.DerpMap), + DERPForceWebSockets: manifest.DerpForceWebsockets, + GitAuthConfigs: int(manifest.GitAuthConfigs), + EnvironmentVariables: manifest.EnvironmentVariables, + Directory: manifest.Directory, + VSCodePortProxyURI: manifest.VsCodePortProxyUri, + MOTDFile: manifest.MotdPath, + DisableDirectConnections: manifest.DisableDirectConnections, + Metadata: MetadataDescriptionsFromProto(manifest.Metadata), + }, nil +} + +func ProtoFromManifest(manifest Manifest) (*proto.Manifest, error) { + apps, err := ProtoFromApps(manifest.Apps) + if err != nil { + return nil, xerrors.Errorf("convert workspace apps: %w", err) + } + return &proto.Manifest{ + AgentId: manifest.AgentID[:], + AgentName: manifest.AgentName, + OwnerUsername: manifest.OwnerName, + WorkspaceId: manifest.WorkspaceID[:], + WorkspaceName: manifest.WorkspaceName, + GitAuthConfigs: uint32(manifest.GitAuthConfigs), + EnvironmentVariables: manifest.EnvironmentVariables, + Directory: manifest.Directory, + VsCodePortProxyUri: manifest.VSCodePortProxyURI, + MotdPath: manifest.MOTDFile, + DisableDirectConnections: manifest.DisableDirectConnections, + DerpForceWebsockets: manifest.DERPForceWebSockets, + DerpMap: tailnet.DERPMapToProto(manifest.DERPMap), + Scripts: ProtoFromScripts(manifest.Scripts), + Apps: apps, + Metadata: ProtoFromMetadataDescriptions(manifest.Metadata), + }, nil +} + +func MetadataDescriptionsFromProto(descriptions []*proto.WorkspaceAgentMetadata_Description) []codersdk.WorkspaceAgentMetadataDescription { + ret := make([]codersdk.WorkspaceAgentMetadataDescription, len(descriptions)) + for i, description := range descriptions { + ret[i] = MetadataDescriptionFromProto(description) + } + return ret +} + +func ProtoFromMetadataDescriptions(descriptions []codersdk.WorkspaceAgentMetadataDescription) []*proto.WorkspaceAgentMetadata_Description { + ret := make([]*proto.WorkspaceAgentMetadata_Description, len(descriptions)) + for i, d := range descriptions { + ret[i] = ProtoFromMetadataDescription(d) + } + return ret +} + +func MetadataDescriptionFromProto(description *proto.WorkspaceAgentMetadata_Description) codersdk.WorkspaceAgentMetadataDescription { + return codersdk.WorkspaceAgentMetadataDescription{ + DisplayName: description.DisplayName, + Key: description.Key, + Script: description.Script, + Interval: int64(description.Interval.AsDuration()), + Timeout: int64(description.Timeout.AsDuration()), + } +} + +func ProtoFromMetadataDescription(d codersdk.WorkspaceAgentMetadataDescription) *proto.WorkspaceAgentMetadata_Description { + return &proto.WorkspaceAgentMetadata_Description{ + DisplayName: d.DisplayName, + Key: d.Key, + Script: d.Script, + Interval: durationpb.New(time.Duration(d.Interval)), + Timeout: durationpb.New(time.Duration(d.Timeout)), + } +} + +func AgentScriptsFromProto(protoScripts []*proto.WorkspaceAgentScript) ([]codersdk.WorkspaceAgentScript, error) { + ret := make([]codersdk.WorkspaceAgentScript, len(protoScripts)) + for i, protoScript := range protoScripts { + app, err := AgentScriptFromProto(protoScript) + if err != nil { + return nil, xerrors.Errorf("parse script %v: %w", i, err) + } + ret[i] = app + } + return ret, nil +} + +func ProtoFromScripts(scripts []codersdk.WorkspaceAgentScript) []*proto.WorkspaceAgentScript { + ret := make([]*proto.WorkspaceAgentScript, len(scripts)) + for i, script := range scripts { + ret[i] = ProtoFromScript(script) + } + return ret +} + +func AgentScriptFromProto(protoScript *proto.WorkspaceAgentScript) (codersdk.WorkspaceAgentScript, error) { + id, err := uuid.FromBytes(protoScript.LogSourceId) + if err != nil { + return codersdk.WorkspaceAgentScript{}, xerrors.Errorf("parse id: %w", err) + } + + return codersdk.WorkspaceAgentScript{ + LogSourceID: id, + LogPath: protoScript.LogPath, + Script: protoScript.Script, + Cron: protoScript.Cron, + RunOnStart: protoScript.RunOnStart, + RunOnStop: protoScript.RunOnStop, + StartBlocksLogin: protoScript.StartBlocksLogin, + Timeout: protoScript.Timeout.AsDuration(), + }, nil +} + +func ProtoFromScript(s codersdk.WorkspaceAgentScript) *proto.WorkspaceAgentScript { + return &proto.WorkspaceAgentScript{ + LogSourceId: s.LogSourceID[:], + LogPath: s.LogPath, + Script: s.Script, + Cron: s.Cron, + RunOnStart: s.RunOnStart, + RunOnStop: s.RunOnStop, + StartBlocksLogin: s.StartBlocksLogin, + Timeout: durationpb.New(s.Timeout), + } +} + +func AppsFromProto(protoApps []*proto.WorkspaceApp) ([]codersdk.WorkspaceApp, error) { + ret := make([]codersdk.WorkspaceApp, len(protoApps)) + for i, protoApp := range protoApps { + app, err := AppFromProto(protoApp) + if err != nil { + return nil, xerrors.Errorf("parse app %v (%q): %w", i, protoApp.Slug, err) + } + ret[i] = app + } + return ret, nil +} + +func ProtoFromApps(apps []codersdk.WorkspaceApp) ([]*proto.WorkspaceApp, error) { + ret := make([]*proto.WorkspaceApp, len(apps)) + var err error + for i, a := range apps { + ret[i], err = ProtoFromApp(a) + if err != nil { + return nil, err + } + } + return ret, nil +} + +func AppFromProto(protoApp *proto.WorkspaceApp) (codersdk.WorkspaceApp, error) { + id, err := uuid.FromBytes(protoApp.Id) + if err != nil { + return codersdk.WorkspaceApp{}, xerrors.Errorf("parse id: %w", err) + } + + sharingLevel := codersdk.WorkspaceAppSharingLevel(strings.ToLower(protoApp.SharingLevel.String())) + if _, ok := codersdk.MapWorkspaceAppSharingLevels[sharingLevel]; !ok { + return codersdk.WorkspaceApp{}, xerrors.Errorf("unknown app sharing level: %v (%q)", protoApp.SharingLevel, protoApp.SharingLevel.String()) + } + + health := codersdk.WorkspaceAppHealth(strings.ToLower(protoApp.Health.String())) + if _, ok := codersdk.MapWorkspaceAppHealths[health]; !ok { + return codersdk.WorkspaceApp{}, xerrors.Errorf("unknown app health: %v (%q)", protoApp.Health, protoApp.Health.String()) + } + + return codersdk.WorkspaceApp{ + ID: id, + URL: protoApp.Url, + External: protoApp.External, + Slug: protoApp.Slug, + DisplayName: protoApp.DisplayName, + Command: protoApp.Command, + Icon: protoApp.Icon, + Subdomain: protoApp.Subdomain, + SubdomainName: protoApp.SubdomainName, + SharingLevel: sharingLevel, + Healthcheck: codersdk.Healthcheck{ + URL: protoApp.Healthcheck.Url, + Interval: int32(protoApp.Healthcheck.Interval.AsDuration().Seconds()), + Threshold: protoApp.Healthcheck.Threshold, + }, + Health: health, + }, nil +} + +func ProtoFromApp(a codersdk.WorkspaceApp) (*proto.WorkspaceApp, error) { + sharingLevel, ok := proto.WorkspaceApp_SharingLevel_value[strings.ToUpper(string(a.SharingLevel))] + if !ok { + return nil, xerrors.Errorf("unknown sharing level %s", a.SharingLevel) + } + health, ok := proto.WorkspaceApp_Health_value[strings.ToUpper(string(a.Health))] + if !ok { + return nil, xerrors.Errorf("unknown health %s", a.Health) + } + return &proto.WorkspaceApp{ + Id: a.ID[:], + Url: a.URL, + External: a.External, + Slug: a.Slug, + DisplayName: a.DisplayName, + Command: a.Command, + Icon: a.Icon, + Subdomain: a.Subdomain, + SubdomainName: a.SubdomainName, + SharingLevel: proto.WorkspaceApp_SharingLevel(sharingLevel), + Healthcheck: &proto.WorkspaceApp_Healthcheck{ + Url: a.Healthcheck.URL, + Interval: durationpb.New(time.Duration(a.Healthcheck.Interval) * time.Second), + Threshold: a.Healthcheck.Threshold, + }, + Health: proto.WorkspaceApp_Health(health), + }, nil +} + +func ServiceBannerFromProto(sbp *proto.ServiceBanner) codersdk.ServiceBannerConfig { + return codersdk.ServiceBannerConfig{ + Enabled: sbp.GetEnabled(), + Message: sbp.GetMessage(), + BackgroundColor: sbp.GetBackgroundColor(), + } +} + +func ProtoFromServiceBanner(sb codersdk.ServiceBannerConfig) *proto.ServiceBanner { + return &proto.ServiceBanner{ + Enabled: sb.Enabled, + Message: sb.Message, + BackgroundColor: sb.BackgroundColor, + } +} diff --git a/codersdk/agentsdk/convert_test.go b/codersdk/agentsdk/convert_test.go new file mode 100644 index 0000000000..9205777e13 --- /dev/null +++ b/codersdk/agentsdk/convert_test.go @@ -0,0 +1,146 @@ +package agentsdk_test + +import ( + "testing" + "time" + + "github.com/google/uuid" + "github.com/stretchr/testify/require" + "tailscale.com/tailcfg" + + "github.com/coder/coder/v2/codersdk" + "github.com/coder/coder/v2/codersdk/agentsdk" + "github.com/coder/coder/v2/tailnet" +) + +func TestManifest(t *testing.T) { + t.Parallel() + manifest := agentsdk.Manifest{ + AgentID: uuid.New(), + AgentName: "test-agent", + OwnerName: "test-owner", + WorkspaceID: uuid.New(), + WorkspaceName: "test-workspace", + GitAuthConfigs: 3, + VSCodePortProxyURI: "http://proxy.example.com/stuff", + Apps: []codersdk.WorkspaceApp{ + { + ID: uuid.New(), + URL: "http://app1.example.com", + External: true, + Slug: "app1", + DisplayName: "App 1", + Command: "app1 -d", + Icon: "app1.png", + Subdomain: true, + SubdomainName: "app1.example.com", + SharingLevel: codersdk.WorkspaceAppSharingLevelAuthenticated, + Healthcheck: codersdk.Healthcheck{ + URL: "http://localhost:3030/healthz", + Interval: 55555666, + Threshold: 55555666, + }, + Health: codersdk.WorkspaceAppHealthHealthy, + }, + { + ID: uuid.New(), + URL: "http://app2.example.com", + External: false, + Slug: "app2", + DisplayName: "App 2", + Command: "app2 -d", + Icon: "app2.png", + Subdomain: false, + SubdomainName: "app2.example.com", + SharingLevel: codersdk.WorkspaceAppSharingLevelPublic, + Healthcheck: codersdk.Healthcheck{ + URL: "http://localhost:3032/healthz", + Interval: 22555666, + Threshold: 22555666, + }, + Health: codersdk.WorkspaceAppHealthInitializing, + }, + }, + DERPMap: &tailcfg.DERPMap{ + HomeParams: &tailcfg.DERPHomeParams{RegionScore: map[int]float64{999: 0.025}}, + Regions: map[int]*tailcfg.DERPRegion{ + 999: { + EmbeddedRelay: true, + RegionID: 999, + RegionCode: "default", + RegionName: "HOME", + Avoid: false, + Nodes: []*tailcfg.DERPNode{ + { + Name: "Home1", + }, + }, + }, + }, + }, + DERPForceWebSockets: true, + EnvironmentVariables: map[string]string{"FOO": "bar"}, + Directory: "/home/coder", + MOTDFile: "/etc/motd", + DisableDirectConnections: true, + Metadata: []codersdk.WorkspaceAgentMetadataDescription{ + { + DisplayName: "CPU", + Key: "cpu", + Script: "getcpu", + Interval: 44444422, + Timeout: 44444411, + }, + { + DisplayName: "MEM", + Key: "mem", + Script: "getmem", + Interval: 54444422, + Timeout: 54444411, + }, + }, + Scripts: []codersdk.WorkspaceAgentScript{ + { + LogSourceID: uuid.New(), + LogPath: "/var/log/script.log", + Script: "script", + Cron: "somecron", + RunOnStart: true, + RunOnStop: true, + StartBlocksLogin: true, + Timeout: time.Second, + }, + { + LogSourceID: uuid.New(), + LogPath: "/var/log/script2.log", + Script: "script2", + Cron: "somecron2", + RunOnStart: false, + RunOnStop: true, + StartBlocksLogin: true, + Timeout: time.Second * 4, + }, + }, + } + p, err := agentsdk.ProtoFromManifest(manifest) + require.NoError(t, err) + back, err := agentsdk.ManifestFromProto(p) + require.NoError(t, err) + require.Equal(t, manifest.AgentID, back.AgentID) + require.Equal(t, manifest.AgentName, back.AgentName) + require.Equal(t, manifest.OwnerName, back.OwnerName) + require.Equal(t, manifest.WorkspaceID, back.WorkspaceID) + require.Equal(t, manifest.WorkspaceName, back.WorkspaceName) + require.Equal(t, manifest.GitAuthConfigs, back.GitAuthConfigs) + require.Equal(t, manifest.VSCodePortProxyURI, back.VSCodePortProxyURI) + require.Equal(t, manifest.Apps, back.Apps) + require.NotNil(t, back.DERPMap) + require.True(t, tailnet.CompareDERPMaps(manifest.DERPMap, back.DERPMap)) + require.Equal(t, manifest.DERPForceWebSockets, back.DERPForceWebSockets) + require.Equal(t, manifest.EnvironmentVariables, back.EnvironmentVariables) + require.Equal(t, manifest.Directory, back.Directory) + require.Equal(t, manifest.MOTDFile, back.MOTDFile) + require.Equal(t, manifest.DisableDirectConnections, back.DisableDirectConnections) + require.Equal(t, manifest.Metadata, back.Metadata) + require.Equal(t, manifest.Scripts, back.Scripts) +} diff --git a/enterprise/coderd/appearance_test.go b/enterprise/coderd/appearance_test.go index 9abdee599d..a200e2bfd7 100644 --- a/enterprise/coderd/appearance_test.go +++ b/enterprise/coderd/appearance_test.go @@ -184,7 +184,7 @@ func requireGetServiceBanner(ctx context.Context, t *testing.T, client *agentsdk aAPI := proto.NewDRPCAgentClient(cc) sbp, err := aAPI.GetServiceBanner(ctx, &proto.GetServiceBannerRequest{}) require.NoError(t, err) - return proto.SDKServiceBannerFromProto(sbp) + return agentsdk.ServiceBannerFromProto(sbp) } func TestCustomSupportLinks(t *testing.T) {