diff --git a/agent/agent.go b/agent/agent.go index ffdacfb64ba75..927612302bf71 100644 --- a/agent/agent.go +++ b/agent/agent.go @@ -95,8 +95,8 @@ type Options struct { } type Client interface { - ConnectRPC24(ctx context.Context) ( - proto.DRPCAgentClient24, tailnetproto.DRPCTailnetClient24, error, + ConnectRPC25(ctx context.Context) ( + proto.DRPCAgentClient25, tailnetproto.DRPCTailnetClient25, error, ) RewriteDERPMap(derpMap *tailcfg.DERPMap) } @@ -908,7 +908,7 @@ func (a *agent) run() (retErr error) { a.sessionToken.Store(&sessionToken) // ConnectRPC returns the dRPC connection we use for the Agent and Tailnet v2+ APIs - aAPI, tAPI, err := a.client.ConnectRPC24(a.hardCtx) + aAPI, tAPI, err := a.client.ConnectRPC25(a.hardCtx) if err != nil { return err } diff --git a/agent/agenttest/client.go b/agent/agenttest/client.go index 24658c44d6e18..05011971c7c50 100644 --- a/agent/agenttest/client.go +++ b/agent/agenttest/client.go @@ -98,8 +98,8 @@ func (c *Client) Close() { c.derpMapOnce.Do(func() { close(c.derpMapUpdates) }) } -func (c *Client) ConnectRPC24(ctx context.Context) ( - agentproto.DRPCAgentClient24, proto.DRPCTailnetClient24, error, +func (c *Client) ConnectRPC25(ctx context.Context) ( + agentproto.DRPCAgentClient25, proto.DRPCTailnetClient25, error, ) { conn, lis := drpcsdk.MemTransportPipe() c.LastWorkspaceAgent = func() { diff --git a/agent/proto/agent.pb.go b/agent/proto/agent.pb.go index ca454026f4790..562e349df9b2c 100644 --- a/agent/proto/agent.pb.go +++ b/agent/proto/agent.pb.go @@ -954,6 +954,7 @@ type Manifest struct { MotdPath string `protobuf:"bytes,6,opt,name=motd_path,json=motdPath,proto3" json:"motd_path,omitempty"` DisableDirectConnections bool `protobuf:"varint,7,opt,name=disable_direct_connections,json=disableDirectConnections,proto3" json:"disable_direct_connections,omitempty"` DerpForceWebsockets bool `protobuf:"varint,8,opt,name=derp_force_websockets,json=derpForceWebsockets,proto3" json:"derp_force_websockets,omitempty"` + ParentId []byte `protobuf:"bytes,18,opt,name=parent_id,json=parentId,proto3,oneof" json:"parent_id,omitempty"` DerpMap *proto.DERPMap `protobuf:"bytes,9,opt,name=derp_map,json=derpMap,proto3" json:"derp_map,omitempty"` Scripts []*WorkspaceAgentScript `protobuf:"bytes,10,rep,name=scripts,proto3" json:"scripts,omitempty"` Apps []*WorkspaceApp `protobuf:"bytes,11,rep,name=apps,proto3" json:"apps,omitempty"` @@ -1077,6 +1078,13 @@ func (x *Manifest) GetDerpForceWebsockets() bool { return false } +func (x *Manifest) GetParentId() []byte { + if x != nil { + return x.ParentId + } + return nil +} + func (x *Manifest) GetDerpMap() *proto.DERPMap { if x != nil { return x.DerpMap @@ -3665,7 +3673,7 @@ var file_agent_proto_agent_proto_rawDesc = []byte{ 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, - 0x22, 0xbc, 0x07, 0x0a, 0x08, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, + 0x22, 0xec, 0x07, 0x0a, 0x08, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x67, @@ -3699,32 +3707,35 @@ var file_agent_proto_agent_proto_rawDesc = []byte{ 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x64, 0x65, 0x72, 0x70, 0x5f, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x5f, 0x77, 0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x64, 0x65, 0x72, 0x70, 0x46, 0x6f, 0x72, - 0x63, 0x65, 0x57, 0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x12, 0x34, 0x0a, 0x08, - 0x64, 0x65, 0x72, 0x70, 0x5f, 0x6d, 0x61, 0x70, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, - 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x2e, 0x76, - 0x32, 0x2e, 0x44, 0x45, 0x52, 0x50, 0x4d, 0x61, 0x70, 0x52, 0x07, 0x64, 0x65, 0x72, 0x70, 0x4d, - 0x61, 0x70, 0x12, 0x3e, 0x0a, 0x07, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x73, 0x18, 0x0a, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, - 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, - 0x65, 0x6e, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x52, 0x07, 0x73, 0x63, 0x72, 0x69, 0x70, - 0x74, 0x73, 0x12, 0x30, 0x0a, 0x04, 0x61, 0x70, 0x70, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, - 0x32, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x70, 0x70, 0x52, 0x04, - 0x61, 0x70, 0x70, 0x73, 0x12, 0x4e, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, - 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, - 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0x12, 0x50, 0x0a, 0x0d, 0x64, 0x65, 0x76, 0x63, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x73, 0x18, 0x11, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x63, 0x6f, - 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x6f, 0x72, - 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x76, 0x63, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x0d, 0x64, 0x65, 0x76, 0x63, 0x6f, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x1a, 0x47, 0x0a, 0x19, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, - 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, + 0x63, 0x65, 0x57, 0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x12, 0x20, 0x0a, 0x09, + 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0c, 0x48, + 0x00, 0x52, 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x88, 0x01, 0x01, 0x12, 0x34, + 0x0a, 0x08, 0x64, 0x65, 0x72, 0x70, 0x5f, 0x6d, 0x61, 0x70, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, + 0x2e, 0x76, 0x32, 0x2e, 0x44, 0x45, 0x52, 0x50, 0x4d, 0x61, 0x70, 0x52, 0x07, 0x64, 0x65, 0x72, + 0x70, 0x4d, 0x61, 0x70, 0x12, 0x3e, 0x0a, 0x07, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x73, 0x18, + 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, + 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x41, 0x67, 0x65, 0x6e, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x52, 0x07, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x73, 0x12, 0x30, 0x0a, 0x04, 0x61, 0x70, 0x70, 0x73, 0x18, 0x0b, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, + 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x70, 0x70, + 0x52, 0x04, 0x61, 0x70, 0x70, 0x73, 0x12, 0x4e, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, + 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x6d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x50, 0x0a, 0x0d, 0x64, 0x65, 0x76, 0x63, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x18, 0x11, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, + 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x57, + 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x76, + 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x0d, 0x64, 0x65, 0x76, 0x63, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x1a, 0x47, 0x0a, 0x19, 0x45, 0x6e, 0x76, 0x69, + 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, + 0x01, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x22, 0x8c, 0x01, 0x0a, 0x1a, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x76, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x29, @@ -4901,6 +4912,7 @@ func file_agent_proto_agent_proto_init() { } } } + file_agent_proto_agent_proto_msgTypes[3].OneofWrappers = []interface{}{} file_agent_proto_agent_proto_msgTypes[30].OneofWrappers = []interface{}{} file_agent_proto_agent_proto_msgTypes[33].OneofWrappers = []interface{}{} file_agent_proto_agent_proto_msgTypes[46].OneofWrappers = []interface{}{} diff --git a/agent/proto/agent.proto b/agent/proto/agent.proto index 5bfd867720cfa..f6237980b6fd6 100644 --- a/agent/proto/agent.proto +++ b/agent/proto/agent.proto @@ -90,6 +90,7 @@ message Manifest { string motd_path = 6; bool disable_direct_connections = 7; bool derp_force_websockets = 8; + optional bytes parent_id = 18; coder.tailnet.v2.DERPMap derp_map = 9; repeated WorkspaceAgentScript scripts = 10; diff --git a/agent/proto/agent_drpc_old.go b/agent/proto/agent_drpc_old.go index 63b666a259c5c..e1e6625908c8a 100644 --- a/agent/proto/agent_drpc_old.go +++ b/agent/proto/agent_drpc_old.go @@ -50,3 +50,8 @@ type DRPCAgentClient24 interface { PushResourcesMonitoringUsage(ctx context.Context, in *PushResourcesMonitoringUsageRequest) (*PushResourcesMonitoringUsageResponse, error) ReportConnection(ctx context.Context, in *ReportConnectionRequest) (*emptypb.Empty, error) } + +// DRPCAgentClient25 is the Agent API at v2.5. +type DRPCAgentClient25 interface { + DRPCAgentClient24 +} diff --git a/coderd/agentapi/manifest.go b/coderd/agentapi/manifest.go index db8a0af3946a9..66bfe4cb5f94f 100644 --- a/coderd/agentapi/manifest.go +++ b/coderd/agentapi/manifest.go @@ -120,6 +120,11 @@ func (a *ManifestAPI) GetManifest(ctx context.Context, _ *agentproto.GetManifest return nil, xerrors.Errorf("converting workspace apps: %w", err) } + var parentID []byte + if workspaceAgent.ParentID.Valid { + parentID = workspaceAgent.ParentID.UUID[:] + } + return &agentproto.Manifest{ AgentId: workspaceAgent.ID[:], AgentName: workspaceAgent.Name, @@ -133,6 +138,7 @@ func (a *ManifestAPI) GetManifest(ctx context.Context, _ *agentproto.GetManifest MotdPath: workspaceAgent.MOTDFile, DisableDirectConnections: a.DisableDirectConnections, DerpForceWebsockets: a.DerpForceWebSockets, + ParentId: parentID, DerpMap: tailnet.DERPMapToProto(a.DerpMapFn()), Scripts: dbAgentScriptsToProto(scripts), diff --git a/coderd/agentapi/manifest_test.go b/coderd/agentapi/manifest_test.go index 98e7ccc8c8b52..9273acb0c40ff 100644 --- a/coderd/agentapi/manifest_test.go +++ b/coderd/agentapi/manifest_test.go @@ -60,6 +60,13 @@ func TestGetManifest(t *testing.T) { Directory: "/cool/dir", MOTDFile: "/cool/motd", } + childAgent = database.WorkspaceAgent{ + ID: uuid.New(), + Name: "cool-child-agent", + ParentID: uuid.NullUUID{Valid: true, UUID: agent.ID}, + Directory: "/workspace/dir", + MOTDFile: "/workspace/motd", + } apps = []database.WorkspaceApp{ { ID: uuid.New(), @@ -337,6 +344,7 @@ func TestGetManifest(t *testing.T) { expected := &agentproto.Manifest{ AgentId: agent.ID[:], AgentName: agent.Name, + ParentId: nil, OwnerUsername: owner.Username, WorkspaceId: workspace.ID[:], WorkspaceName: workspace.Name, @@ -364,6 +372,70 @@ func TestGetManifest(t *testing.T) { require.Equal(t, expected, got) }) + t.Run("OK/Child", func(t *testing.T) { + t.Parallel() + + mDB := dbmock.NewMockStore(gomock.NewController(t)) + + api := &agentapi.ManifestAPI{ + AccessURL: &url.URL{Scheme: "https", Host: "example.com"}, + AppHostname: "*--apps.example.com", + ExternalAuthConfigs: []*externalauth.Config{ + {Type: string(codersdk.EnhancedExternalAuthProviderGitHub)}, + {Type: "some-provider"}, + {Type: string(codersdk.EnhancedExternalAuthProviderGitLab)}, + }, + DisableDirectConnections: true, + DerpForceWebSockets: true, + + AgentFn: func(ctx context.Context) (database.WorkspaceAgent, error) { + return childAgent, nil + }, + WorkspaceID: workspace.ID, + Database: mDB, + DerpMapFn: derpMapFn, + } + + mDB.EXPECT().GetWorkspaceAppsByAgentID(gomock.Any(), childAgent.ID).Return([]database.WorkspaceApp{}, nil) + mDB.EXPECT().GetWorkspaceAgentScriptsByAgentIDs(gomock.Any(), []uuid.UUID{childAgent.ID}).Return([]database.WorkspaceAgentScript{}, nil) + mDB.EXPECT().GetWorkspaceAgentMetadata(gomock.Any(), database.GetWorkspaceAgentMetadataParams{ + WorkspaceAgentID: childAgent.ID, + Keys: nil, // all + }).Return([]database.WorkspaceAgentMetadatum{}, nil) + mDB.EXPECT().GetWorkspaceAgentDevcontainersByAgentID(gomock.Any(), childAgent.ID).Return([]database.WorkspaceAgentDevcontainer{}, nil) + mDB.EXPECT().GetWorkspaceByID(gomock.Any(), workspace.ID).Return(workspace, nil) + mDB.EXPECT().GetUserByID(gomock.Any(), workspace.OwnerID).Return(owner, nil) + + got, err := api.GetManifest(context.Background(), &agentproto.GetManifestRequest{}) + require.NoError(t, err) + + expected := &agentproto.Manifest{ + AgentId: childAgent.ID[:], + AgentName: childAgent.Name, + ParentId: agent.ID[:], + OwnerUsername: owner.Username, + WorkspaceId: workspace.ID[:], + WorkspaceName: workspace.Name, + GitAuthConfigs: 2, // two "enhanced" external auth configs + EnvironmentVariables: nil, + Directory: childAgent.Directory, + VsCodePortProxyUri: fmt.Sprintf("https://{{port}}--%s--%s--%s--apps.example.com", childAgent.Name, workspace.Name, owner.Username), + MotdPath: childAgent.MOTDFile, + DisableDirectConnections: true, + DerpForceWebsockets: true, + // tailnet.DERPMapToProto() is extensively tested elsewhere, so it's + // not necessary to manually recreate a big DERP map here like we + // did for apps and metadata. + DerpMap: tailnet.DERPMapToProto(derpMapFn()), + Scripts: []*agentproto.WorkspaceAgentScript{}, + Apps: []*agentproto.WorkspaceApp{}, + Metadata: []*agentproto.WorkspaceAgentMetadata_Description{}, + Devcontainers: []*agentproto.WorkspaceAgentDevcontainer{}, + } + + require.Equal(t, expected, got) + }) + t.Run("NoAppHostname", func(t *testing.T) { t.Parallel() diff --git a/coderd/workspaceagents_test.go b/coderd/workspaceagents_test.go index 10403f1ac00ae..0075a05fea083 100644 --- a/coderd/workspaceagents_test.go +++ b/coderd/workspaceagents_test.go @@ -2464,7 +2464,7 @@ func requireGetManifest(ctx context.Context, t testing.TB, aAPI agentproto.DRPCA } func postStartup(ctx context.Context, t testing.TB, client agent.Client, startup *agentproto.Startup) error { - aAPI, _, err := client.ConnectRPC24(ctx) + aAPI, _, err := client.ConnectRPC25(ctx) require.NoError(t, err) defer func() { cErr := aAPI.DRPCConn().Close() diff --git a/codersdk/agentsdk/agentsdk.go b/codersdk/agentsdk/agentsdk.go index ba3ff5681b742..9e6df933ce6c3 100644 --- a/codersdk/agentsdk/agentsdk.go +++ b/codersdk/agentsdk/agentsdk.go @@ -246,7 +246,7 @@ func (c *Client) ConnectRPC23(ctx context.Context) ( } // ConnectRPC24 returns a dRPC client to the Agent API v2.4. It is useful when you want to be -// maximally compatible with Coderd Release Versions from 2.xx+ // TODO @vincent: define version +// maximally compatible with Coderd Release Versions from 2.20+ func (c *Client) ConnectRPC24(ctx context.Context) ( proto.DRPCAgentClient24, tailnetproto.DRPCTailnetClient24, error, ) { @@ -257,6 +257,18 @@ func (c *Client) ConnectRPC24(ctx context.Context) ( return proto.NewDRPCAgentClient(conn), tailnetproto.NewDRPCTailnetClient(conn), nil } +// ConnectRPC25 returns a dRPC client to the Agent API v2.5. It is useful when you want to be +// maximally compatible with Coderd Release Versions from 2.xx+ // TODO(DanielleMaywood): Update version +func (c *Client) ConnectRPC25(ctx context.Context) ( + proto.DRPCAgentClient25, tailnetproto.DRPCTailnetClient25, error, +) { + conn, err := c.connectRPCVersion(ctx, apiversion.New(2, 5)) + if err != nil { + return nil, nil, err + } + return proto.NewDRPCAgentClient(conn), tailnetproto.NewDRPCTailnetClient(conn), nil +} + // ConnectRPC connects to the workspace agent API and tailnet API func (c *Client) ConnectRPC(ctx context.Context) (drpc.Conn, error) { return c.connectRPCVersion(ctx, proto.CurrentVersion) diff --git a/tailnet/proto/tailnet_drpc_old.go b/tailnet/proto/tailnet_drpc_old.go index c98932c9f41a7..ffbfa679b5912 100644 --- a/tailnet/proto/tailnet_drpc_old.go +++ b/tailnet/proto/tailnet_drpc_old.go @@ -40,3 +40,8 @@ type DRPCTailnetClient23 interface { type DRPCTailnetClient24 interface { DRPCTailnetClient23 } + +// DRPCTailnetClient25 is the Tailnet API at v2.5. +type DRPCTailnetClient25 interface { + DRPCTailnetClient24 +} diff --git a/tailnet/proto/version.go b/tailnet/proto/version.go index dd478fdcbdcd4..9e3e58ff0c051 100644 --- a/tailnet/proto/version.go +++ b/tailnet/proto/version.go @@ -45,9 +45,13 @@ import ( // PushResourcesMonitoringUsage RPCs on the Agent API. // - Added support for reporting connection events for auditing via the // ReportConnection RPC on the Agent API. +// +// API v2.5: +// - Shipped in Coder v2.xx.x // TODO(DanielleMaywood): Update version +// - Added `ParentId` to the agent manifest. const ( CurrentMajor = 2 - CurrentMinor = 4 + CurrentMinor = 5 ) var CurrentVersion = apiversion.New(CurrentMajor, CurrentMinor)