From a9bac040bb46da0211ba9fe79c856ff6484d2d15 Mon Sep 17 00:00:00 2001 From: Michael Quigley Date: Mon, 26 Aug 2024 14:18:17 -0400 Subject: [PATCH] most minimal public sharing (proxy only) to elaborate plumbing (#463) --- agent/agentGrpc/agent.pb.go | 365 +++++++++++++++++++++++++------ agent/agentGrpc/agent.proto | 18 ++ agent/agentGrpc/agent_grpc.pb.go | 42 +++- agent/model.go | 6 + agent/publicShare.go | 93 ++++++++ cmd/zrok/agentSharePublic.go | 111 ++++++++++ cmd/zrok/main.go | 6 + 7 files changed, 569 insertions(+), 72 deletions(-) create mode 100644 agent/publicShare.go create mode 100644 cmd/zrok/agentSharePublic.go diff --git a/agent/agentGrpc/agent.pb.go b/agent/agentGrpc/agent.pb.go index 7c24933d0..c96c229d5 100644 --- a/agent/agentGrpc/agent.pb.go +++ b/agent/agentGrpc/agent.pb.go @@ -83,6 +83,172 @@ func (x *AccessDetail) GetResponseHeaders() []string { return nil } +type PublicShareReply struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` +} + +func (x *PublicShareReply) Reset() { + *x = PublicShareReply{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_agentGrpc_agent_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PublicShareReply) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PublicShareReply) ProtoMessage() {} + +func (x *PublicShareReply) ProtoReflect() protoreflect.Message { + mi := &file_agent_agentGrpc_agent_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PublicShareReply.ProtoReflect.Descriptor instead. +func (*PublicShareReply) Descriptor() ([]byte, []int) { + return file_agent_agentGrpc_agent_proto_rawDescGZIP(), []int{1} +} + +func (x *PublicShareReply) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +type PublicShareRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Target string `protobuf:"bytes,1,opt,name=target,proto3" json:"target,omitempty"` + BasicAuth []string `protobuf:"bytes,2,rep,name=basicAuth,proto3" json:"basicAuth,omitempty"` + FrontendSelection []string `protobuf:"bytes,3,rep,name=frontendSelection,proto3" json:"frontendSelection,omitempty"` + BackendMode string `protobuf:"bytes,4,opt,name=backendMode,proto3" json:"backendMode,omitempty"` + Insecure bool `protobuf:"varint,5,opt,name=insecure,proto3" json:"insecure,omitempty"` + OauthProvider string `protobuf:"bytes,6,opt,name=oauthProvider,proto3" json:"oauthProvider,omitempty"` + OauthEmailAddressPatterns []string `protobuf:"bytes,7,rep,name=oauthEmailAddressPatterns,proto3" json:"oauthEmailAddressPatterns,omitempty"` + OauthCheckInterval string `protobuf:"bytes,8,opt,name=oauthCheckInterval,proto3" json:"oauthCheckInterval,omitempty"` + Closed bool `protobuf:"varint,9,opt,name=closed,proto3" json:"closed,omitempty"` + AccessGrants []string `protobuf:"bytes,10,rep,name=accessGrants,proto3" json:"accessGrants,omitempty"` +} + +func (x *PublicShareRequest) Reset() { + *x = PublicShareRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_agentGrpc_agent_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PublicShareRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PublicShareRequest) ProtoMessage() {} + +func (x *PublicShareRequest) ProtoReflect() protoreflect.Message { + mi := &file_agent_agentGrpc_agent_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PublicShareRequest.ProtoReflect.Descriptor instead. +func (*PublicShareRequest) Descriptor() ([]byte, []int) { + return file_agent_agentGrpc_agent_proto_rawDescGZIP(), []int{2} +} + +func (x *PublicShareRequest) GetTarget() string { + if x != nil { + return x.Target + } + return "" +} + +func (x *PublicShareRequest) GetBasicAuth() []string { + if x != nil { + return x.BasicAuth + } + return nil +} + +func (x *PublicShareRequest) GetFrontendSelection() []string { + if x != nil { + return x.FrontendSelection + } + return nil +} + +func (x *PublicShareRequest) GetBackendMode() string { + if x != nil { + return x.BackendMode + } + return "" +} + +func (x *PublicShareRequest) GetInsecure() bool { + if x != nil { + return x.Insecure + } + return false +} + +func (x *PublicShareRequest) GetOauthProvider() string { + if x != nil { + return x.OauthProvider + } + return "" +} + +func (x *PublicShareRequest) GetOauthEmailAddressPatterns() []string { + if x != nil { + return x.OauthEmailAddressPatterns + } + return nil +} + +func (x *PublicShareRequest) GetOauthCheckInterval() string { + if x != nil { + return x.OauthCheckInterval + } + return "" +} + +func (x *PublicShareRequest) GetClosed() bool { + if x != nil { + return x.Closed + } + return false +} + +func (x *PublicShareRequest) GetAccessGrants() []string { + if x != nil { + return x.AccessGrants + } + return nil +} + type ShareDetail struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -101,7 +267,7 @@ type ShareDetail struct { func (x *ShareDetail) Reset() { *x = ShareDetail{} if protoimpl.UnsafeEnabled { - mi := &file_agent_agentGrpc_agent_proto_msgTypes[1] + mi := &file_agent_agentGrpc_agent_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -114,7 +280,7 @@ func (x *ShareDetail) String() string { func (*ShareDetail) ProtoMessage() {} func (x *ShareDetail) ProtoReflect() protoreflect.Message { - mi := &file_agent_agentGrpc_agent_proto_msgTypes[1] + mi := &file_agent_agentGrpc_agent_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -127,7 +293,7 @@ func (x *ShareDetail) ProtoReflect() protoreflect.Message { // Deprecated: Use ShareDetail.ProtoReflect.Descriptor instead. func (*ShareDetail) Descriptor() ([]byte, []int) { - return file_agent_agentGrpc_agent_proto_rawDescGZIP(), []int{1} + return file_agent_agentGrpc_agent_proto_rawDescGZIP(), []int{3} } func (x *ShareDetail) GetToken() string { @@ -195,7 +361,7 @@ type StatusRequest struct { func (x *StatusRequest) Reset() { *x = StatusRequest{} if protoimpl.UnsafeEnabled { - mi := &file_agent_agentGrpc_agent_proto_msgTypes[2] + mi := &file_agent_agentGrpc_agent_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -208,7 +374,7 @@ func (x *StatusRequest) String() string { func (*StatusRequest) ProtoMessage() {} func (x *StatusRequest) ProtoReflect() protoreflect.Message { - mi := &file_agent_agentGrpc_agent_proto_msgTypes[2] + mi := &file_agent_agentGrpc_agent_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -221,7 +387,7 @@ func (x *StatusRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use StatusRequest.ProtoReflect.Descriptor instead. func (*StatusRequest) Descriptor() ([]byte, []int) { - return file_agent_agentGrpc_agent_proto_rawDescGZIP(), []int{2} + return file_agent_agentGrpc_agent_proto_rawDescGZIP(), []int{4} } type StatusReply struct { @@ -236,7 +402,7 @@ type StatusReply struct { func (x *StatusReply) Reset() { *x = StatusReply{} if protoimpl.UnsafeEnabled { - mi := &file_agent_agentGrpc_agent_proto_msgTypes[3] + mi := &file_agent_agentGrpc_agent_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -249,7 +415,7 @@ func (x *StatusReply) String() string { func (*StatusReply) ProtoMessage() {} func (x *StatusReply) ProtoReflect() protoreflect.Message { - mi := &file_agent_agentGrpc_agent_proto_msgTypes[3] + mi := &file_agent_agentGrpc_agent_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -262,7 +428,7 @@ func (x *StatusReply) ProtoReflect() protoreflect.Message { // Deprecated: Use StatusReply.ProtoReflect.Descriptor instead. func (*StatusReply) Descriptor() ([]byte, []int) { - return file_agent_agentGrpc_agent_proto_rawDescGZIP(), []int{3} + return file_agent_agentGrpc_agent_proto_rawDescGZIP(), []int{5} } func (x *StatusReply) GetAccesses() []*AccessDetail { @@ -288,7 +454,7 @@ type VersionRequest struct { func (x *VersionRequest) Reset() { *x = VersionRequest{} if protoimpl.UnsafeEnabled { - mi := &file_agent_agentGrpc_agent_proto_msgTypes[4] + mi := &file_agent_agentGrpc_agent_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -301,7 +467,7 @@ func (x *VersionRequest) String() string { func (*VersionRequest) ProtoMessage() {} func (x *VersionRequest) ProtoReflect() protoreflect.Message { - mi := &file_agent_agentGrpc_agent_proto_msgTypes[4] + mi := &file_agent_agentGrpc_agent_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -314,7 +480,7 @@ func (x *VersionRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use VersionRequest.ProtoReflect.Descriptor instead. func (*VersionRequest) Descriptor() ([]byte, []int) { - return file_agent_agentGrpc_agent_proto_rawDescGZIP(), []int{4} + return file_agent_agentGrpc_agent_proto_rawDescGZIP(), []int{6} } type VersionReply struct { @@ -328,7 +494,7 @@ type VersionReply struct { func (x *VersionReply) Reset() { *x = VersionReply{} if protoimpl.UnsafeEnabled { - mi := &file_agent_agentGrpc_agent_proto_msgTypes[5] + mi := &file_agent_agentGrpc_agent_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -341,7 +507,7 @@ func (x *VersionReply) String() string { func (*VersionReply) ProtoMessage() {} func (x *VersionReply) ProtoReflect() protoreflect.Message { - mi := &file_agent_agentGrpc_agent_proto_msgTypes[5] + mi := &file_agent_agentGrpc_agent_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -354,7 +520,7 @@ func (x *VersionReply) ProtoReflect() protoreflect.Message { // Deprecated: Use VersionReply.ProtoReflect.Descriptor instead. func (*VersionReply) Descriptor() ([]byte, []int) { - return file_agent_agentGrpc_agent_proto_rawDescGZIP(), []int{5} + return file_agent_agentGrpc_agent_proto_rawDescGZIP(), []int{7} } func (x *VersionReply) GetV() string { @@ -376,42 +542,73 @@ var file_agent_agentGrpc_agent_proto_rawDesc = []byte{ 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x28, 0x0a, 0x0f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x22, - 0x85, 0x02, 0x0a, 0x0b, 0x53, 0x68, 0x61, 0x72, 0x65, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x12, - 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x68, 0x61, 0x72, 0x65, 0x4d, 0x6f, - 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x68, 0x61, 0x72, 0x65, 0x4d, - 0x6f, 0x64, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x4d, 0x6f, - 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, - 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x64, 0x12, 0x2a, 0x0a, 0x10, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x45, 0x6e, 0x64, - 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x66, 0x72, 0x6f, - 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x28, 0x0a, - 0x0f, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x45, - 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6c, 0x6f, 0x73, 0x65, - 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x64, 0x12, - 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x0f, 0x0a, 0x0d, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x5e, 0x0a, 0x0b, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x29, 0x0a, 0x08, 0x61, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x41, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x08, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x65, 0x73, 0x12, 0x24, 0x0a, 0x06, 0x73, 0x68, 0x61, 0x72, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x65, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, - 0x52, 0x06, 0x73, 0x68, 0x61, 0x72, 0x65, 0x73, 0x22, 0x10, 0x0a, 0x0e, 0x56, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x1c, 0x0a, 0x0c, 0x56, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x0c, 0x0a, 0x01, 0x76, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x01, 0x76, 0x32, 0x5e, 0x0a, 0x05, 0x41, 0x67, 0x65, 0x6e, - 0x74, 0x12, 0x28, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0e, 0x2e, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0c, 0x2e, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x2b, 0x0a, 0x07, 0x56, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x0f, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0d, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x42, 0x2a, 0x5a, 0x28, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x7a, 0x69, 0x74, 0x69, 0x2f, - 0x7a, 0x72, 0x6f, 0x6b, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, - 0x47, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x28, 0x0a, 0x10, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x53, 0x68, 0x61, 0x72, 0x65, 0x52, 0x65, + 0x70, 0x6c, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x86, 0x03, 0x0a, 0x12, 0x50, 0x75, + 0x62, 0x6c, 0x69, 0x63, 0x53, 0x68, 0x61, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x62, 0x61, 0x73, 0x69, + 0x63, 0x41, 0x75, 0x74, 0x68, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x62, 0x61, 0x73, + 0x69, 0x63, 0x41, 0x75, 0x74, 0x68, 0x12, 0x2c, 0x0a, 0x11, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x65, + 0x6e, 0x64, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x11, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x53, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x4d, + 0x6f, 0x64, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x62, 0x61, 0x63, 0x6b, 0x65, + 0x6e, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x6e, 0x73, 0x65, 0x63, 0x75, + 0x72, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x69, 0x6e, 0x73, 0x65, 0x63, 0x75, + 0x72, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x6f, 0x61, 0x75, 0x74, 0x68, 0x50, 0x72, 0x6f, 0x76, 0x69, + 0x64, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6f, 0x61, 0x75, 0x74, 0x68, + 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x3c, 0x0a, 0x19, 0x6f, 0x61, 0x75, 0x74, + 0x68, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x50, 0x61, 0x74, + 0x74, 0x65, 0x72, 0x6e, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x19, 0x6f, 0x61, 0x75, + 0x74, 0x68, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x50, 0x61, + 0x74, 0x74, 0x65, 0x72, 0x6e, 0x73, 0x12, 0x2e, 0x0a, 0x12, 0x6f, 0x61, 0x75, 0x74, 0x68, 0x43, + 0x68, 0x65, 0x63, 0x6b, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x08, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x12, 0x6f, 0x61, 0x75, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x49, 0x6e, + 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x64, + 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x64, 0x12, 0x22, + 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x18, 0x0a, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x6e, + 0x74, 0x73, 0x22, 0x85, 0x02, 0x0a, 0x0b, 0x53, 0x68, 0x61, 0x72, 0x65, 0x44, 0x65, 0x74, 0x61, + 0x69, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x68, 0x61, 0x72, + 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x68, 0x61, + 0x72, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, + 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x62, 0x61, 0x63, + 0x6b, 0x65, 0x6e, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x72, 0x65, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x64, 0x12, 0x2a, 0x0a, 0x10, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, + 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, + 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, + 0x12, 0x28, 0x0a, 0x0f, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x45, 0x6e, 0x64, 0x70, 0x6f, + 0x69, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x62, 0x61, 0x63, 0x6b, 0x65, + 0x6e, 0x64, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6c, + 0x6f, 0x73, 0x65, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x63, 0x6c, 0x6f, 0x73, + 0x65, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x08, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x0f, 0x0a, 0x0d, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x5e, 0x0a, 0x0b, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x29, 0x0a, 0x08, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x08, 0x61, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, 0x24, 0x0a, 0x06, 0x73, 0x68, 0x61, 0x72, 0x65, 0x73, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x65, 0x44, 0x65, 0x74, + 0x61, 0x69, 0x6c, 0x52, 0x06, 0x73, 0x68, 0x61, 0x72, 0x65, 0x73, 0x22, 0x10, 0x0a, 0x0e, 0x56, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x1c, 0x0a, + 0x0c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x0c, 0x0a, + 0x01, 0x76, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x01, 0x76, 0x32, 0x97, 0x01, 0x0a, 0x05, + 0x41, 0x67, 0x65, 0x6e, 0x74, 0x12, 0x37, 0x0a, 0x0b, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x53, + 0x68, 0x61, 0x72, 0x65, 0x12, 0x13, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x53, 0x68, 0x61, + 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x50, 0x75, 0x62, 0x6c, + 0x69, 0x63, 0x53, 0x68, 0x61, 0x72, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x28, + 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0e, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0c, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x2b, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x12, 0x0f, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0d, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x70, 0x6c, 0x79, 0x22, 0x00, 0x42, 0x2a, 0x5a, 0x28, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x7a, 0x69, 0x74, 0x69, 0x2f, 0x7a, 0x72, 0x6f, + 0x6b, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x70, + 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -426,24 +623,28 @@ func file_agent_agentGrpc_agent_proto_rawDescGZIP() []byte { return file_agent_agentGrpc_agent_proto_rawDescData } -var file_agent_agentGrpc_agent_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_agent_agentGrpc_agent_proto_msgTypes = make([]protoimpl.MessageInfo, 8) var file_agent_agentGrpc_agent_proto_goTypes = []any{ - (*AccessDetail)(nil), // 0: AccessDetail - (*ShareDetail)(nil), // 1: ShareDetail - (*StatusRequest)(nil), // 2: StatusRequest - (*StatusReply)(nil), // 3: StatusReply - (*VersionRequest)(nil), // 4: VersionRequest - (*VersionReply)(nil), // 5: VersionReply + (*AccessDetail)(nil), // 0: AccessDetail + (*PublicShareReply)(nil), // 1: PublicShareReply + (*PublicShareRequest)(nil), // 2: PublicShareRequest + (*ShareDetail)(nil), // 3: ShareDetail + (*StatusRequest)(nil), // 4: StatusRequest + (*StatusReply)(nil), // 5: StatusReply + (*VersionRequest)(nil), // 6: VersionRequest + (*VersionReply)(nil), // 7: VersionReply } var file_agent_agentGrpc_agent_proto_depIdxs = []int32{ 0, // 0: StatusReply.accesses:type_name -> AccessDetail - 1, // 1: StatusReply.shares:type_name -> ShareDetail - 2, // 2: Agent.Status:input_type -> StatusRequest - 4, // 3: Agent.Version:input_type -> VersionRequest - 3, // 4: Agent.Status:output_type -> StatusReply - 5, // 5: Agent.Version:output_type -> VersionReply - 4, // [4:6] is the sub-list for method output_type - 2, // [2:4] is the sub-list for method input_type + 3, // 1: StatusReply.shares:type_name -> ShareDetail + 2, // 2: Agent.PublicShare:input_type -> PublicShareRequest + 4, // 3: Agent.Status:input_type -> StatusRequest + 6, // 4: Agent.Version:input_type -> VersionRequest + 1, // 5: Agent.PublicShare:output_type -> PublicShareReply + 5, // 6: Agent.Status:output_type -> StatusReply + 7, // 7: Agent.Version:output_type -> VersionReply + 5, // [5:8] is the sub-list for method output_type + 2, // [2:5] is the sub-list for method input_type 2, // [2:2] is the sub-list for extension type_name 2, // [2:2] is the sub-list for extension extendee 0, // [0:2] is the sub-list for field type_name @@ -468,7 +669,7 @@ func file_agent_agentGrpc_agent_proto_init() { } } file_agent_agentGrpc_agent_proto_msgTypes[1].Exporter = func(v any, i int) any { - switch v := v.(*ShareDetail); i { + switch v := v.(*PublicShareReply); i { case 0: return &v.state case 1: @@ -480,7 +681,7 @@ func file_agent_agentGrpc_agent_proto_init() { } } file_agent_agentGrpc_agent_proto_msgTypes[2].Exporter = func(v any, i int) any { - switch v := v.(*StatusRequest); i { + switch v := v.(*PublicShareRequest); i { case 0: return &v.state case 1: @@ -492,7 +693,7 @@ func file_agent_agentGrpc_agent_proto_init() { } } file_agent_agentGrpc_agent_proto_msgTypes[3].Exporter = func(v any, i int) any { - switch v := v.(*StatusReply); i { + switch v := v.(*ShareDetail); i { case 0: return &v.state case 1: @@ -504,7 +705,7 @@ func file_agent_agentGrpc_agent_proto_init() { } } file_agent_agentGrpc_agent_proto_msgTypes[4].Exporter = func(v any, i int) any { - switch v := v.(*VersionRequest); i { + switch v := v.(*StatusRequest); i { case 0: return &v.state case 1: @@ -516,6 +717,30 @@ func file_agent_agentGrpc_agent_proto_init() { } } file_agent_agentGrpc_agent_proto_msgTypes[5].Exporter = func(v any, i int) any { + switch v := v.(*StatusReply); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_agentGrpc_agent_proto_msgTypes[6].Exporter = func(v any, i int) any { + switch v := v.(*VersionRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_agentGrpc_agent_proto_msgTypes[7].Exporter = func(v any, i int) any { switch v := v.(*VersionReply); i { case 0: return &v.state @@ -534,7 +759,7 @@ func file_agent_agentGrpc_agent_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_agent_agentGrpc_agent_proto_rawDesc, NumEnums: 0, - NumMessages: 6, + NumMessages: 8, NumExtensions: 0, NumServices: 1, }, diff --git a/agent/agentGrpc/agent.proto b/agent/agentGrpc/agent.proto index a022e63dd..421b21412 100644 --- a/agent/agentGrpc/agent.proto +++ b/agent/agentGrpc/agent.proto @@ -3,6 +3,7 @@ syntax = "proto3"; option go_package = "github.com/openziti/zrok/agent/agentGrpc"; service Agent { + rpc PublicShare(PublicShareRequest) returns (PublicShareReply) {} rpc Status(StatusRequest) returns (StatusReply) {} rpc Version(VersionRequest) returns (VersionReply) {} } @@ -13,6 +14,23 @@ message AccessDetail { repeated string responseHeaders = 3; } +message PublicShareReply { + string token = 1; +} + +message PublicShareRequest { + string target = 1; + repeated string basicAuth = 2; + repeated string frontendSelection = 3; + string backendMode = 4; + bool insecure = 5; + string oauthProvider = 6; + repeated string oauthEmailAddressPatterns = 7; + string oauthCheckInterval = 8; + bool closed = 9; + repeated string accessGrants = 10; +} + message ShareDetail { string token = 1; string shareMode = 2; diff --git a/agent/agentGrpc/agent_grpc.pb.go b/agent/agentGrpc/agent_grpc.pb.go index 26cefa8fe..d65597b31 100644 --- a/agent/agentGrpc/agent_grpc.pb.go +++ b/agent/agentGrpc/agent_grpc.pb.go @@ -19,14 +19,16 @@ import ( const _ = grpc.SupportPackageIsVersion9 const ( - Agent_Status_FullMethodName = "/Agent/Status" - Agent_Version_FullMethodName = "/Agent/Version" + Agent_PublicShare_FullMethodName = "/Agent/PublicShare" + Agent_Status_FullMethodName = "/Agent/Status" + Agent_Version_FullMethodName = "/Agent/Version" ) // AgentClient is the client API for Agent service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type AgentClient interface { + PublicShare(ctx context.Context, in *PublicShareRequest, opts ...grpc.CallOption) (*PublicShareReply, error) Status(ctx context.Context, in *StatusRequest, opts ...grpc.CallOption) (*StatusReply, error) Version(ctx context.Context, in *VersionRequest, opts ...grpc.CallOption) (*VersionReply, error) } @@ -39,6 +41,16 @@ func NewAgentClient(cc grpc.ClientConnInterface) AgentClient { return &agentClient{cc} } +func (c *agentClient) PublicShare(ctx context.Context, in *PublicShareRequest, opts ...grpc.CallOption) (*PublicShareReply, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(PublicShareReply) + err := c.cc.Invoke(ctx, Agent_PublicShare_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *agentClient) Status(ctx context.Context, in *StatusRequest, opts ...grpc.CallOption) (*StatusReply, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(StatusReply) @@ -63,6 +75,7 @@ func (c *agentClient) Version(ctx context.Context, in *VersionRequest, opts ...g // All implementations must embed UnimplementedAgentServer // for forward compatibility. type AgentServer interface { + PublicShare(context.Context, *PublicShareRequest) (*PublicShareReply, error) Status(context.Context, *StatusRequest) (*StatusReply, error) Version(context.Context, *VersionRequest) (*VersionReply, error) mustEmbedUnimplementedAgentServer() @@ -75,6 +88,9 @@ type AgentServer interface { // pointer dereference when methods are called. type UnimplementedAgentServer struct{} +func (UnimplementedAgentServer) PublicShare(context.Context, *PublicShareRequest) (*PublicShareReply, error) { + return nil, status.Errorf(codes.Unimplemented, "method PublicShare not implemented") +} func (UnimplementedAgentServer) Status(context.Context, *StatusRequest) (*StatusReply, error) { return nil, status.Errorf(codes.Unimplemented, "method Status not implemented") } @@ -102,6 +118,24 @@ func RegisterAgentServer(s grpc.ServiceRegistrar, srv AgentServer) { s.RegisterService(&Agent_ServiceDesc, srv) } +func _Agent_PublicShare_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PublicShareRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AgentServer).PublicShare(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Agent_PublicShare_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AgentServer).PublicShare(ctx, req.(*PublicShareRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Agent_Status_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(StatusRequest) if err := dec(in); err != nil { @@ -145,6 +179,10 @@ var Agent_ServiceDesc = grpc.ServiceDesc{ ServiceName: "Agent", HandlerType: (*AgentServer)(nil), Methods: []grpc.MethodDesc{ + { + MethodName: "PublicShare", + Handler: _Agent_PublicShare_Handler, + }, { MethodName: "Status", Handler: _Agent_Status_Handler, diff --git a/agent/model.go b/agent/model.go index fd0bf81d6..72da4c24f 100644 --- a/agent/model.go +++ b/agent/model.go @@ -21,6 +21,8 @@ type share struct { oauthCheckInterval time.Duration closed bool accessGrants []string + + handler backendHandler } type access struct { @@ -34,3 +36,7 @@ type agentGrpcImpl struct { agentGrpc.UnimplementedAgentServer a *Agent } + +type backendHandler interface { + Run() error +} diff --git a/agent/publicShare.go b/agent/publicShare.go new file mode 100644 index 000000000..5b7be474e --- /dev/null +++ b/agent/publicShare.go @@ -0,0 +1,93 @@ +package agent + +import ( + "context" + "errors" + "github.com/openziti/zrok/agent/agentGrpc" + "github.com/openziti/zrok/endpoints/proxy" + "github.com/openziti/zrok/environment" + "github.com/openziti/zrok/sdk/golang/sdk" + "github.com/sirupsen/logrus" + "time" +) + +func (i *agentGrpcImpl) PublicShare(_ context.Context, req *agentGrpc.PublicShareRequest) (*agentGrpc.PublicShareReply, error) { + root, err := environment.LoadRoot() + if err != nil { + return nil, err + } + + if !root.IsEnabled() { + return nil, errors.New("unable to load environment; did you 'zrok enable'?") + } + + zif, err := root.ZitiIdentityNamed(root.EnvironmentIdentityName()) + if err != nil { + return nil, err + } + + shrReq := &sdk.ShareRequest{ + BackendMode: sdk.BackendMode(req.BackendMode), + ShareMode: sdk.PublicShareMode, + Frontends: req.FrontendSelection, + BasicAuth: req.BasicAuth, + Target: req.Target, + } + if req.Closed { + shrReq.PermissionMode = sdk.ClosedPermissionMode + shrReq.AccessGrants = req.AccessGrants + } + if req.OauthProvider != "" { + shrReq.OauthProvider = req.OauthProvider + shrReq.OauthEmailAddressPatterns = req.OauthEmailAddressPatterns + checkInterval, err := time.ParseDuration(req.GetOauthCheckInterval()) + if err != nil { + return nil, err + } + shrReq.OauthAuthorizationCheckInterval = checkInterval + } + shr, err := sdk.CreateShare(root, shrReq) + if err != nil { + return nil, err + } + + switch req.BackendMode { + case "proxy": + cfg := &proxy.BackendConfig{ + IdentityPath: zif, + EndpointAddress: req.Target, + ShrToken: shr.Token, + Insecure: req.Insecure, + } + + be, err := proxy.NewBackend(cfg) + if err != nil { + return nil, err + } + + agentShr := &share{ + token: shr.Token, + target: req.Target, + basicAuth: req.BasicAuth, + frontendSelection: shr.FrontendEndpoints, + shareMode: sdk.PublicShareMode, + backendMode: sdk.BackendMode(req.BackendMode), + insecure: req.Insecure, + oauthProvider: req.OauthProvider, + oauthEmailAddressPatterns: req.OauthEmailAddressPatterns, + oauthCheckInterval: shrReq.OauthAuthorizationCheckInterval, + closed: req.Closed, + accessGrants: req.AccessGrants, + handler: be, + } + + i.a.shares[shr.Token] = agentShr + go func() { + if err := agentShr.handler.Run(); err != nil { + logrus.Errorf("error running proxy backend: %v", err) + } + }() + } + + return &agentGrpc.PublicShareReply{Token: shr.Token}, nil +} diff --git a/cmd/zrok/agentSharePublic.go b/cmd/zrok/agentSharePublic.go new file mode 100644 index 000000000..03da860fa --- /dev/null +++ b/cmd/zrok/agentSharePublic.go @@ -0,0 +1,111 @@ +package main + +import ( + "context" + "fmt" + "github.com/openziti/zrok/agent/agentClient" + "github.com/openziti/zrok/agent/agentGrpc" + "github.com/openziti/zrok/environment" + "github.com/openziti/zrok/tui" + "github.com/spf13/cobra" + "time" +) + +func init() { + agentShareCmd.AddCommand(newAgentSharePublicCommand().cmd) +} + +type agentSharePublicCommand struct { + basicAuth []string + frontendSelection []string + backendMode string + headless bool + insecure bool + oauthProvider string + oauthEmailAddressPatterns []string + oauthCheckInterval time.Duration + closed bool + accessGrants []string + cmd *cobra.Command +} + +func newAgentSharePublicCommand() *agentSharePublicCommand { + cmd := &cobra.Command{ + Use: "public ", + Short: "Create a public share in the zrok Agent", + Args: cobra.ExactArgs(1), + } + command := &agentSharePublicCommand{cmd: cmd} + defaultFrontends := []string{"public"} + if root, err := environment.LoadRoot(); err == nil { + defaultFrontend, _ := root.DefaultFrontend() + defaultFrontends = []string{defaultFrontend} + } + cmd.Flags().StringArrayVar(&command.frontendSelection, "frontend", defaultFrontends, "Selected frontends to use for the share") + cmd.Flags().StringVarP(&command.backendMode, "backend-mode", "b", "proxy", "The backend mode {proxy, web, caddy, drive}") + cmd.Flags().BoolVar(&command.headless, "headless", false, "Disable TUI and run headless") + cmd.Flags().BoolVar(&command.insecure, "insecure", false, "Enable insecure TLS certificate validation for ") + cmd.Flags().BoolVar(&command.closed, "closed", false, "Enable closed permission mode (see --access-grant)") + cmd.Flags().StringArrayVar(&command.accessGrants, "access-grant", []string{}, "zrok accounts that are allowed to access this share (see --closed)") + + cmd.Flags().StringArrayVar(&command.basicAuth, "basic-auth", []string{}, "Basic authentication users (,...)") + cmd.Flags().StringVar(&command.oauthProvider, "oauth-provider", "", "Enable OAuth provider [google, github]") + cmd.Flags().StringArrayVar(&command.oauthEmailAddressPatterns, "oauth-email-address-patterns", []string{}, "Allow only these email domain globs to authenticate via OAuth") + cmd.Flags().DurationVar(&command.oauthCheckInterval, "oauth-check-interval", 3*time.Hour, "Maximum lifetime for OAuth authentication; reauthenticate after expiry") + cmd.MarkFlagsMutuallyExclusive("basic-auth", "oauth-provider") + + cmd.Run = command.run + return command +} + +func (cmd *agentSharePublicCommand) run(_ *cobra.Command, args []string) { + var target string + + switch cmd.backendMode { + case "proxy": + v, err := parseUrl(args[0]) + if err != nil { + if !panicInstead { + tui.Error("invalid target endpoint URL", err) + } + panic(err) + } + target = v + } + + root, err := environment.LoadRoot() + if err != nil { + if !panicInstead { + tui.Error("unable to load environment", err) + } + panic(err) + } + + if !root.IsEnabled() { + tui.Error("unable to load environment; did you 'zrok enable'?", nil) + } + + client, conn, err := agentClient.NewClient(root) + if err != nil { + tui.Error("error connecting to agent", err) + } + defer conn.Close() + + shr, err := client.PublicShare(context.Background(), &agentGrpc.PublicShareRequest{ + Target: target, + BasicAuth: cmd.basicAuth, + FrontendSelection: cmd.frontendSelection, + BackendMode: cmd.backendMode, + Insecure: cmd.insecure, + OauthProvider: cmd.oauthProvider, + OauthEmailAddressPatterns: cmd.oauthEmailAddressPatterns, + OauthCheckInterval: cmd.oauthCheckInterval.String(), + Closed: cmd.closed, + AccessGrants: cmd.accessGrants, + }) + if err != nil { + tui.Error("error creating share", err) + } + + fmt.Println(shr.GetToken()) +} diff --git a/cmd/zrok/main.go b/cmd/zrok/main.go index 9fe7eb4a5..1c540a76b 100644 --- a/cmd/zrok/main.go +++ b/cmd/zrok/main.go @@ -24,6 +24,7 @@ func init() { adminCmd.AddCommand(adminListCmd) adminCmd.AddCommand(adminUpdateCmd) rootCmd.AddCommand(agentCmd) + agentCmd.AddCommand(agentShareCmd) testCmd.AddCommand(loopCmd) rootCmd.AddCommand(adminCmd) rootCmd.AddCommand(configCmd) @@ -82,6 +83,11 @@ var agentCmd = &cobra.Command{ Aliases: []string{"daemon"}, } +var agentShareCmd = &cobra.Command{ + Use: "share", + Short: "zrok Agent sharing commands", +} + var configCmd = &cobra.Command{ Use: "config", Short: "Configure your zrok environment",