diff --git a/api/managementpb/external.pb.go b/api/managementpb/external.pb.go new file mode 100644 index 0000000000..31878dd9cb --- /dev/null +++ b/api/managementpb/external.pb.go @@ -0,0 +1,352 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: managementpb/external.proto + +package managementpb + +import ( + context "context" + fmt "fmt" + proto "github.com/golang/protobuf/proto" + _ "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/options" + _ "github.com/mwitkow/go-proto-validators" + inventorypb "github.com/percona/pmm/api/inventorypb" + _ "google.golang.org/genproto/googleapis/api/annotations" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +type AddExternalRequest struct { + // Node identifier on which a external exporter is been running. Required. + RunsOnNodeId string `protobuf:"bytes,1,opt,name=runs_on_node_id,json=runsOnNodeId,proto3" json:"runs_on_node_id,omitempty"` + // Unique across all Services user-defined name. Required. + ServiceName string `protobuf:"bytes,2,opt,name=service_name,json=serviceName,proto3" json:"service_name,omitempty"` + // HTTP basic auth username for collecting metrics. + Username string `protobuf:"bytes,3,opt,name=username,proto3" json:"username,omitempty"` + // HTTP basic auth password for collecting metrics. + Password string `protobuf:"bytes,4,opt,name=password,proto3" json:"password,omitempty"` + // Scheme to generate URI to exporter metrics endpoints. + Scheme string `protobuf:"bytes,5,opt,name=scheme,proto3" json:"scheme,omitempty"` + // Path under which metrics are exposed, used to generate URI. + MetricsPath string `protobuf:"bytes,6,opt,name=metrics_path,json=metricsPath,proto3" json:"metrics_path,omitempty"` + // Listen port for scraping metrics. + ListenPort uint32 `protobuf:"varint,7,opt,name=listen_port,json=listenPort,proto3" json:"listen_port,omitempty"` + // Node identifier on which a external service is been running. Required. + NodeId string `protobuf:"bytes,8,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"` + // Environment name. + Environment string `protobuf:"bytes,9,opt,name=environment,proto3" json:"environment,omitempty"` + // Cluster name. + Cluster string `protobuf:"bytes,10,opt,name=cluster,proto3" json:"cluster,omitempty"` + // Replication set name. + ReplicationSet string `protobuf:"bytes,11,opt,name=replication_set,json=replicationSet,proto3" json:"replication_set,omitempty"` + // Custom user-assigned labels for Service. + CustomLabels map[string]string `protobuf:"bytes,15,rep,name=custom_labels,json=customLabels,proto3" json:"custom_labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *AddExternalRequest) Reset() { *m = AddExternalRequest{} } +func (m *AddExternalRequest) String() string { return proto.CompactTextString(m) } +func (*AddExternalRequest) ProtoMessage() {} +func (*AddExternalRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_dab8accc93fe1440, []int{0} +} + +func (m *AddExternalRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_AddExternalRequest.Unmarshal(m, b) +} +func (m *AddExternalRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_AddExternalRequest.Marshal(b, m, deterministic) +} +func (m *AddExternalRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_AddExternalRequest.Merge(m, src) +} +func (m *AddExternalRequest) XXX_Size() int { + return xxx_messageInfo_AddExternalRequest.Size(m) +} +func (m *AddExternalRequest) XXX_DiscardUnknown() { + xxx_messageInfo_AddExternalRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_AddExternalRequest proto.InternalMessageInfo + +func (m *AddExternalRequest) GetRunsOnNodeId() string { + if m != nil { + return m.RunsOnNodeId + } + return "" +} + +func (m *AddExternalRequest) GetServiceName() string { + if m != nil { + return m.ServiceName + } + return "" +} + +func (m *AddExternalRequest) GetUsername() string { + if m != nil { + return m.Username + } + return "" +} + +func (m *AddExternalRequest) GetPassword() string { + if m != nil { + return m.Password + } + return "" +} + +func (m *AddExternalRequest) GetScheme() string { + if m != nil { + return m.Scheme + } + return "" +} + +func (m *AddExternalRequest) GetMetricsPath() string { + if m != nil { + return m.MetricsPath + } + return "" +} + +func (m *AddExternalRequest) GetListenPort() uint32 { + if m != nil { + return m.ListenPort + } + return 0 +} + +func (m *AddExternalRequest) GetNodeId() string { + if m != nil { + return m.NodeId + } + return "" +} + +func (m *AddExternalRequest) GetEnvironment() string { + if m != nil { + return m.Environment + } + return "" +} + +func (m *AddExternalRequest) GetCluster() string { + if m != nil { + return m.Cluster + } + return "" +} + +func (m *AddExternalRequest) GetReplicationSet() string { + if m != nil { + return m.ReplicationSet + } + return "" +} + +func (m *AddExternalRequest) GetCustomLabels() map[string]string { + if m != nil { + return m.CustomLabels + } + return nil +} + +type AddExternalResponse struct { + Service *inventorypb.ExternalService `protobuf:"bytes,1,opt,name=service,proto3" json:"service,omitempty"` + ExternalExporter *inventorypb.ExternalExporter `protobuf:"bytes,2,opt,name=external_exporter,json=externalExporter,proto3" json:"external_exporter,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *AddExternalResponse) Reset() { *m = AddExternalResponse{} } +func (m *AddExternalResponse) String() string { return proto.CompactTextString(m) } +func (*AddExternalResponse) ProtoMessage() {} +func (*AddExternalResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_dab8accc93fe1440, []int{1} +} + +func (m *AddExternalResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_AddExternalResponse.Unmarshal(m, b) +} +func (m *AddExternalResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_AddExternalResponse.Marshal(b, m, deterministic) +} +func (m *AddExternalResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_AddExternalResponse.Merge(m, src) +} +func (m *AddExternalResponse) XXX_Size() int { + return xxx_messageInfo_AddExternalResponse.Size(m) +} +func (m *AddExternalResponse) XXX_DiscardUnknown() { + xxx_messageInfo_AddExternalResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_AddExternalResponse proto.InternalMessageInfo + +func (m *AddExternalResponse) GetService() *inventorypb.ExternalService { + if m != nil { + return m.Service + } + return nil +} + +func (m *AddExternalResponse) GetExternalExporter() *inventorypb.ExternalExporter { + if m != nil { + return m.ExternalExporter + } + return nil +} + +func init() { + proto.RegisterType((*AddExternalRequest)(nil), "management.AddExternalRequest") + proto.RegisterMapType((map[string]string)(nil), "management.AddExternalRequest.CustomLabelsEntry") + proto.RegisterType((*AddExternalResponse)(nil), "management.AddExternalResponse") +} + +func init() { proto.RegisterFile("managementpb/external.proto", fileDescriptor_dab8accc93fe1440) } + +var fileDescriptor_dab8accc93fe1440 = []byte{ + // 609 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x94, 0xdb, 0x6e, 0xd3, 0x4c, + 0x10, 0xc7, 0x3f, 0xa7, 0x6d, 0xd2, 0x8e, 0xd3, 0xd3, 0x7e, 0x08, 0xad, 0x5c, 0x44, 0x42, 0x2e, + 0xa0, 0x1c, 0x62, 0x43, 0x40, 0x08, 0xf5, 0x06, 0xb5, 0xa8, 0x12, 0x48, 0xa8, 0x54, 0xae, 0x90, + 0x10, 0x37, 0xd6, 0xc6, 0x1e, 0x39, 0x56, 0xed, 0x5d, 0xb3, 0xbb, 0x76, 0xda, 0xbb, 0xaa, 0xaf, + 0x80, 0x78, 0x0b, 0xde, 0x86, 0x07, 0xa8, 0x54, 0xf1, 0x20, 0xc8, 0xa7, 0x36, 0x25, 0xc0, 0x55, + 0x76, 0xe6, 0xf7, 0xdf, 0x99, 0x9d, 0xfc, 0x77, 0x0d, 0x5b, 0x09, 0xe3, 0x2c, 0xc4, 0x04, 0xb9, + 0x4e, 0xc7, 0x0e, 0x9e, 0x68, 0x94, 0x9c, 0xc5, 0x76, 0x2a, 0x85, 0x16, 0x04, 0xae, 0xa1, 0xf5, + 0x32, 0x8c, 0xf4, 0x24, 0x1b, 0xdb, 0xbe, 0x48, 0x9c, 0x64, 0x1a, 0xe9, 0x63, 0x31, 0x75, 0x42, + 0x31, 0x2c, 0x85, 0xc3, 0x9c, 0xc5, 0x51, 0xc0, 0xb4, 0x90, 0xca, 0xb9, 0x5a, 0x56, 0x35, 0xac, + 0x3b, 0xa1, 0x10, 0x61, 0x8c, 0x0e, 0x4b, 0x23, 0x87, 0x71, 0x2e, 0x34, 0xd3, 0x91, 0xe0, 0xaa, + 0xa6, 0x34, 0xe2, 0x39, 0x72, 0x2d, 0xe4, 0x69, 0x3a, 0x76, 0x58, 0x88, 0x5c, 0x37, 0xc4, 0x9a, + 0x25, 0x0a, 0x65, 0x1e, 0xf9, 0xd8, 0xb0, 0x27, 0xe5, 0x8f, 0x3f, 0x0c, 0x91, 0x0f, 0xd5, 0x94, + 0x85, 0x21, 0x4a, 0x47, 0xa4, 0x65, 0xdd, 0xf9, 0x1e, 0x83, 0xef, 0x8b, 0x40, 0x76, 0x83, 0x60, + 0xbf, 0x9e, 0xcd, 0xc5, 0x2f, 0x19, 0x2a, 0x4d, 0x86, 0xb0, 0x2e, 0x33, 0xae, 0x3c, 0xc1, 0x3d, + 0x2e, 0x02, 0xf4, 0xa2, 0x80, 0x1a, 0x7d, 0x63, 0x7b, 0x65, 0xaf, 0x7d, 0x79, 0xd1, 0x6b, 0x7d, + 0x32, 0xdc, 0x6e, 0x81, 0x3f, 0xf0, 0x03, 0x11, 0xe0, 0xbb, 0x80, 0x3c, 0x84, 0x6e, 0x7d, 0x0a, + 0x8f, 0xb3, 0x04, 0x69, 0xeb, 0x86, 0xd6, 0xac, 0xd9, 0x01, 0x4b, 0x90, 0x58, 0xb0, 0x9c, 0xa9, + 0xa2, 0x57, 0x82, 0x74, 0xa1, 0x90, 0xb9, 0x57, 0x71, 0xc1, 0x52, 0xa6, 0xd4, 0x54, 0xc8, 0x80, + 0x2e, 0x56, 0xac, 0x89, 0xc9, 0x6d, 0x68, 0x2b, 0x7f, 0x82, 0x09, 0xd2, 0xa5, 0x92, 0xd4, 0x11, + 0xb9, 0x07, 0xdd, 0x04, 0xb5, 0x8c, 0x7c, 0xe5, 0xa5, 0x4c, 0x4f, 0x68, 0xbb, 0xa4, 0x66, 0x9d, + 0x3b, 0x64, 0x7a, 0x42, 0x1e, 0x83, 0x19, 0x47, 0x4a, 0x23, 0xf7, 0x52, 0x21, 0x35, 0xed, 0xf4, + 0x8d, 0xed, 0xd5, 0x3d, 0xb8, 0xbc, 0xe8, 0xb5, 0x37, 0xfe, 0xa3, 0x67, 0x67, 0x8b, 0x2e, 0x54, + 0xf8, 0x50, 0x48, 0x4d, 0x7a, 0xd0, 0x69, 0x26, 0x5e, 0xbe, 0x31, 0x45, 0x9b, 0x57, 0xb3, 0xf6, + 0xc1, 0x44, 0x9e, 0x47, 0x52, 0xf0, 0xc2, 0x7a, 0xba, 0x52, 0xf5, 0x9b, 0x49, 0x11, 0x0a, 0x1d, + 0x3f, 0xce, 0x94, 0x46, 0x49, 0xa1, 0xa4, 0x4d, 0x48, 0x1e, 0xc0, 0xba, 0xc4, 0x34, 0x8e, 0xfc, + 0xd2, 0x03, 0x4f, 0xa1, 0xa6, 0x66, 0xa9, 0x58, 0x9b, 0x49, 0x1f, 0xa1, 0x26, 0x1f, 0x61, 0xd5, + 0xcf, 0x94, 0x16, 0x89, 0x17, 0xb3, 0x31, 0xc6, 0x8a, 0xae, 0xf7, 0x17, 0xb6, 0xcd, 0xd1, 0x53, + 0xfb, 0xfa, 0xd2, 0xd9, 0xf3, 0xb6, 0xd9, 0x6f, 0xca, 0x3d, 0xef, 0xcb, 0x2d, 0xfb, 0x5c, 0xcb, + 0x53, 0xb7, 0xeb, 0xcf, 0xa4, 0xac, 0xd7, 0xb0, 0x39, 0x27, 0x21, 0x1b, 0xb0, 0x70, 0x8c, 0xa7, + 0x95, 0xbf, 0x6e, 0xb1, 0x24, 0xb7, 0x60, 0x29, 0x67, 0x71, 0x56, 0xfb, 0xe8, 0x56, 0xc1, 0x4e, + 0xeb, 0x95, 0x31, 0xf8, 0x66, 0xc0, 0xff, 0x37, 0xfa, 0xaa, 0x54, 0x70, 0x85, 0xe4, 0x05, 0x74, + 0x6a, 0x93, 0xcb, 0x3a, 0xe6, 0xc8, 0xb2, 0xaf, 0xae, 0xa8, 0xdd, 0xa8, 0x8f, 0x2a, 0x85, 0xdb, + 0x48, 0xc9, 0x5b, 0xd8, 0x6c, 0x1e, 0x95, 0x87, 0x27, 0x85, 0x39, 0x28, 0xcb, 0x9e, 0xe6, 0x68, + 0xeb, 0x0f, 0xfb, 0xf7, 0x6b, 0x89, 0xbb, 0x81, 0xbf, 0x65, 0x46, 0xe7, 0x06, 0x2c, 0x37, 0x32, + 0x92, 0x83, 0x39, 0x73, 0x46, 0x72, 0xf7, 0xdf, 0x7f, 0x9a, 0xd5, 0xfb, 0x2b, 0xaf, 0x86, 0x1b, + 0xdc, 0x3f, 0xff, 0xf1, 0xf3, 0x6b, 0xab, 0x3f, 0xd8, 0x72, 0xf2, 0x67, 0xce, 0xb5, 0xd6, 0x69, + 0x84, 0xce, 0x6e, 0x10, 0xec, 0x18, 0x8f, 0xf6, 0xd6, 0x3e, 0x77, 0x67, 0x3f, 0x18, 0xe3, 0x76, + 0xf9, 0xc4, 0x9e, 0xff, 0x0a, 0x00, 0x00, 0xff, 0xff, 0xa2, 0x04, 0x20, 0x41, 0x47, 0x04, 0x00, + 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConnInterface + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion6 + +// ExternalClient is the client API for External service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type ExternalClient interface { + // AddExternal adds external service and adds external exporter. + // It automatically adds a service to inventory, which is running on provided "node_id", + // then adds an "external exporter" agent to inventory, which is running on provided "runs_on_node_id". + AddExternal(ctx context.Context, in *AddExternalRequest, opts ...grpc.CallOption) (*AddExternalResponse, error) +} + +type externalClient struct { + cc grpc.ClientConnInterface +} + +func NewExternalClient(cc grpc.ClientConnInterface) ExternalClient { + return &externalClient{cc} +} + +func (c *externalClient) AddExternal(ctx context.Context, in *AddExternalRequest, opts ...grpc.CallOption) (*AddExternalResponse, error) { + out := new(AddExternalResponse) + err := c.cc.Invoke(ctx, "/management.External/AddExternal", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// ExternalServer is the server API for External service. +type ExternalServer interface { + // AddExternal adds external service and adds external exporter. + // It automatically adds a service to inventory, which is running on provided "node_id", + // then adds an "external exporter" agent to inventory, which is running on provided "runs_on_node_id". + AddExternal(context.Context, *AddExternalRequest) (*AddExternalResponse, error) +} + +// UnimplementedExternalServer can be embedded to have forward compatible implementations. +type UnimplementedExternalServer struct { +} + +func (*UnimplementedExternalServer) AddExternal(ctx context.Context, req *AddExternalRequest) (*AddExternalResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method AddExternal not implemented") +} + +func RegisterExternalServer(s *grpc.Server, srv ExternalServer) { + s.RegisterService(&_External_serviceDesc, srv) +} + +func _External_AddExternal_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AddExternalRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ExternalServer).AddExternal(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/management.External/AddExternal", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ExternalServer).AddExternal(ctx, req.(*AddExternalRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _External_serviceDesc = grpc.ServiceDesc{ + ServiceName: "management.External", + HandlerType: (*ExternalServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "AddExternal", + Handler: _External_AddExternal_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "managementpb/external.proto", +} diff --git a/api/managementpb/external.pb.gw.go b/api/managementpb/external.pb.gw.go new file mode 100644 index 0000000000..489c2f4d10 --- /dev/null +++ b/api/managementpb/external.pb.gw.go @@ -0,0 +1,163 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: managementpb/external.proto + +/* +Package managementpb is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package managementpb + +import ( + "context" + "io" + "net/http" + + "github.com/golang/protobuf/descriptor" + "github.com/golang/protobuf/proto" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/grpc-ecosystem/grpc-gateway/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/status" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = descriptor.ForMessage + +func request_External_AddExternal_0(ctx context.Context, marshaler runtime.Marshaler, client ExternalClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq AddExternalRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.AddExternal(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_External_AddExternal_0(ctx context.Context, marshaler runtime.Marshaler, server ExternalServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq AddExternalRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.AddExternal(ctx, &protoReq) + return msg, metadata, err + +} + +// RegisterExternalHandlerServer registers the http handlers for service External to "mux". +// UnaryRPC :call ExternalServer directly. +// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +func RegisterExternalHandlerServer(ctx context.Context, mux *runtime.ServeMux, server ExternalServer) error { + + mux.Handle("POST", pattern_External_AddExternal_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_External_AddExternal_0(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_External_AddExternal_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +// RegisterExternalHandlerFromEndpoint is same as RegisterExternalHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterExternalHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterExternalHandler(ctx, mux, conn) +} + +// RegisterExternalHandler registers the http handlers for service External to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterExternalHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterExternalHandlerClient(ctx, mux, NewExternalClient(conn)) +} + +// RegisterExternalHandlerClient registers the http handlers for service External +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "ExternalClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "ExternalClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "ExternalClient" to call the correct interceptors. +func RegisterExternalHandlerClient(ctx context.Context, mux *runtime.ServeMux, client ExternalClient) error { + + mux.Handle("POST", pattern_External_AddExternal_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_External_AddExternal_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_External_AddExternal_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_External_AddExternal_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v1", "management", "External", "Add"}, "", runtime.AssumeColonVerbOpt(true))) +) + +var ( + forward_External_AddExternal_0 = runtime.ForwardResponseMessage +) diff --git a/api/managementpb/external.proto b/api/managementpb/external.proto new file mode 100644 index 0000000000..294429640d --- /dev/null +++ b/api/managementpb/external.proto @@ -0,0 +1,75 @@ +syntax = "proto3"; + +package management; + +option go_package = "managementpb"; + +import "github.com/mwitkow/go-proto-validators/validator.proto"; +import "google/api/annotations.proto"; +import "inventorypb/agents.proto"; +import "inventorypb/services.proto"; +import "protoc-gen-swagger/options/annotations.proto"; + +// Add External + +message AddExternalRequest { + // Node identifier on which a external exporter is been running. Required. + string runs_on_node_id = 1 [ + (validator.field) = { + string_not_empty: true + } + ]; + // Unique across all Services user-defined name. Required. + string service_name = 2 [ + (validator.field) = { + string_not_empty: true + } + ]; + // HTTP basic auth username for collecting metrics. + string username = 3; + // HTTP basic auth password for collecting metrics. + string password = 4; + // Scheme to generate URI to exporter metrics endpoints. + string scheme = 5; + // Path under which metrics are exposed, used to generate URI. + string metrics_path = 6; + // Listen port for scraping metrics. + uint32 listen_port = 7 [ + (validator.field) = { + int_gt: 0 + int_lt: 65536 + } + ]; + // Node identifier on which a external service is been running. Required. + string node_id = 8 [ + (validator.field) = { + string_not_empty: true + } + ]; + // Environment name. + string environment = 9; + // Cluster name. + string cluster = 10; + // Replication set name. + string replication_set = 11; + // Custom user-assigned labels for Service. + map custom_labels = 15; +} + +message AddExternalResponse { + inventory.ExternalService service = 1; + inventory.ExternalExporter external_exporter = 2; +} + +// External service provides public Management API methods for External Service. +service External { + // AddExternal adds external service and adds external exporter. + // It automatically adds a service to inventory, which is running on provided "node_id", + // then adds an "external exporter" agent to inventory, which is running on provided "runs_on_node_id". + rpc AddExternal(AddExternalRequest) returns (AddExternalResponse) { + option (google.api.http) = { + post: "/v1/management/External/Add" + body: "*" + }; + } +} diff --git a/api/managementpb/external.validator.pb.go b/api/managementpb/external.validator.pb.go new file mode 100644 index 0000000000..1ae55b6a81 --- /dev/null +++ b/api/managementpb/external.validator.pb.go @@ -0,0 +1,53 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: managementpb/external.proto + +package managementpb + +import ( + fmt "fmt" + proto "github.com/golang/protobuf/proto" + _ "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/options" + _ "github.com/mwitkow/go-proto-validators" + github_com_mwitkow_go_proto_validators "github.com/mwitkow/go-proto-validators" + _ "github.com/percona/pmm/api/inventorypb" + _ "google.golang.org/genproto/googleapis/api/annotations" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +func (this *AddExternalRequest) Validate() error { + if this.RunsOnNodeId == "" { + return github_com_mwitkow_go_proto_validators.FieldError("RunsOnNodeId", fmt.Errorf(`value '%v' must not be an empty string`, this.RunsOnNodeId)) + } + if this.ServiceName == "" { + return github_com_mwitkow_go_proto_validators.FieldError("ServiceName", fmt.Errorf(`value '%v' must not be an empty string`, this.ServiceName)) + } + if !(this.ListenPort > 0) { + return github_com_mwitkow_go_proto_validators.FieldError("ListenPort", fmt.Errorf(`value '%v' must be greater than '0'`, this.ListenPort)) + } + if !(this.ListenPort < 65536) { + return github_com_mwitkow_go_proto_validators.FieldError("ListenPort", fmt.Errorf(`value '%v' must be less than '65536'`, this.ListenPort)) + } + if this.NodeId == "" { + return github_com_mwitkow_go_proto_validators.FieldError("NodeId", fmt.Errorf(`value '%v' must not be an empty string`, this.NodeId)) + } + // Validation of proto3 map<> fields is unsupported. + return nil +} +func (this *AddExternalResponse) Validate() error { + if this.Service != nil { + if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.Service); err != nil { + return github_com_mwitkow_go_proto_validators.FieldError("Service", err) + } + } + if this.ExternalExporter != nil { + if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.ExternalExporter); err != nil { + return github_com_mwitkow_go_proto_validators.FieldError("ExternalExporter", err) + } + } + return nil +} diff --git a/api/managementpb/json/client/external/add_external_parameters.go b/api/managementpb/json/client/external/add_external_parameters.go new file mode 100644 index 0000000000..1332ec5d85 --- /dev/null +++ b/api/managementpb/json/client/external/add_external_parameters.go @@ -0,0 +1,132 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package external + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + "time" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + cr "github.com/go-openapi/runtime/client" + + strfmt "github.com/go-openapi/strfmt" +) + +// NewAddExternalParams creates a new AddExternalParams object +// with the default values initialized. +func NewAddExternalParams() *AddExternalParams { + var () + return &AddExternalParams{ + + timeout: cr.DefaultTimeout, + } +} + +// NewAddExternalParamsWithTimeout creates a new AddExternalParams object +// with the default values initialized, and the ability to set a timeout on a request +func NewAddExternalParamsWithTimeout(timeout time.Duration) *AddExternalParams { + var () + return &AddExternalParams{ + + timeout: timeout, + } +} + +// NewAddExternalParamsWithContext creates a new AddExternalParams object +// with the default values initialized, and the ability to set a context for a request +func NewAddExternalParamsWithContext(ctx context.Context) *AddExternalParams { + var () + return &AddExternalParams{ + + Context: ctx, + } +} + +// NewAddExternalParamsWithHTTPClient creates a new AddExternalParams object +// with the default values initialized, and the ability to set a custom HTTPClient for a request +func NewAddExternalParamsWithHTTPClient(client *http.Client) *AddExternalParams { + var () + return &AddExternalParams{ + HTTPClient: client, + } +} + +/*AddExternalParams contains all the parameters to send to the API endpoint +for the add external operation typically these are written to a http.Request +*/ +type AddExternalParams struct { + + /*Body*/ + Body AddExternalBody + + timeout time.Duration + Context context.Context + HTTPClient *http.Client +} + +// WithTimeout adds the timeout to the add external params +func (o *AddExternalParams) WithTimeout(timeout time.Duration) *AddExternalParams { + o.SetTimeout(timeout) + return o +} + +// SetTimeout adds the timeout to the add external params +func (o *AddExternalParams) SetTimeout(timeout time.Duration) { + o.timeout = timeout +} + +// WithContext adds the context to the add external params +func (o *AddExternalParams) WithContext(ctx context.Context) *AddExternalParams { + o.SetContext(ctx) + return o +} + +// SetContext adds the context to the add external params +func (o *AddExternalParams) SetContext(ctx context.Context) { + o.Context = ctx +} + +// WithHTTPClient adds the HTTPClient to the add external params +func (o *AddExternalParams) WithHTTPClient(client *http.Client) *AddExternalParams { + o.SetHTTPClient(client) + return o +} + +// SetHTTPClient adds the HTTPClient to the add external params +func (o *AddExternalParams) SetHTTPClient(client *http.Client) { + o.HTTPClient = client +} + +// WithBody adds the body to the add external params +func (o *AddExternalParams) WithBody(body AddExternalBody) *AddExternalParams { + o.SetBody(body) + return o +} + +// SetBody adds the body to the add external params +func (o *AddExternalParams) SetBody(body AddExternalBody) { + o.Body = body +} + +// WriteToRequest writes these params to a swagger request +func (o *AddExternalParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error { + + if err := r.SetTimeout(o.timeout); err != nil { + return err + } + var res []error + + if err := r.SetBodyParam(o.Body); err != nil { + return err + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/api/managementpb/json/client/external/add_external_responses.go b/api/managementpb/json/client/external/add_external_responses.go new file mode 100644 index 0000000000..688ae67f6b --- /dev/null +++ b/api/managementpb/json/client/external/add_external_responses.go @@ -0,0 +1,609 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package external + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "fmt" + "io" + "strconv" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + "github.com/go-openapi/swag" + + strfmt "github.com/go-openapi/strfmt" +) + +// AddExternalReader is a Reader for the AddExternal structure. +type AddExternalReader struct { + formats strfmt.Registry +} + +// ReadResponse reads a server response into the received o. +func (o *AddExternalReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) { + switch response.Code() { + case 200: + result := NewAddExternalOK() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return result, nil + default: + result := NewAddExternalDefault(response.Code()) + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + if response.Code()/100 == 2 { + return result, nil + } + return nil, result + } +} + +// NewAddExternalOK creates a AddExternalOK with default headers values +func NewAddExternalOK() *AddExternalOK { + return &AddExternalOK{} +} + +/*AddExternalOK handles this case with default header values. + +A successful response. +*/ +type AddExternalOK struct { + Payload *AddExternalOKBody +} + +func (o *AddExternalOK) Error() string { + return fmt.Sprintf("[POST /v1/management/External/Add][%d] addExternalOk %+v", 200, o.Payload) +} + +func (o *AddExternalOK) GetPayload() *AddExternalOKBody { + return o.Payload +} + +func (o *AddExternalOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(AddExternalOKBody) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} + +// NewAddExternalDefault creates a AddExternalDefault with default headers values +func NewAddExternalDefault(code int) *AddExternalDefault { + return &AddExternalDefault{ + _statusCode: code, + } +} + +/*AddExternalDefault handles this case with default header values. + +An unexpected error response +*/ +type AddExternalDefault struct { + _statusCode int + + Payload *AddExternalDefaultBody +} + +// Code gets the status code for the add external default response +func (o *AddExternalDefault) Code() int { + return o._statusCode +} + +func (o *AddExternalDefault) Error() string { + return fmt.Sprintf("[POST /v1/management/External/Add][%d] AddExternal default %+v", o._statusCode, o.Payload) +} + +func (o *AddExternalDefault) GetPayload() *AddExternalDefaultBody { + return o.Payload +} + +func (o *AddExternalDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(AddExternalDefaultBody) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} + +/*AddExternalBody add external body +swagger:model AddExternalBody +*/ +type AddExternalBody struct { + + // Node identifier on which a external exporter is been running. Required. + RunsOnNodeID string `json:"runs_on_node_id,omitempty"` + + // Unique across all Services user-defined name. Required. + ServiceName string `json:"service_name,omitempty"` + + // HTTP basic auth username for collecting metrics. + Username string `json:"username,omitempty"` + + // HTTP basic auth password for collecting metrics. + Password string `json:"password,omitempty"` + + // Scheme to generate URI to exporter metrics endpoints. + Scheme string `json:"scheme,omitempty"` + + // Path under which metrics are exposed, used to generate URI. + MetricsPath string `json:"metrics_path,omitempty"` + + // Listen port for scraping metrics. + ListenPort int64 `json:"listen_port,omitempty"` + + // Node identifier on which a external service is been running. Required. + NodeID string `json:"node_id,omitempty"` + + // Environment name. + Environment string `json:"environment,omitempty"` + + // Cluster name. + Cluster string `json:"cluster,omitempty"` + + // Replication set name. + ReplicationSet string `json:"replication_set,omitempty"` + + // Custom user-assigned labels for Service. + CustomLabels map[string]string `json:"custom_labels,omitempty"` +} + +// Validate validates this add external body +func (o *AddExternalBody) Validate(formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (o *AddExternalBody) MarshalBinary() ([]byte, error) { + if o == nil { + return nil, nil + } + return swag.WriteJSON(o) +} + +// UnmarshalBinary interface implementation +func (o *AddExternalBody) UnmarshalBinary(b []byte) error { + var res AddExternalBody + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *o = res + return nil +} + +/*AddExternalDefaultBody add external default body +swagger:model AddExternalDefaultBody +*/ +type AddExternalDefaultBody struct { + + // error + Error string `json:"error,omitempty"` + + // code + Code int32 `json:"code,omitempty"` + + // message + Message string `json:"message,omitempty"` + + // details + Details []*DetailsItems0 `json:"details"` +} + +// Validate validates this add external default body +func (o *AddExternalDefaultBody) Validate(formats strfmt.Registry) error { + var res []error + + if err := o.validateDetails(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *AddExternalDefaultBody) validateDetails(formats strfmt.Registry) error { + + if swag.IsZero(o.Details) { // not required + return nil + } + + for i := 0; i < len(o.Details); i++ { + if swag.IsZero(o.Details[i]) { // not required + continue + } + + if o.Details[i] != nil { + if err := o.Details[i].Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("AddExternal default" + "." + "details" + "." + strconv.Itoa(i)) + } + return err + } + } + + } + + return nil +} + +// MarshalBinary interface implementation +func (o *AddExternalDefaultBody) MarshalBinary() ([]byte, error) { + if o == nil { + return nil, nil + } + return swag.WriteJSON(o) +} + +// UnmarshalBinary interface implementation +func (o *AddExternalDefaultBody) UnmarshalBinary(b []byte) error { + var res AddExternalDefaultBody + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *o = res + return nil +} + +/*AddExternalOKBody add external OK body +swagger:model AddExternalOKBody +*/ +type AddExternalOKBody struct { + + // external exporter + ExternalExporter *AddExternalOKBodyExternalExporter `json:"external_exporter,omitempty"` + + // service + Service *AddExternalOKBodyService `json:"service,omitempty"` +} + +// Validate validates this add external OK body +func (o *AddExternalOKBody) Validate(formats strfmt.Registry) error { + var res []error + + if err := o.validateExternalExporter(formats); err != nil { + res = append(res, err) + } + + if err := o.validateService(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *AddExternalOKBody) validateExternalExporter(formats strfmt.Registry) error { + + if swag.IsZero(o.ExternalExporter) { // not required + return nil + } + + if o.ExternalExporter != nil { + if err := o.ExternalExporter.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("addExternalOk" + "." + "external_exporter") + } + return err + } + } + + return nil +} + +func (o *AddExternalOKBody) validateService(formats strfmt.Registry) error { + + if swag.IsZero(o.Service) { // not required + return nil + } + + if o.Service != nil { + if err := o.Service.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("addExternalOk" + "." + "service") + } + return err + } + } + + return nil +} + +// MarshalBinary interface implementation +func (o *AddExternalOKBody) MarshalBinary() ([]byte, error) { + if o == nil { + return nil, nil + } + return swag.WriteJSON(o) +} + +// UnmarshalBinary interface implementation +func (o *AddExternalOKBody) UnmarshalBinary(b []byte) error { + var res AddExternalOKBody + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *o = res + return nil +} + +/*AddExternalOKBodyExternalExporter ExternalExporter runs on any Node type, including Remote Node. +swagger:model AddExternalOKBodyExternalExporter +*/ +type AddExternalOKBodyExternalExporter struct { + + // Unique randomly generated instance identifier. + AgentID string `json:"agent_id,omitempty"` + + // Node identifier where this instance runs. + RunsOnNodeID string `json:"runs_on_node_id,omitempty"` + + // If disabled, metrics from this exporter will not be collected. + Disabled bool `json:"disabled,omitempty"` + + // Service identifier. + ServiceID string `json:"service_id,omitempty"` + + // HTTP basic auth username for collecting metrics. + Username string `json:"username,omitempty"` + + // Scheme to generate URI to exporter metrics endpoints. + Scheme string `json:"scheme,omitempty"` + + // Path under which metrics are exposed, used to generate URI. + MetricsPath string `json:"metrics_path,omitempty"` + + // Custom user-assigned labels. + CustomLabels map[string]string `json:"custom_labels,omitempty"` + + // Listen port for scraping metrics. + ListenPort int64 `json:"listen_port,omitempty"` +} + +// Validate validates this add external OK body external exporter +func (o *AddExternalOKBodyExternalExporter) Validate(formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (o *AddExternalOKBodyExternalExporter) MarshalBinary() ([]byte, error) { + if o == nil { + return nil, nil + } + return swag.WriteJSON(o) +} + +// UnmarshalBinary interface implementation +func (o *AddExternalOKBodyExternalExporter) UnmarshalBinary(b []byte) error { + var res AddExternalOKBodyExternalExporter + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *o = res + return nil +} + +/*AddExternalOKBodyService ExternalService represents a generic External service instance. +swagger:model AddExternalOKBodyService +*/ +type AddExternalOKBodyService struct { + + // Unique randomly generated instance identifier. + ServiceID string `json:"service_id,omitempty"` + + // Unique across all Services user-defined name. + ServiceName string `json:"service_name,omitempty"` + + // Node identifier where this service instance runs. + NodeID string `json:"node_id,omitempty"` + + // Environment name. + Environment string `json:"environment,omitempty"` + + // Cluster name. + Cluster string `json:"cluster,omitempty"` + + // Replication set name. + ReplicationSet string `json:"replication_set,omitempty"` + + // Custom user-assigned labels. + CustomLabels map[string]string `json:"custom_labels,omitempty"` +} + +// Validate validates this add external OK body service +func (o *AddExternalOKBodyService) Validate(formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (o *AddExternalOKBodyService) MarshalBinary() ([]byte, error) { + if o == nil { + return nil, nil + } + return swag.WriteJSON(o) +} + +// UnmarshalBinary interface implementation +func (o *AddExternalOKBodyService) UnmarshalBinary(b []byte) error { + var res AddExternalOKBodyService + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *o = res + return nil +} + +/*DetailsItems0 `Any` contains an arbitrary serialized protocol buffer message along with a +// URL that describes the type of the serialized message. +// +// Protobuf library provides support to pack/unpack Any values in the form +// of utility functions or additional generated methods of the Any type. +// +// Example 1: Pack and unpack a message in C++. +// +// Foo foo = ...; +// Any any; +// any.PackFrom(foo); +// ... +// if (any.UnpackTo(&foo)) { +// ... +// } +// +// Example 2: Pack and unpack a message in Java. +// +// Foo foo = ...; +// Any any = Any.pack(foo); +// ... +// if (any.is(Foo.class)) { +// foo = any.unpack(Foo.class); +// } +// +// Example 3: Pack and unpack a message in Python. +// +// foo = Foo(...) +// any = Any() +// any.Pack(foo) +// ... +// if any.Is(Foo.DESCRIPTOR): +// any.Unpack(foo) +// ... +// +// Example 4: Pack and unpack a message in Go +// +// foo := &pb.Foo{...} +// any, err := ptypes.MarshalAny(foo) +// ... +// foo := &pb.Foo{} +// if err := ptypes.UnmarshalAny(any, foo); err != nil { +// ... +// } +// +// The pack methods provided by protobuf library will by default use +// 'type.googleapis.com/full.type.name' as the type URL and the unpack +// methods only use the fully qualified type name after the last '/' +// in the type URL, for example "foo.bar.com/x/y.z" will yield type +// name "y.z". +// +// +// JSON +// ==== +// The JSON representation of an `Any` value uses the regular +// representation of the deserialized, embedded message, with an +// additional field `@type` which contains the type URL. Example: +// +// package google.profile; +// message Person { +// string first_name = 1; +// string last_name = 2; +// } +// +// { +// "@type": "type.googleapis.com/google.profile.Person", +// "firstName": , +// "lastName": +// } +// +// If the embedded message type is well-known and has a custom JSON +// representation, that representation will be embedded adding a field +// `value` which holds the custom JSON in addition to the `@type` +// field. Example (for message [google.protobuf.Duration][]): +// +// { +// "@type": "type.googleapis.com/google.protobuf.Duration", +// "value": "1.212s" +// } +swagger:model DetailsItems0 +*/ +type DetailsItems0 struct { + + // A URL/resource name that uniquely identifies the type of the serialized + // protocol buffer message. This string must contain at least + // one "/" character. The last segment of the URL's path must represent + // the fully qualified name of the type (as in + // `path/google.protobuf.Duration`). The name should be in a canonical form + // (e.g., leading "." is not accepted). + // + // In practice, teams usually precompile into the binary all types that they + // expect it to use in the context of Any. However, for URLs which use the + // scheme `http`, `https`, or no scheme, one can optionally set up a type + // server that maps type URLs to message definitions as follows: + // + // * If no scheme is provided, `https` is assumed. + // * An HTTP GET on the URL must yield a [google.protobuf.Type][] + // value in binary format, or produce an error. + // * Applications are allowed to cache lookup results based on the + // URL, or have them precompiled into a binary to avoid any + // lookup. Therefore, binary compatibility needs to be preserved + // on changes to types. (Use versioned type names to manage + // breaking changes.) + // + // Note: this functionality is not currently available in the official + // protobuf release, and it is not used for type URLs beginning with + // type.googleapis.com. + // + // Schemes other than `http`, `https` (or the empty scheme) might be + // used with implementation specific semantics. + TypeURL string `json:"type_url,omitempty"` + + // Must be a valid serialized protocol buffer of the above specified type. + // Format: byte + Value strfmt.Base64 `json:"value,omitempty"` +} + +// Validate validates this details items0 +func (o *DetailsItems0) Validate(formats strfmt.Registry) error { + var res []error + + if err := o.validateValue(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *DetailsItems0) validateValue(formats strfmt.Registry) error { + + if swag.IsZero(o.Value) { // not required + return nil + } + + // Format "byte" (base64 string) is already validated when unmarshalled + + return nil +} + +// MarshalBinary interface implementation +func (o *DetailsItems0) MarshalBinary() ([]byte, error) { + if o == nil { + return nil, nil + } + return swag.WriteJSON(o) +} + +// UnmarshalBinary interface implementation +func (o *DetailsItems0) UnmarshalBinary(b []byte) error { + var res DetailsItems0 + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *o = res + return nil +} diff --git a/api/managementpb/json/client/external/external_client.go b/api/managementpb/json/client/external/external_client.go new file mode 100644 index 0000000000..361aeb5478 --- /dev/null +++ b/api/managementpb/json/client/external/external_client.go @@ -0,0 +1,63 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package external + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "github.com/go-openapi/runtime" + + strfmt "github.com/go-openapi/strfmt" +) + +// New creates a new external API client. +func New(transport runtime.ClientTransport, formats strfmt.Registry) *Client { + return &Client{transport: transport, formats: formats} +} + +/* +Client for external API +*/ +type Client struct { + transport runtime.ClientTransport + formats strfmt.Registry +} + +/* +AddExternal adds external adds external service and adds external exporter it automatically adds a service to inventory which is running on provided node id then adds an external exporter agent to inventory which is running on provided runs on node id +*/ +func (a *Client) AddExternal(params *AddExternalParams) (*AddExternalOK, error) { + // TODO: Validate the params before sending + if params == nil { + params = NewAddExternalParams() + } + + result, err := a.transport.Submit(&runtime.ClientOperation{ + ID: "AddExternal", + Method: "POST", + PathPattern: "/v1/management/External/Add", + ProducesMediaTypes: []string{"application/json"}, + ConsumesMediaTypes: []string{"application/json"}, + Schemes: []string{"http", "https"}, + Params: params, + Reader: &AddExternalReader{formats: a.formats}, + Context: params.Context, + Client: params.HTTPClient, + }) + if err != nil { + return nil, err + } + success, ok := result.(*AddExternalOK) + if ok { + return success, nil + } + // unexpected success response + unexpectedSuccess := result.(*AddExternalDefault) + return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) +} + +// SetTransport changes the transport on the client +func (a *Client) SetTransport(transport runtime.ClientTransport) { + a.transport = transport +} diff --git a/api/managementpb/json/client/pmm_management_client.go b/api/managementpb/json/client/pmm_management_client.go index 3c373946b4..fb8324c597 100644 --- a/api/managementpb/json/client/pmm_management_client.go +++ b/api/managementpb/json/client/pmm_management_client.go @@ -13,6 +13,7 @@ import ( "github.com/percona/pmm/api/managementpb/json/client/actions" "github.com/percona/pmm/api/managementpb/json/client/annotation" + "github.com/percona/pmm/api/managementpb/json/client/external" "github.com/percona/pmm/api/managementpb/json/client/mongo_db" "github.com/percona/pmm/api/managementpb/json/client/my_sql" "github.com/percona/pmm/api/managementpb/json/client/node" @@ -69,6 +70,8 @@ func New(transport runtime.ClientTransport, formats strfmt.Registry) *PMMManagem cli.Annotation = annotation.New(transport, formats) + cli.External = external.New(transport, formats) + cli.MongoDB = mongo_db.New(transport, formats) cli.MySQL = my_sql.New(transport, formats) @@ -131,6 +134,8 @@ type PMMManagement struct { Annotation *annotation.Client + External *external.Client + MongoDB *mongo_db.Client MySQL *my_sql.Client @@ -156,6 +161,8 @@ func (c *PMMManagement) SetTransport(transport runtime.ClientTransport) { c.Annotation.SetTransport(transport) + c.External.SetTransport(transport) + c.MongoDB.SetTransport(transport) c.MySQL.SetTransport(transport) diff --git a/api/managementpb/json/managementpb.json b/api/managementpb/json/managementpb.json index ce60a68127..aa9dcdbfcb 100644 --- a/api/managementpb/json/managementpb.json +++ b/api/managementpb/json/managementpb.json @@ -1202,6 +1202,245 @@ } } }, + "/v1/management/External/Add": { + "post": { + "tags": [ + "External" + ], + "summary": "AddExternal adds external service and adds external exporter.\nIt automatically adds a service to inventory, which is running on provided \"node_id\",\nthen adds an \"external exporter\" agent to inventory, which is running on provided \"runs_on_node_id\".", + "operationId": "AddExternal", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "cluster": { + "description": "Cluster name.", + "type": "string", + "x-order": 9 + }, + "custom_labels": { + "description": "Custom user-assigned labels for Service.", + "type": "object", + "additionalProperties": { + "type": "string" + }, + "x-order": 11 + }, + "environment": { + "description": "Environment name.", + "type": "string", + "x-order": 8 + }, + "listen_port": { + "description": "Listen port for scraping metrics.", + "type": "integer", + "format": "int64", + "x-order": 6 + }, + "metrics_path": { + "description": "Path under which metrics are exposed, used to generate URI.", + "type": "string", + "x-order": 5 + }, + "node_id": { + "description": "Node identifier on which a external service is been running. Required.", + "type": "string", + "x-order": 7 + }, + "password": { + "description": "HTTP basic auth password for collecting metrics.", + "type": "string", + "x-order": 3 + }, + "replication_set": { + "description": "Replication set name.", + "type": "string", + "x-order": 10 + }, + "runs_on_node_id": { + "description": "Node identifier on which a external exporter is been running. Required.", + "type": "string", + "x-order": 0 + }, + "scheme": { + "description": "Scheme to generate URI to exporter metrics endpoints.", + "type": "string", + "x-order": 4 + }, + "service_name": { + "description": "Unique across all Services user-defined name. Required.", + "type": "string", + "x-order": 1 + }, + "username": { + "description": "HTTP basic auth username for collecting metrics.", + "type": "string", + "x-order": 2 + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "type": "object", + "properties": { + "external_exporter": { + "description": "ExternalExporter runs on any Node type, including Remote Node.", + "type": "object", + "properties": { + "agent_id": { + "description": "Unique randomly generated instance identifier.", + "type": "string", + "x-order": 0 + }, + "custom_labels": { + "description": "Custom user-assigned labels.", + "type": "object", + "additionalProperties": { + "type": "string" + }, + "x-order": 7 + }, + "disabled": { + "description": "If disabled, metrics from this exporter will not be collected.", + "type": "boolean", + "format": "boolean", + "x-order": 2 + }, + "listen_port": { + "description": "Listen port for scraping metrics.", + "type": "integer", + "format": "int64", + "x-order": 8 + }, + "metrics_path": { + "description": "Path under which metrics are exposed, used to generate URI.", + "type": "string", + "x-order": 6 + }, + "runs_on_node_id": { + "description": "Node identifier where this instance runs.", + "type": "string", + "x-order": 1 + }, + "scheme": { + "description": "Scheme to generate URI to exporter metrics endpoints.", + "type": "string", + "x-order": 5 + }, + "service_id": { + "description": "Service identifier.", + "type": "string", + "x-order": 3 + }, + "username": { + "description": "HTTP basic auth username for collecting metrics.", + "type": "string", + "x-order": 4 + } + }, + "x-order": 1 + }, + "service": { + "description": "ExternalService represents a generic External service instance.", + "type": "object", + "properties": { + "cluster": { + "description": "Cluster name.", + "type": "string", + "x-order": 4 + }, + "custom_labels": { + "description": "Custom user-assigned labels.", + "type": "object", + "additionalProperties": { + "type": "string" + }, + "x-order": 6 + }, + "environment": { + "description": "Environment name.", + "type": "string", + "x-order": 3 + }, + "node_id": { + "description": "Node identifier where this service instance runs.", + "type": "string", + "x-order": 2 + }, + "replication_set": { + "description": "Replication set name.", + "type": "string", + "x-order": 5 + }, + "service_id": { + "description": "Unique randomly generated instance identifier.", + "type": "string", + "x-order": 0 + }, + "service_name": { + "description": "Unique across all Services user-defined name.", + "type": "string", + "x-order": 1 + } + }, + "x-order": 0 + } + } + } + }, + "default": { + "description": "An unexpected error response", + "schema": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32", + "x-order": 1 + }, + "details": { + "type": "array", + "items": { + "description": "`Any` contains an arbitrary serialized protocol buffer message along with a\nURL that describes the type of the serialized message.\n\nProtobuf library provides support to pack/unpack Any values in the form\nof utility functions or additional generated methods of the Any type.\n\nExample 1: Pack and unpack a message in C++.\n\n Foo foo = ...;\n Any any;\n any.PackFrom(foo);\n ...\n if (any.UnpackTo(\u0026foo)) {\n ...\n }\n\nExample 2: Pack and unpack a message in Java.\n\n Foo foo = ...;\n Any any = Any.pack(foo);\n ...\n if (any.is(Foo.class)) {\n foo = any.unpack(Foo.class);\n }\n\n Example 3: Pack and unpack a message in Python.\n\n foo = Foo(...)\n any = Any()\n any.Pack(foo)\n ...\n if any.Is(Foo.DESCRIPTOR):\n any.Unpack(foo)\n ...\n\n Example 4: Pack and unpack a message in Go\n\n foo := \u0026pb.Foo{...}\n any, err := ptypes.MarshalAny(foo)\n ...\n foo := \u0026pb.Foo{}\n if err := ptypes.UnmarshalAny(any, foo); err != nil {\n ...\n }\n\nThe pack methods provided by protobuf library will by default use\n'type.googleapis.com/full.type.name' as the type URL and the unpack\nmethods only use the fully qualified type name after the last '/'\nin the type URL, for example \"foo.bar.com/x/y.z\" will yield type\nname \"y.z\".\n\n\nJSON\n====\nThe JSON representation of an `Any` value uses the regular\nrepresentation of the deserialized, embedded message, with an\nadditional field `@type` which contains the type URL. Example:\n\n package google.profile;\n message Person {\n string first_name = 1;\n string last_name = 2;\n }\n\n {\n \"@type\": \"type.googleapis.com/google.profile.Person\",\n \"firstName\": \u003cstring\u003e,\n \"lastName\": \u003cstring\u003e\n }\n\nIf the embedded message type is well-known and has a custom JSON\nrepresentation, that representation will be embedded adding a field\n`value` which holds the custom JSON in addition to the `@type`\nfield. Example (for message [google.protobuf.Duration][]):\n\n {\n \"@type\": \"type.googleapis.com/google.protobuf.Duration\",\n \"value\": \"1.212s\"\n }", + "type": "object", + "properties": { + "type_url": { + "description": "A URL/resource name that uniquely identifies the type of the serialized\nprotocol buffer message. This string must contain at least\none \"/\" character. The last segment of the URL's path must represent\nthe fully qualified name of the type (as in\n`path/google.protobuf.Duration`). The name should be in a canonical form\n(e.g., leading \".\" is not accepted).\n\nIn practice, teams usually precompile into the binary all types that they\nexpect it to use in the context of Any. However, for URLs which use the\nscheme `http`, `https`, or no scheme, one can optionally set up a type\nserver that maps type URLs to message definitions as follows:\n\n* If no scheme is provided, `https` is assumed.\n* An HTTP GET on the URL must yield a [google.protobuf.Type][]\n value in binary format, or produce an error.\n* Applications are allowed to cache lookup results based on the\n URL, or have them precompiled into a binary to avoid any\n lookup. Therefore, binary compatibility needs to be preserved\n on changes to types. (Use versioned type names to manage\n breaking changes.)\n\nNote: this functionality is not currently available in the official\nprotobuf release, and it is not used for type URLs beginning with\ntype.googleapis.com.\n\nSchemes other than `http`, `https` (or the empty scheme) might be\nused with implementation specific semantics.", + "type": "string", + "x-order": 0 + }, + "value": { + "description": "Must be a valid serialized protocol buffer of the above specified type.", + "type": "string", + "format": "byte", + "x-order": 1 + } + } + }, + "x-order": 3 + }, + "error": { + "type": "string", + "x-order": 0 + }, + "message": { + "type": "string", + "x-order": 2 + } + } + } + } + } + } + }, "/v1/management/MongoDB/Add": { "post": { "tags": [ diff --git a/api/swagger/swagger.json b/api/swagger/swagger.json index 052bb99663..f4384c05aa 100644 --- a/api/swagger/swagger.json +++ b/api/swagger/swagger.json @@ -11077,6 +11077,245 @@ } } }, + "/v1/management/External/Add": { + "post": { + "tags": [ + "External" + ], + "summary": "AddExternal adds external service and adds external exporter.\nIt automatically adds a service to inventory, which is running on provided \"node_id\",\nthen adds an \"external exporter\" agent to inventory, which is running on provided \"runs_on_node_id\".", + "operationId": "AddExternal", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "runs_on_node_id": { + "description": "Node identifier on which a external exporter is been running. Required.", + "type": "string", + "x-order": 0 + }, + "service_name": { + "description": "Unique across all Services user-defined name. Required.", + "type": "string", + "x-order": 1 + }, + "username": { + "description": "HTTP basic auth username for collecting metrics.", + "type": "string", + "x-order": 2 + }, + "password": { + "description": "HTTP basic auth password for collecting metrics.", + "type": "string", + "x-order": 3 + }, + "scheme": { + "description": "Scheme to generate URI to exporter metrics endpoints.", + "type": "string", + "x-order": 4 + }, + "metrics_path": { + "description": "Path under which metrics are exposed, used to generate URI.", + "type": "string", + "x-order": 5 + }, + "listen_port": { + "description": "Listen port for scraping metrics.", + "type": "integer", + "format": "int64", + "x-order": 6 + }, + "node_id": { + "description": "Node identifier on which a external service is been running. Required.", + "type": "string", + "x-order": 7 + }, + "environment": { + "description": "Environment name.", + "type": "string", + "x-order": 8 + }, + "cluster": { + "description": "Cluster name.", + "type": "string", + "x-order": 9 + }, + "replication_set": { + "description": "Replication set name.", + "type": "string", + "x-order": 10 + }, + "custom_labels": { + "description": "Custom user-assigned labels for Service.", + "type": "object", + "additionalProperties": { + "type": "string" + }, + "x-order": 11 + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "type": "object", + "properties": { + "service": { + "description": "ExternalService represents a generic External service instance.", + "type": "object", + "properties": { + "service_id": { + "description": "Unique randomly generated instance identifier.", + "type": "string", + "x-order": 0 + }, + "service_name": { + "description": "Unique across all Services user-defined name.", + "type": "string", + "x-order": 1 + }, + "node_id": { + "description": "Node identifier where this service instance runs.", + "type": "string", + "x-order": 2 + }, + "environment": { + "description": "Environment name.", + "type": "string", + "x-order": 3 + }, + "cluster": { + "description": "Cluster name.", + "type": "string", + "x-order": 4 + }, + "replication_set": { + "description": "Replication set name.", + "type": "string", + "x-order": 5 + }, + "custom_labels": { + "description": "Custom user-assigned labels.", + "type": "object", + "additionalProperties": { + "type": "string" + }, + "x-order": 6 + } + }, + "x-order": 0 + }, + "external_exporter": { + "description": "ExternalExporter runs on any Node type, including Remote Node.", + "type": "object", + "properties": { + "agent_id": { + "description": "Unique randomly generated instance identifier.", + "type": "string", + "x-order": 0 + }, + "runs_on_node_id": { + "description": "Node identifier where this instance runs.", + "type": "string", + "x-order": 1 + }, + "disabled": { + "description": "If disabled, metrics from this exporter will not be collected.", + "type": "boolean", + "format": "boolean", + "x-order": 2 + }, + "service_id": { + "description": "Service identifier.", + "type": "string", + "x-order": 3 + }, + "username": { + "description": "HTTP basic auth username for collecting metrics.", + "type": "string", + "x-order": 4 + }, + "scheme": { + "description": "Scheme to generate URI to exporter metrics endpoints.", + "type": "string", + "x-order": 5 + }, + "metrics_path": { + "description": "Path under which metrics are exposed, used to generate URI.", + "type": "string", + "x-order": 6 + }, + "custom_labels": { + "description": "Custom user-assigned labels.", + "type": "object", + "additionalProperties": { + "type": "string" + }, + "x-order": 7 + }, + "listen_port": { + "description": "Listen port for scraping metrics.", + "type": "integer", + "format": "int64", + "x-order": 8 + } + }, + "x-order": 1 + } + } + } + }, + "default": { + "description": "An unexpected error response", + "schema": { + "type": "object", + "properties": { + "error": { + "type": "string", + "x-order": 0 + }, + "code": { + "type": "integer", + "format": "int32", + "x-order": 1 + }, + "message": { + "type": "string", + "x-order": 2 + }, + "details": { + "type": "array", + "items": { + "description": "`Any` contains an arbitrary serialized protocol buffer message along with a\nURL that describes the type of the serialized message.\n\nProtobuf library provides support to pack/unpack Any values in the form\nof utility functions or additional generated methods of the Any type.\n\nExample 1: Pack and unpack a message in C++.\n\n Foo foo = ...;\n Any any;\n any.PackFrom(foo);\n ...\n if (any.UnpackTo(\u0026foo)) {\n ...\n }\n\nExample 2: Pack and unpack a message in Java.\n\n Foo foo = ...;\n Any any = Any.pack(foo);\n ...\n if (any.is(Foo.class)) {\n foo = any.unpack(Foo.class);\n }\n\n Example 3: Pack and unpack a message in Python.\n\n foo = Foo(...)\n any = Any()\n any.Pack(foo)\n ...\n if any.Is(Foo.DESCRIPTOR):\n any.Unpack(foo)\n ...\n\n Example 4: Pack and unpack a message in Go\n\n foo := \u0026pb.Foo{...}\n any, err := ptypes.MarshalAny(foo)\n ...\n foo := \u0026pb.Foo{}\n if err := ptypes.UnmarshalAny(any, foo); err != nil {\n ...\n }\n\nThe pack methods provided by protobuf library will by default use\n'type.googleapis.com/full.type.name' as the type URL and the unpack\nmethods only use the fully qualified type name after the last '/'\nin the type URL, for example \"foo.bar.com/x/y.z\" will yield type\nname \"y.z\".\n\n\nJSON\n====\nThe JSON representation of an `Any` value uses the regular\nrepresentation of the deserialized, embedded message, with an\nadditional field `@type` which contains the type URL. Example:\n\n package google.profile;\n message Person {\n string first_name = 1;\n string last_name = 2;\n }\n\n {\n \"@type\": \"type.googleapis.com/google.profile.Person\",\n \"firstName\": \u003cstring\u003e,\n \"lastName\": \u003cstring\u003e\n }\n\nIf the embedded message type is well-known and has a custom JSON\nrepresentation, that representation will be embedded adding a field\n`value` which holds the custom JSON in addition to the `@type`\nfield. Example (for message [google.protobuf.Duration][]):\n\n {\n \"@type\": \"type.googleapis.com/google.protobuf.Duration\",\n \"value\": \"1.212s\"\n }", + "type": "object", + "properties": { + "type_url": { + "description": "A URL/resource name that uniquely identifies the type of the serialized\nprotocol buffer message. This string must contain at least\none \"/\" character. The last segment of the URL's path must represent\nthe fully qualified name of the type (as in\n`path/google.protobuf.Duration`). The name should be in a canonical form\n(e.g., leading \".\" is not accepted).\n\nIn practice, teams usually precompile into the binary all types that they\nexpect it to use in the context of Any. However, for URLs which use the\nscheme `http`, `https`, or no scheme, one can optionally set up a type\nserver that maps type URLs to message definitions as follows:\n\n* If no scheme is provided, `https` is assumed.\n* An HTTP GET on the URL must yield a [google.protobuf.Type][]\n value in binary format, or produce an error.\n* Applications are allowed to cache lookup results based on the\n URL, or have them precompiled into a binary to avoid any\n lookup. Therefore, binary compatibility needs to be preserved\n on changes to types. (Use versioned type names to manage\n breaking changes.)\n\nNote: this functionality is not currently available in the official\nprotobuf release, and it is not used for type URLs beginning with\ntype.googleapis.com.\n\nSchemes other than `http`, `https` (or the empty scheme) might be\nused with implementation specific semantics.", + "type": "string", + "x-order": 0 + }, + "value": { + "description": "Must be a valid serialized protocol buffer of the above specified type.", + "type": "string", + "format": "byte", + "x-order": 1 + } + } + }, + "x-order": 3 + } + } + } + } + } + } + }, "/v1/management/MongoDB/Add": { "post": { "tags": [