diff --git a/management/internals/modules/reverseproxy/accesslogs/accesslogentry.go b/management/internals/modules/reverseproxy/accesslogs/accesslogentry.go index 1101dc681..019cb634a 100644 --- a/management/internals/modules/reverseproxy/accesslogs/accesslogentry.go +++ b/management/internals/modules/reverseproxy/accesslogs/accesslogentry.go @@ -13,7 +13,7 @@ import ( type AccessLogEntry struct { ID string `gorm:"primaryKey"` AccountID string `gorm:"index"` - ProxyID string `gorm:"index"` + ServiceID string `gorm:"index"` Timestamp time.Time `gorm:"index"` GeoLocation peer.Location `gorm:"embedded;embeddedPrefix:location_"` Method string `gorm:"index"` @@ -27,28 +27,28 @@ type AccessLogEntry struct { } // FromProto creates an AccessLogEntry from a proto.AccessLog -func (a *AccessLogEntry) FromProto(proxyLog *proto.AccessLog) { - a.ID = proxyLog.GetLogId() - a.ProxyID = proxyLog.GetServiceId() - a.Timestamp = proxyLog.GetTimestamp().AsTime() - a.Method = proxyLog.GetMethod() - a.Host = proxyLog.GetHost() - a.Path = proxyLog.GetPath() - a.Duration = time.Duration(proxyLog.GetDurationMs()) * time.Millisecond - a.StatusCode = int(proxyLog.GetResponseCode()) - a.UserId = proxyLog.GetUserId() - a.AuthMethodUsed = proxyLog.GetAuthMechanism() - a.AccountID = proxyLog.GetAccountId() +func (a *AccessLogEntry) FromProto(serviceLog *proto.AccessLog) { + a.ID = serviceLog.GetLogId() + a.ServiceID = serviceLog.GetServiceId() + a.Timestamp = serviceLog.GetTimestamp().AsTime() + a.Method = serviceLog.GetMethod() + a.Host = serviceLog.GetHost() + a.Path = serviceLog.GetPath() + a.Duration = time.Duration(serviceLog.GetDurationMs()) * time.Millisecond + a.StatusCode = int(serviceLog.GetResponseCode()) + a.UserId = serviceLog.GetUserId() + a.AuthMethodUsed = serviceLog.GetAuthMechanism() + a.AccountID = serviceLog.GetAccountId() - if sourceIP := proxyLog.GetSourceIp(); sourceIP != "" { + if sourceIP := serviceLog.GetSourceIp(); sourceIP != "" { if ip, err := netip.ParseAddr(sourceIP); err == nil { a.GeoLocation.ConnectionIP = net.IP(ip.AsSlice()) } } - if !proxyLog.GetAuthSuccess() { + if !serviceLog.GetAuthSuccess() { a.Reason = "Authentication failed" - } else if proxyLog.GetResponseCode() >= 400 { + } else if serviceLog.GetResponseCode() >= 400 { a.Reason = "Request failed" } } @@ -88,7 +88,7 @@ func (a *AccessLogEntry) ToAPIResponse() *api.ProxyAccessLog { return &api.ProxyAccessLog{ Id: a.ID, - ProxyId: a.ProxyID, + ServiceId: a.ServiceID, Timestamp: a.Timestamp, Method: a.Method, Host: a.Host, diff --git a/management/internals/modules/reverseproxy/accesslogs/manager/manager.go b/management/internals/modules/reverseproxy/accesslogs/manager/manager.go index 369b53547..7bcdecb1b 100644 --- a/management/internals/modules/reverseproxy/accesslogs/manager/manager.go +++ b/management/internals/modules/reverseproxy/accesslogs/manager/manager.go @@ -44,11 +44,11 @@ func (m *managerImpl) SaveAccessLog(ctx context.Context, logEntry *accesslogs.Ac if err := m.store.CreateAccessLog(ctx, logEntry); err != nil { log.WithContext(ctx).WithFields(log.Fields{ - "proxy_id": logEntry.ProxyID, - "method": logEntry.Method, - "host": logEntry.Host, - "path": logEntry.Path, - "status": logEntry.StatusCode, + "service_id": logEntry.ServiceID, + "method": logEntry.Method, + "host": logEntry.Host, + "path": logEntry.Path, + "status": logEntry.StatusCode, }).Errorf("failed to save access log: %v", err) return err } diff --git a/management/internals/modules/reverseproxy/interface.go b/management/internals/modules/reverseproxy/interface.go index 83064e2c6..0b6741055 100644 --- a/management/internals/modules/reverseproxy/interface.go +++ b/management/internals/modules/reverseproxy/interface.go @@ -5,17 +5,17 @@ import ( ) type Manager interface { - GetAllReverseProxies(ctx context.Context, accountID, userID string) ([]*ReverseProxy, error) - GetReverseProxy(ctx context.Context, accountID, userID, reverseProxyID string) (*ReverseProxy, error) - CreateReverseProxy(ctx context.Context, accountID, userID string, reverseProxy *ReverseProxy) (*ReverseProxy, error) - UpdateReverseProxy(ctx context.Context, accountID, userID string, reverseProxy *ReverseProxy) (*ReverseProxy, error) - DeleteReverseProxy(ctx context.Context, accountID, userID, reverseProxyID string) error - SetCertificateIssuedAt(ctx context.Context, accountID, reverseProxyID string) error - SetStatus(ctx context.Context, accountID, reverseProxyID string, status ProxyStatus) error - ReloadAllReverseProxiesForAccount(ctx context.Context, accountID string) error - ReloadReverseProxy(ctx context.Context, accountID, reverseProxyID string) error - GetGlobalReverseProxies(ctx context.Context) ([]*ReverseProxy, error) - GetProxyByID(ctx context.Context, accountID, reverseProxyID string) (*ReverseProxy, error) - GetAccountReverseProxies(ctx context.Context, accountID string) ([]*ReverseProxy, error) - GetProxyIDByTargetID(ctx context.Context, accountID string, resourceID string) (string, error) + GetAllServices(ctx context.Context, accountID, userID string) ([]*Service, error) + GetService(ctx context.Context, accountID, userID, serviceID string) (*Service, error) + CreateService(ctx context.Context, accountID, userID string, service *Service) (*Service, error) + UpdateService(ctx context.Context, accountID, userID string, service *Service) (*Service, error) + DeleteService(ctx context.Context, accountID, userID, serviceID string) error + SetCertificateIssuedAt(ctx context.Context, accountID, serviceID string) error + SetStatus(ctx context.Context, accountID, serviceID string, status ProxyStatus) error + ReloadAllServicesForAccount(ctx context.Context, accountID string) error + ReloadService(ctx context.Context, accountID, serviceID string) error + GetGlobalServices(ctx context.Context) ([]*Service, error) + GetServiceByID(ctx context.Context, accountID, serviceID string) (*Service, error) + GetAccountServices(ctx context.Context, accountID string) ([]*Service, error) + GetServiceIDByTargetID(ctx context.Context, accountID string, resourceID string) (string, error) } diff --git a/management/internals/modules/reverseproxy/manager/api.go b/management/internals/modules/reverseproxy/manager/api.go index 990f775b4..92f54faca 100644 --- a/management/internals/modules/reverseproxy/manager/api.go +++ b/management/internals/modules/reverseproxy/manager/api.go @@ -20,148 +20,148 @@ type handler struct { manager reverseproxy.Manager } -// RegisterEndpoints registers all reverse proxy HTTP endpoints. +// RegisterEndpoints registers all service HTTP endpoints. func RegisterEndpoints(manager reverseproxy.Manager, domainManager domain.Manager, accessLogsManager accesslogs.Manager, router *mux.Router) { h := &handler{ manager: manager, } - domainRouter := router.PathPrefix("/reverse-proxies").Subrouter() + domainRouter := router.PathPrefix("/services").Subrouter() domain.RegisterEndpoints(domainRouter, domainManager) accesslogsmanager.RegisterEndpoints(router, accessLogsManager) - router.HandleFunc("/reverse-proxies", h.getAllReverseProxies).Methods("GET", "OPTIONS") - router.HandleFunc("/reverse-proxies", h.createReverseProxy).Methods("POST", "OPTIONS") - router.HandleFunc("/reverse-proxies/{proxyId}", h.getReverseProxy).Methods("GET", "OPTIONS") - router.HandleFunc("/reverse-proxies/{proxyId}", h.updateReverseProxy).Methods("PUT", "OPTIONS") - router.HandleFunc("/reverse-proxies/{proxyId}", h.deleteReverseProxy).Methods("DELETE", "OPTIONS") + router.HandleFunc("/services", h.getAllServices).Methods("GET", "OPTIONS") + router.HandleFunc("/services", h.createService).Methods("POST", "OPTIONS") + router.HandleFunc("/services/{serviceId}", h.getService).Methods("GET", "OPTIONS") + router.HandleFunc("/services/{serviceId}", h.updateService).Methods("PUT", "OPTIONS") + router.HandleFunc("/services/{serviceId}", h.deleteService).Methods("DELETE", "OPTIONS") } -func (h *handler) getAllReverseProxies(w http.ResponseWriter, r *http.Request) { +func (h *handler) getAllServices(w http.ResponseWriter, r *http.Request) { userAuth, err := nbcontext.GetUserAuthFromContext(r.Context()) if err != nil { util.WriteError(r.Context(), err, w) return } - allReverseProxies, err := h.manager.GetAllReverseProxies(r.Context(), userAuth.AccountId, userAuth.UserId) + allServices, err := h.manager.GetAllServices(r.Context(), userAuth.AccountId, userAuth.UserId) if err != nil { util.WriteError(r.Context(), err, w) return } - apiReverseProxies := make([]*api.ReverseProxy, 0, len(allReverseProxies)) - for _, reverseProxy := range allReverseProxies { - apiReverseProxies = append(apiReverseProxies, reverseProxy.ToAPIResponse()) + apiServices := make([]*api.Service, 0, len(allServices)) + for _, service := range allServices { + apiServices = append(apiServices, service.ToAPIResponse()) } - util.WriteJSONObject(r.Context(), w, apiReverseProxies) + util.WriteJSONObject(r.Context(), w, apiServices) } -func (h *handler) createReverseProxy(w http.ResponseWriter, r *http.Request) { +func (h *handler) createService(w http.ResponseWriter, r *http.Request) { userAuth, err := nbcontext.GetUserAuthFromContext(r.Context()) if err != nil { util.WriteError(r.Context(), err, w) return } - var req api.ReverseProxyRequest + var req api.ServiceRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { util.WriteErrorResponse("couldn't parse JSON request", http.StatusBadRequest, w) return } - reverseProxy := new(reverseproxy.ReverseProxy) - reverseProxy.FromAPIRequest(&req, userAuth.AccountId) + service := new(reverseproxy.Service) + service.FromAPIRequest(&req, userAuth.AccountId) - if err = reverseProxy.Validate(); err != nil { + if err = service.Validate(); err != nil { util.WriteError(r.Context(), status.Errorf(status.InvalidArgument, "%s", err.Error()), w) return } - createdReverseProxy, err := h.manager.CreateReverseProxy(r.Context(), userAuth.AccountId, userAuth.UserId, reverseProxy) + createdService, err := h.manager.CreateService(r.Context(), userAuth.AccountId, userAuth.UserId, service) if err != nil { util.WriteError(r.Context(), err, w) return } - util.WriteJSONObject(r.Context(), w, createdReverseProxy.ToAPIResponse()) + util.WriteJSONObject(r.Context(), w, createdService.ToAPIResponse()) } -func (h *handler) getReverseProxy(w http.ResponseWriter, r *http.Request) { +func (h *handler) getService(w http.ResponseWriter, r *http.Request) { userAuth, err := nbcontext.GetUserAuthFromContext(r.Context()) if err != nil { util.WriteError(r.Context(), err, w) return } - reverseProxyID := mux.Vars(r)["proxyId"] - if reverseProxyID == "" { - util.WriteError(r.Context(), status.Errorf(status.InvalidArgument, "reverse proxy ID is required"), w) + serviceID := mux.Vars(r)["serviceId"] + if serviceID == "" { + util.WriteError(r.Context(), status.Errorf(status.InvalidArgument, "service ID is required"), w) return } - reverseProxy, err := h.manager.GetReverseProxy(r.Context(), userAuth.AccountId, userAuth.UserId, reverseProxyID) + service, err := h.manager.GetService(r.Context(), userAuth.AccountId, userAuth.UserId, serviceID) if err != nil { util.WriteError(r.Context(), err, w) return } - util.WriteJSONObject(r.Context(), w, reverseProxy.ToAPIResponse()) + util.WriteJSONObject(r.Context(), w, service.ToAPIResponse()) } -func (h *handler) updateReverseProxy(w http.ResponseWriter, r *http.Request) { +func (h *handler) updateService(w http.ResponseWriter, r *http.Request) { userAuth, err := nbcontext.GetUserAuthFromContext(r.Context()) if err != nil { util.WriteError(r.Context(), err, w) return } - reverseProxyID := mux.Vars(r)["proxyId"] - if reverseProxyID == "" { - util.WriteError(r.Context(), status.Errorf(status.InvalidArgument, "reverse proxy ID is required"), w) + serviceID := mux.Vars(r)["serviceId"] + if serviceID == "" { + util.WriteError(r.Context(), status.Errorf(status.InvalidArgument, "service ID is required"), w) return } - var req api.ReverseProxyRequest + var req api.ServiceRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { util.WriteErrorResponse("couldn't parse JSON request", http.StatusBadRequest, w) return } - reverseProxy := new(reverseproxy.ReverseProxy) - reverseProxy.ID = reverseProxyID - reverseProxy.FromAPIRequest(&req, userAuth.AccountId) + service := new(reverseproxy.Service) + service.ID = serviceID + service.FromAPIRequest(&req, userAuth.AccountId) - if err = reverseProxy.Validate(); err != nil { + if err = service.Validate(); err != nil { util.WriteError(r.Context(), status.Errorf(status.InvalidArgument, "%s", err.Error()), w) return } - updatedReverseProxy, err := h.manager.UpdateReverseProxy(r.Context(), userAuth.AccountId, userAuth.UserId, reverseProxy) + updatedService, err := h.manager.UpdateService(r.Context(), userAuth.AccountId, userAuth.UserId, service) if err != nil { util.WriteError(r.Context(), err, w) return } - util.WriteJSONObject(r.Context(), w, updatedReverseProxy.ToAPIResponse()) + util.WriteJSONObject(r.Context(), w, updatedService.ToAPIResponse()) } -func (h *handler) deleteReverseProxy(w http.ResponseWriter, r *http.Request) { +func (h *handler) deleteService(w http.ResponseWriter, r *http.Request) { userAuth, err := nbcontext.GetUserAuthFromContext(r.Context()) if err != nil { util.WriteError(r.Context(), err, w) return } - reverseProxyID := mux.Vars(r)["proxyId"] - if reverseProxyID == "" { - util.WriteError(r.Context(), status.Errorf(status.InvalidArgument, "reverse proxy ID is required"), w) + serviceID := mux.Vars(r)["serviceId"] + if serviceID == "" { + util.WriteError(r.Context(), status.Errorf(status.InvalidArgument, "service ID is required"), w) return } - if err := h.manager.DeleteReverseProxy(r.Context(), userAuth.AccountId, userAuth.UserId, reverseProxyID); err != nil { + if err := h.manager.DeleteService(r.Context(), userAuth.AccountId, userAuth.UserId, serviceID); err != nil { util.WriteError(r.Context(), err, w) return } diff --git a/management/internals/modules/reverseproxy/manager/manager.go b/management/internals/modules/reverseproxy/manager/manager.go index f42e07398..d19360322 100644 --- a/management/internals/modules/reverseproxy/manager/manager.go +++ b/management/internals/modules/reverseproxy/manager/manager.go @@ -35,7 +35,7 @@ type managerImpl struct { clusterDeriver ClusterDeriver } -// NewManager creates a new reverse proxy manager. +// NewManager creates a new service manager. func NewManager(store store.Store, accountManager account.Manager, permissionsManager permissions.Manager, proxyGRPCServer *nbgrpc.ProxyServiceServer, tokenStore *nbgrpc.OneTimeTokenStore, clusterDeriver ClusterDeriver) reverseproxy.Manager { return &managerImpl{ store: store, @@ -47,7 +47,7 @@ func NewManager(store store.Store, accountManager account.Manager, permissionsMa } } -func (m *managerImpl) GetAllReverseProxies(ctx context.Context, accountID, userID string) ([]*reverseproxy.ReverseProxy, error) { +func (m *managerImpl) GetAllServices(ctx context.Context, accountID, userID string) ([]*reverseproxy.Service, error) { ok, err := m.permissionsManager.ValidateUserPermissions(ctx, accountID, userID, modules.Services, operations.Read) if err != nil { return nil, status.NewPermissionValidationError(err) @@ -56,28 +56,28 @@ func (m *managerImpl) GetAllReverseProxies(ctx context.Context, accountID, userI return nil, status.NewPermissionDeniedError() } - proxies, err := m.store.GetAccountReverseProxies(ctx, store.LockingStrengthNone, accountID) + services, err := m.store.GetAccountServices(ctx, store.LockingStrengthNone, accountID) if err != nil { - return nil, fmt.Errorf("failed to get reverse proxies: %w", err) + return nil, fmt.Errorf("failed to get services: %w", err) } - for _, proxy := range proxies { - err = m.replaceHostByLookup(ctx, accountID, proxy) + for _, service := range services { + err = m.replaceHostByLookup(ctx, accountID, service) if err != nil { - return nil, fmt.Errorf("failed to replace host by lookup for proxy %s: %w", proxy.ID, err) + return nil, fmt.Errorf("failed to replace host by lookup for service %s: %w", service.ID, err) } } - return proxies, nil + return services, nil } -func (m *managerImpl) replaceHostByLookup(ctx context.Context, accountID string, proxy *reverseproxy.ReverseProxy) error { - for _, target := range proxy.Targets { +func (m *managerImpl) replaceHostByLookup(ctx context.Context, accountID string, service *reverseproxy.Service) error { + for _, target := range service.Targets { switch target.TargetType { case reverseproxy.TargetTypePeer: peer, err := m.store.GetPeerByID(ctx, store.LockingStrengthNone, accountID, target.TargetId) if err != nil { - log.WithContext(ctx).Warnf("failed to get peer by id %s for reverse proxy %s: %v", target.TargetId, proxy.ID, err) + log.WithContext(ctx).Warnf("failed to get peer by id %s for service %s: %v", target.TargetId, service.ID, err) target.Host = unknownHostPlaceholder continue } @@ -85,7 +85,7 @@ func (m *managerImpl) replaceHostByLookup(ctx context.Context, accountID string, case reverseproxy.TargetTypeHost: resource, err := m.store.GetNetworkResourceByID(ctx, store.LockingStrengthNone, accountID, target.TargetId) if err != nil { - log.WithContext(ctx).Warnf("failed to get resource by id %s for reverse proxy %s: %v", target.TargetId, proxy.ID, err) + log.WithContext(ctx).Warnf("failed to get resource by id %s for service %s: %v", target.TargetId, service.ID, err) target.Host = unknownHostPlaceholder continue } @@ -93,7 +93,7 @@ func (m *managerImpl) replaceHostByLookup(ctx context.Context, accountID string, case reverseproxy.TargetTypeDomain: resource, err := m.store.GetNetworkResourceByID(ctx, store.LockingStrengthNone, accountID, target.TargetId) if err != nil { - log.WithContext(ctx).Warnf("failed to get resource by id %s for reverse proxy %s: %v", target.TargetId, proxy.ID, err) + log.WithContext(ctx).Warnf("failed to get resource by id %s for service %s: %v", target.TargetId, service.ID, err) target.Host = unknownHostPlaceholder continue } @@ -107,7 +107,7 @@ func (m *managerImpl) replaceHostByLookup(ctx context.Context, accountID string, return nil } -func (m *managerImpl) GetReverseProxy(ctx context.Context, accountID, userID, reverseProxyID string) (*reverseproxy.ReverseProxy, error) { +func (m *managerImpl) GetService(ctx context.Context, accountID, userID, serviceID string) (*reverseproxy.Service, error) { ok, err := m.permissionsManager.ValidateUserPermissions(ctx, accountID, userID, modules.Services, operations.Read) if err != nil { return nil, status.NewPermissionValidationError(err) @@ -116,19 +116,19 @@ func (m *managerImpl) GetReverseProxy(ctx context.Context, accountID, userID, re return nil, status.NewPermissionDeniedError() } - proxy, err := m.store.GetReverseProxyByID(ctx, store.LockingStrengthNone, accountID, reverseProxyID) + service, err := m.store.GetServiceByID(ctx, store.LockingStrengthNone, accountID, serviceID) if err != nil { - return nil, fmt.Errorf("failed to get reverse proxy: %w", err) + return nil, fmt.Errorf("failed to get service: %w", err) } - err = m.replaceHostByLookup(ctx, accountID, proxy) + err = m.replaceHostByLookup(ctx, accountID, service) if err != nil { - return nil, fmt.Errorf("failed to replace host by lookup for proxy %s: %w", proxy.ID, err) + return nil, fmt.Errorf("failed to replace host by lookup for service %s: %w", service.ID, err) } - return proxy, nil + return service, nil } -func (m *managerImpl) CreateReverseProxy(ctx context.Context, accountID, userID string, reverseProxy *reverseproxy.ReverseProxy) (*reverseproxy.ReverseProxy, error) { +func (m *managerImpl) CreateService(ctx context.Context, accountID, userID string, service *reverseproxy.Service) (*reverseproxy.Service, error) { ok, err := m.permissionsManager.ValidateUserPermissions(ctx, accountID, userID, modules.Services, operations.Create) if err != nil { return nil, status.NewPermissionValidationError(err) @@ -139,16 +139,16 @@ func (m *managerImpl) CreateReverseProxy(ctx context.Context, accountID, userID var proxyCluster string if m.clusterDeriver != nil { - proxyCluster, err = m.clusterDeriver.DeriveClusterFromDomain(ctx, reverseProxy.Domain) + proxyCluster, err = m.clusterDeriver.DeriveClusterFromDomain(ctx, service.Domain) if err != nil { - log.WithError(err).Warnf("could not derive cluster from domain %s, updates will broadcast to all proxies", reverseProxy.Domain) + log.WithError(err).Warnf("could not derive cluster from domain %s, updates will broadcast to all proxy servers", service.Domain) } } - reverseProxy.AccountID = accountID - reverseProxy.ProxyCluster = proxyCluster - reverseProxy.InitNewRecord() - err = reverseProxy.Auth.HashSecrets() + service.AccountID = accountID + service.ProxyCluster = proxyCluster + service.InitNewRecord() + err = service.Auth.HashSecrets() if err != nil { return nil, fmt.Errorf("hash secrets: %w", err) } @@ -158,27 +158,27 @@ func (m *managerImpl) CreateReverseProxy(ctx context.Context, accountID, userID if err != nil { return nil, fmt.Errorf("generate session keys: %w", err) } - reverseProxy.SessionPrivateKey = keyPair.PrivateKey - reverseProxy.SessionPublicKey = keyPair.PublicKey + service.SessionPrivateKey = keyPair.PrivateKey + service.SessionPublicKey = keyPair.PublicKey err = m.store.ExecuteInTransaction(ctx, func(transaction store.Store) error { // Check for duplicate domain - existingReverseProxy, err := transaction.GetReverseProxyByDomain(ctx, accountID, reverseProxy.Domain) + existingService, err := transaction.GetServiceByDomain(ctx, accountID, service.Domain) if err != nil { if sErr, ok := status.FromError(err); !ok || sErr.Type() != status.NotFound { - return fmt.Errorf("failed to check existing reverse proxy: %w", err) + return fmt.Errorf("failed to check existing service: %w", err) } } - if existingReverseProxy != nil { - return status.Errorf(status.AlreadyExists, "reverse proxy with domain %s already exists", reverseProxy.Domain) + if existingService != nil { + return status.Errorf(status.AlreadyExists, "service with domain %s already exists", service.Domain) } - if err = validateTargetReferences(ctx, transaction, accountID, reverseProxy.Targets); err != nil { + if err = validateTargetReferences(ctx, transaction, accountID, service.Targets); err != nil { return err } - if err = transaction.CreateReverseProxy(ctx, reverseProxy); err != nil { - return fmt.Errorf("failed to create reverse proxy: %w", err) + if err = transaction.CreateService(ctx, service); err != nil { + return fmt.Errorf("failed to create service: %w", err) } return nil @@ -187,26 +187,26 @@ func (m *managerImpl) CreateReverseProxy(ctx context.Context, accountID, userID return nil, err } - token, err := m.tokenStore.GenerateToken(accountID, reverseProxy.ID, 5*time.Minute) + token, err := m.tokenStore.GenerateToken(accountID, service.ID, 5*time.Minute) if err != nil { return nil, fmt.Errorf("failed to generate authentication token: %w", err) } - m.accountManager.StoreEvent(ctx, userID, reverseProxy.ID, accountID, activity.ReverseProxyCreated, reverseProxy.EventMeta()) + m.accountManager.StoreEvent(ctx, userID, service.ID, accountID, activity.ServiceCreated, service.EventMeta()) - err = m.replaceHostByLookup(ctx, accountID, reverseProxy) + err = m.replaceHostByLookup(ctx, accountID, service) if err != nil { - return nil, fmt.Errorf("failed to replace host by lookup for proxy %s: %w", reverseProxy.ID, err) + return nil, fmt.Errorf("failed to replace host by lookup for service %s: %w", service.ID, err) } - m.proxyGRPCServer.SendReverseProxyUpdateToCluster(reverseProxy.ToProtoMapping(reverseproxy.Create, token, m.proxyGRPCServer.GetOIDCValidationConfig()), reverseProxy.ProxyCluster) + m.proxyGRPCServer.SendServiceUpdateToCluster(service.ToProtoMapping(reverseproxy.Create, token, m.proxyGRPCServer.GetOIDCValidationConfig()), service.ProxyCluster) m.accountManager.UpdateAccountPeers(ctx, accountID) - return reverseProxy, nil + return service, nil } -func (m *managerImpl) UpdateReverseProxy(ctx context.Context, accountID, userID string, reverseProxy *reverseproxy.ReverseProxy) (*reverseproxy.ReverseProxy, error) { +func (m *managerImpl) UpdateService(ctx context.Context, accountID, userID string, service *reverseproxy.Service) (*reverseproxy.Service, error) { ok, err := m.permissionsManager.ValidateUserPermissions(ctx, accountID, userID, modules.Services, operations.Update) if err != nil { return nil, status.NewPermissionValidationError(err) @@ -217,67 +217,67 @@ func (m *managerImpl) UpdateReverseProxy(ctx context.Context, accountID, userID var oldCluster string var domainChanged bool - var reverseProxyEnabledChanged bool + var serviceEnabledChanged bool - err = reverseProxy.Auth.HashSecrets() + err = service.Auth.HashSecrets() if err != nil { return nil, fmt.Errorf("hash secrets: %w", err) } err = m.store.ExecuteInTransaction(ctx, func(transaction store.Store) error { - existingReverseProxy, err := transaction.GetReverseProxyByID(ctx, store.LockingStrengthUpdate, accountID, reverseProxy.ID) + existingService, err := transaction.GetServiceByID(ctx, store.LockingStrengthUpdate, accountID, service.ID) if err != nil { return err } - oldCluster = existingReverseProxy.ProxyCluster + oldCluster = existingService.ProxyCluster - if existingReverseProxy.Domain != reverseProxy.Domain { + if existingService.Domain != service.Domain { domainChanged = true - conflictReverseProxy, err := transaction.GetReverseProxyByDomain(ctx, accountID, reverseProxy.Domain) + conflictService, err := transaction.GetServiceByDomain(ctx, accountID, service.Domain) if err != nil { if sErr, ok := status.FromError(err); !ok || sErr.Type() != status.NotFound { - return fmt.Errorf("check existing reverse proxy: %w", err) + return fmt.Errorf("check existing service: %w", err) } } - if conflictReverseProxy != nil && conflictReverseProxy.ID != reverseProxy.ID { - return status.Errorf(status.AlreadyExists, "reverse proxy with domain %s already exists", reverseProxy.Domain) + if conflictService != nil && conflictService.ID != service.ID { + return status.Errorf(status.AlreadyExists, "service with domain %s already exists", service.Domain) } if m.clusterDeriver != nil { - newCluster, err := m.clusterDeriver.DeriveClusterFromDomain(ctx, reverseProxy.Domain) + newCluster, err := m.clusterDeriver.DeriveClusterFromDomain(ctx, service.Domain) if err != nil { - log.WithError(err).Warnf("could not derive cluster from domain %s", reverseProxy.Domain) + log.WithError(err).Warnf("could not derive cluster from domain %s", service.Domain) } - reverseProxy.ProxyCluster = newCluster + service.ProxyCluster = newCluster } } else { - reverseProxy.ProxyCluster = existingReverseProxy.ProxyCluster + service.ProxyCluster = existingService.ProxyCluster } - if reverseProxy.Auth.PasswordAuth != nil && reverseProxy.Auth.PasswordAuth.Enabled && - existingReverseProxy.Auth.PasswordAuth != nil && existingReverseProxy.Auth.PasswordAuth.Enabled && - reverseProxy.Auth.PasswordAuth.Password == "" { - reverseProxy.Auth.PasswordAuth = existingReverseProxy.Auth.PasswordAuth + if service.Auth.PasswordAuth != nil && service.Auth.PasswordAuth.Enabled && + existingService.Auth.PasswordAuth != nil && existingService.Auth.PasswordAuth.Enabled && + service.Auth.PasswordAuth.Password == "" { + service.Auth.PasswordAuth = existingService.Auth.PasswordAuth } - if reverseProxy.Auth.PinAuth != nil && reverseProxy.Auth.PinAuth.Enabled && - existingReverseProxy.Auth.PinAuth != nil && existingReverseProxy.Auth.PinAuth.Enabled && - reverseProxy.Auth.PinAuth.Pin == "" { - reverseProxy.Auth.PinAuth = existingReverseProxy.Auth.PinAuth + if service.Auth.PinAuth != nil && service.Auth.PinAuth.Enabled && + existingService.Auth.PinAuth != nil && existingService.Auth.PinAuth.Enabled && + service.Auth.PinAuth.Pin == "" { + service.Auth.PinAuth = existingService.Auth.PinAuth } - reverseProxy.Meta = existingReverseProxy.Meta - reverseProxy.SessionPrivateKey = existingReverseProxy.SessionPrivateKey - reverseProxy.SessionPublicKey = existingReverseProxy.SessionPublicKey - reverseProxyEnabledChanged = existingReverseProxy.Enabled != reverseProxy.Enabled + service.Meta = existingService.Meta + service.SessionPrivateKey = existingService.SessionPrivateKey + service.SessionPublicKey = existingService.SessionPublicKey + serviceEnabledChanged = existingService.Enabled != service.Enabled - if err = validateTargetReferences(ctx, transaction, accountID, reverseProxy.Targets); err != nil { + if err = validateTargetReferences(ctx, transaction, accountID, service.Targets); err != nil { return err } - if err = transaction.UpdateReverseProxy(ctx, reverseProxy); err != nil { - return fmt.Errorf("update reverse proxy: %w", err) + if err = transaction.UpdateService(ctx, service); err != nil { + return fmt.Errorf("update service: %w", err) } return nil @@ -286,33 +286,33 @@ func (m *managerImpl) UpdateReverseProxy(ctx context.Context, accountID, userID return nil, err } - m.accountManager.StoreEvent(ctx, userID, reverseProxy.ID, accountID, activity.ReverseProxyUpdated, reverseProxy.EventMeta()) + m.accountManager.StoreEvent(ctx, userID, service.ID, accountID, activity.ServiceUpdated, service.EventMeta()) - err = m.replaceHostByLookup(ctx, accountID, reverseProxy) + err = m.replaceHostByLookup(ctx, accountID, service) if err != nil { - return nil, fmt.Errorf("failed to replace host by lookup for proxy %s: %w", reverseProxy.ID, err) + return nil, fmt.Errorf("failed to replace host by lookup for service %s: %w", service.ID, err) } - token, err := m.tokenStore.GenerateToken(accountID, reverseProxy.ID, 5*time.Minute) + token, err := m.tokenStore.GenerateToken(accountID, service.ID, 5*time.Minute) if err != nil { return nil, fmt.Errorf("failed to generate authentication token: %w", err) } switch { - case domainChanged && oldCluster != reverseProxy.ProxyCluster: - m.proxyGRPCServer.SendReverseProxyUpdateToCluster(reverseProxy.ToProtoMapping(reverseproxy.Delete, "", m.proxyGRPCServer.GetOIDCValidationConfig()), oldCluster) - m.proxyGRPCServer.SendReverseProxyUpdateToCluster(reverseProxy.ToProtoMapping(reverseproxy.Create, token, m.proxyGRPCServer.GetOIDCValidationConfig()), reverseProxy.ProxyCluster) - case !reverseProxy.Enabled && reverseProxyEnabledChanged: - m.proxyGRPCServer.SendReverseProxyUpdateToCluster(reverseProxy.ToProtoMapping(reverseproxy.Delete, "", m.proxyGRPCServer.GetOIDCValidationConfig()), reverseProxy.ProxyCluster) - case reverseProxy.Enabled && reverseProxyEnabledChanged: - m.proxyGRPCServer.SendReverseProxyUpdateToCluster(reverseProxy.ToProtoMapping(reverseproxy.Create, token, m.proxyGRPCServer.GetOIDCValidationConfig()), reverseProxy.ProxyCluster) + case domainChanged && oldCluster != service.ProxyCluster: + m.proxyGRPCServer.SendServiceUpdateToCluster(service.ToProtoMapping(reverseproxy.Delete, "", m.proxyGRPCServer.GetOIDCValidationConfig()), oldCluster) + m.proxyGRPCServer.SendServiceUpdateToCluster(service.ToProtoMapping(reverseproxy.Create, token, m.proxyGRPCServer.GetOIDCValidationConfig()), service.ProxyCluster) + case !service.Enabled && serviceEnabledChanged: + m.proxyGRPCServer.SendServiceUpdateToCluster(service.ToProtoMapping(reverseproxy.Delete, "", m.proxyGRPCServer.GetOIDCValidationConfig()), service.ProxyCluster) + case service.Enabled && serviceEnabledChanged: + m.proxyGRPCServer.SendServiceUpdateToCluster(service.ToProtoMapping(reverseproxy.Create, token, m.proxyGRPCServer.GetOIDCValidationConfig()), service.ProxyCluster) default: - m.proxyGRPCServer.SendReverseProxyUpdateToCluster(reverseProxy.ToProtoMapping(reverseproxy.Update, "", m.proxyGRPCServer.GetOIDCValidationConfig()), reverseProxy.ProxyCluster) + m.proxyGRPCServer.SendServiceUpdateToCluster(service.ToProtoMapping(reverseproxy.Update, "", m.proxyGRPCServer.GetOIDCValidationConfig()), service.ProxyCluster) } m.accountManager.UpdateAccountPeers(ctx, accountID) - return reverseProxy, nil + return service, nil } // validateTargetReferences checks that all target IDs reference existing peers or resources in the account. @@ -338,7 +338,7 @@ func validateTargetReferences(ctx context.Context, transaction store.Store, acco return nil } -func (m *managerImpl) DeleteReverseProxy(ctx context.Context, accountID, userID, reverseProxyID string) error { +func (m *managerImpl) DeleteService(ctx context.Context, accountID, userID, serviceID string) error { ok, err := m.permissionsManager.ValidateUserPermissions(ctx, accountID, userID, modules.Services, operations.Delete) if err != nil { return status.NewPermissionValidationError(err) @@ -347,16 +347,16 @@ func (m *managerImpl) DeleteReverseProxy(ctx context.Context, accountID, userID, return status.NewPermissionDeniedError() } - var reverseProxy *reverseproxy.ReverseProxy + var service *reverseproxy.Service err = m.store.ExecuteInTransaction(ctx, func(transaction store.Store) error { var err error - reverseProxy, err = transaction.GetReverseProxyByID(ctx, store.LockingStrengthUpdate, accountID, reverseProxyID) + service, err = transaction.GetServiceByID(ctx, store.LockingStrengthUpdate, accountID, serviceID) if err != nil { return err } - if err = transaction.DeleteReverseProxy(ctx, accountID, reverseProxyID); err != nil { - return fmt.Errorf("failed to delete reverse proxy: %w", err) + if err = transaction.DeleteService(ctx, accountID, serviceID); err != nil { + return fmt.Errorf("failed to delete service: %w", err) } return nil @@ -365,9 +365,9 @@ func (m *managerImpl) DeleteReverseProxy(ctx context.Context, accountID, userID, return err } - m.accountManager.StoreEvent(ctx, userID, reverseProxyID, accountID, activity.ReverseProxyDeleted, reverseProxy.EventMeta()) + m.accountManager.StoreEvent(ctx, userID, serviceID, accountID, activity.ServiceDeleted, service.EventMeta()) - m.proxyGRPCServer.SendReverseProxyUpdateToCluster(reverseProxy.ToProtoMapping(reverseproxy.Delete, "", m.proxyGRPCServer.GetOIDCValidationConfig()), reverseProxy.ProxyCluster) + m.proxyGRPCServer.SendServiceUpdateToCluster(service.ToProtoMapping(reverseproxy.Delete, "", m.proxyGRPCServer.GetOIDCValidationConfig()), service.ProxyCluster) m.accountManager.UpdateAccountPeers(ctx, accountID) @@ -376,71 +376,71 @@ func (m *managerImpl) DeleteReverseProxy(ctx context.Context, accountID, userID, // SetCertificateIssuedAt sets the certificate issued timestamp to the current time. // Call this when receiving a gRPC notification that the certificate was issued. -func (m *managerImpl) SetCertificateIssuedAt(ctx context.Context, accountID, reverseProxyID string) error { +func (m *managerImpl) SetCertificateIssuedAt(ctx context.Context, accountID, serviceID string) error { return m.store.ExecuteInTransaction(ctx, func(transaction store.Store) error { - proxy, err := transaction.GetReverseProxyByID(ctx, store.LockingStrengthUpdate, accountID, reverseProxyID) + service, err := transaction.GetServiceByID(ctx, store.LockingStrengthUpdate, accountID, serviceID) if err != nil { - return fmt.Errorf("failed to get reverse proxy: %w", err) + return fmt.Errorf("failed to get service: %w", err) } - proxy.Meta.CertificateIssuedAt = time.Now() + service.Meta.CertificateIssuedAt = time.Now() - if err = transaction.UpdateReverseProxy(ctx, proxy); err != nil { - return fmt.Errorf("failed to update reverse proxy certificate timestamp: %w", err) + if err = transaction.UpdateService(ctx, service); err != nil { + return fmt.Errorf("failed to update service certificate timestamp: %w", err) } return nil }) } -// SetStatus updates the status of the reverse proxy (e.g., "active", "tunnel_not_created", etc.) -func (m *managerImpl) SetStatus(ctx context.Context, accountID, reverseProxyID string, status reverseproxy.ProxyStatus) error { +// SetStatus updates the status of the service (e.g., "active", "tunnel_not_created", etc.) +func (m *managerImpl) SetStatus(ctx context.Context, accountID, serviceID string, status reverseproxy.ProxyStatus) error { return m.store.ExecuteInTransaction(ctx, func(transaction store.Store) error { - proxy, err := transaction.GetReverseProxyByID(ctx, store.LockingStrengthUpdate, accountID, reverseProxyID) + service, err := transaction.GetServiceByID(ctx, store.LockingStrengthUpdate, accountID, serviceID) if err != nil { - return fmt.Errorf("failed to get reverse proxy: %w", err) + return fmt.Errorf("failed to get service: %w", err) } - proxy.Meta.Status = string(status) + service.Meta.Status = string(status) - if err = transaction.UpdateReverseProxy(ctx, proxy); err != nil { - return fmt.Errorf("failed to update reverse proxy status: %w", err) + if err = transaction.UpdateService(ctx, service); err != nil { + return fmt.Errorf("failed to update service status: %w", err) } return nil }) } -func (m *managerImpl) ReloadReverseProxy(ctx context.Context, accountID, reverseProxyID string) error { - proxy, err := m.store.GetReverseProxyByID(ctx, store.LockingStrengthNone, accountID, reverseProxyID) +func (m *managerImpl) ReloadService(ctx context.Context, accountID, serviceID string) error { + service, err := m.store.GetServiceByID(ctx, store.LockingStrengthNone, accountID, serviceID) if err != nil { - return fmt.Errorf("failed to get reverse proxy: %w", err) + return fmt.Errorf("failed to get service: %w", err) } - err = m.replaceHostByLookup(ctx, accountID, proxy) + err = m.replaceHostByLookup(ctx, accountID, service) if err != nil { - return fmt.Errorf("failed to replace host by lookup for proxy %s: %w", proxy.ID, err) + return fmt.Errorf("failed to replace host by lookup for service %s: %w", service.ID, err) } - m.proxyGRPCServer.SendReverseProxyUpdateToCluster(proxy.ToProtoMapping(reverseproxy.Update, "", m.proxyGRPCServer.GetOIDCValidationConfig()), proxy.ProxyCluster) + m.proxyGRPCServer.SendServiceUpdateToCluster(service.ToProtoMapping(reverseproxy.Update, "", m.proxyGRPCServer.GetOIDCValidationConfig()), service.ProxyCluster) m.accountManager.UpdateAccountPeers(ctx, accountID) return nil } -func (m *managerImpl) ReloadAllReverseProxiesForAccount(ctx context.Context, accountID string) error { - proxies, err := m.store.GetAccountReverseProxies(ctx, store.LockingStrengthNone, accountID) +func (m *managerImpl) ReloadAllServicesForAccount(ctx context.Context, accountID string) error { + services, err := m.store.GetAccountServices(ctx, store.LockingStrengthNone, accountID) if err != nil { - return fmt.Errorf("failed to get reverse proxies: %w", err) + return fmt.Errorf("failed to get services: %w", err) } - for _, proxy := range proxies { - err = m.replaceHostByLookup(ctx, accountID, proxy) + for _, service := range services { + err = m.replaceHostByLookup(ctx, accountID, service) if err != nil { - return fmt.Errorf("failed to replace host by lookup for proxy %s: %w", proxy.ID, err) + return fmt.Errorf("failed to replace host by lookup for service %s: %w", service.ID, err) } - m.proxyGRPCServer.SendReverseProxyUpdateToCluster(proxy.ToProtoMapping(reverseproxy.Update, "", m.proxyGRPCServer.GetOIDCValidationConfig()), proxy.ProxyCluster) + m.proxyGRPCServer.SendServiceUpdateToCluster(service.ToProtoMapping(reverseproxy.Update, "", m.proxyGRPCServer.GetOIDCValidationConfig()), service.ProxyCluster) } m.accountManager.UpdateAccountPeers(ctx, accountID) @@ -448,61 +448,61 @@ func (m *managerImpl) ReloadAllReverseProxiesForAccount(ctx context.Context, acc return nil } -func (m *managerImpl) GetGlobalReverseProxies(ctx context.Context) ([]*reverseproxy.ReverseProxy, error) { - proxies, err := m.store.GetReverseProxies(ctx, store.LockingStrengthNone) +func (m *managerImpl) GetGlobalServices(ctx context.Context) ([]*reverseproxy.Service, error) { + services, err := m.store.GetServices(ctx, store.LockingStrengthNone) if err != nil { - return nil, fmt.Errorf("failed to get reverse proxies: %w", err) + return nil, fmt.Errorf("failed to get services: %w", err) } - for _, proxy := range proxies { - err = m.replaceHostByLookup(ctx, proxy.AccountID, proxy) + for _, service := range services { + err = m.replaceHostByLookup(ctx, service.AccountID, service) if err != nil { - return nil, fmt.Errorf("failed to replace host by lookup for proxy %s: %w", proxy.ID, err) + return nil, fmt.Errorf("failed to replace host by lookup for service %s: %w", service.ID, err) } } - return proxies, nil + return services, nil } -func (m *managerImpl) GetProxyByID(ctx context.Context, accountID, reverseProxyID string) (*reverseproxy.ReverseProxy, error) { - proxy, err := m.store.GetReverseProxyByID(ctx, store.LockingStrengthNone, accountID, reverseProxyID) +func (m *managerImpl) GetServiceByID(ctx context.Context, accountID, serviceID string) (*reverseproxy.Service, error) { + service, err := m.store.GetServiceByID(ctx, store.LockingStrengthNone, accountID, serviceID) if err != nil { - return nil, fmt.Errorf("failed to get reverse proxy: %w", err) + return nil, fmt.Errorf("failed to get service: %w", err) } - err = m.replaceHostByLookup(ctx, accountID, proxy) + err = m.replaceHostByLookup(ctx, accountID, service) if err != nil { - return nil, fmt.Errorf("failed to replace host by lookup for proxy %s: %w", proxy.ID, err) + return nil, fmt.Errorf("failed to replace host by lookup for service %s: %w", service.ID, err) } - return proxy, nil + return service, nil } -func (m *managerImpl) GetAccountReverseProxies(ctx context.Context, accountID string) ([]*reverseproxy.ReverseProxy, error) { - proxies, err := m.store.GetAccountReverseProxies(ctx, store.LockingStrengthNone, accountID) +func (m *managerImpl) GetAccountServices(ctx context.Context, accountID string) ([]*reverseproxy.Service, error) { + services, err := m.store.GetAccountServices(ctx, store.LockingStrengthNone, accountID) if err != nil { - return nil, fmt.Errorf("failed to get reverse proxies: %w", err) + return nil, fmt.Errorf("failed to get services: %w", err) } - for _, proxy := range proxies { - err = m.replaceHostByLookup(ctx, accountID, proxy) + for _, service := range services { + err = m.replaceHostByLookup(ctx, accountID, service) if err != nil { - return nil, fmt.Errorf("failed to replace host by lookup for proxy %s: %w", proxy.ID, err) + return nil, fmt.Errorf("failed to replace host by lookup for service %s: %w", service.ID, err) } } - return proxies, nil + return services, nil } -func (m *managerImpl) GetProxyIDByTargetID(ctx context.Context, accountID string, resourceID string) (string, error) { - target, err := m.store.GetReverseProxyTargetByTargetID(ctx, store.LockingStrengthNone, accountID, resourceID) +func (m *managerImpl) GetServiceIDByTargetID(ctx context.Context, accountID string, resourceID string) (string, error) { + target, err := m.store.GetServiceTargetByTargetID(ctx, store.LockingStrengthNone, accountID, resourceID) if err != nil { - return "", fmt.Errorf("failed to get reverse proxy target by resource ID: %w", err) + return "", fmt.Errorf("failed to get service target by resource ID: %w", err) } if target == nil { return "", nil } - return target.ReverseProxyID, nil + return target.ServiceID, nil } diff --git a/management/internals/modules/reverseproxy/reverseproxy.go b/management/internals/modules/reverseproxy/reverseproxy.go index ded9c13cc..0cbbe450b 100644 --- a/management/internals/modules/reverseproxy/reverseproxy.go +++ b/management/internals/modules/reverseproxy/reverseproxy.go @@ -43,16 +43,16 @@ const ( ) type Target struct { - ID uint `gorm:"primaryKey" json:"-"` - AccountID string `gorm:"index:idx_target_account;not null" json:"-"` - ReverseProxyID string `gorm:"index:idx_reverse_proxy_targets;not null" json:"-"` - Path *string `json:"path,omitempty"` - Host string `json:"host"` // the Host field is only used for subnet targets, otherwise ignored - Port int `gorm:"index:idx_target_port" json:"port"` - Protocol string `gorm:"index:idx_target_protocol" json:"protocol"` - TargetId string `gorm:"index:idx_target_id" json:"target_id"` - TargetType string `gorm:"index:idx_target_type" json:"target_type"` - Enabled bool `gorm:"index:idx_target_enabled" json:"enabled"` + ID uint `gorm:"primaryKey" json:"-"` + AccountID string `gorm:"index:idx_target_account;not null" json:"-"` + ServiceID string `gorm:"index:idx_service_targets;not null" json:"-"` + Path *string `json:"path,omitempty"` + Host string `json:"host"` // the Host field is only used for subnet targets, otherwise ignored + Port int `gorm:"index:idx_target_port" json:"port"` + Protocol string `gorm:"index:idx_target_protocol" json:"protocol"` + TargetId string `gorm:"index:idx_target_id" json:"target_id"` + TargetType string `gorm:"index:idx_target_type" json:"target_type"` + Enabled bool `gorm:"index:idx_target_enabled" json:"enabled"` } type PasswordAuthConfig struct { @@ -112,34 +112,34 @@ type OIDCValidationConfig struct { MaxTokenAgeSeconds int64 } -type ReverseProxyMeta struct { +type ServiceMeta struct { CreatedAt time.Time CertificateIssuedAt time.Time Status string } -type ReverseProxy struct { +type Service struct { ID string `gorm:"primaryKey"` AccountID string `gorm:"index"` Name string Domain string `gorm:"index"` ProxyCluster string `gorm:"index"` - Targets []*Target `gorm:"foreignKey:ReverseProxyID;constraint:OnDelete:CASCADE"` + Targets []*Target `gorm:"foreignKey:ServiceID;constraint:OnDelete:CASCADE"` Enabled bool PassHostHeader bool RewriteRedirects bool - Auth AuthConfig `gorm:"serializer:json"` - Meta ReverseProxyMeta `gorm:"embedded;embeddedPrefix:meta_"` - SessionPrivateKey string `gorm:"column:session_private_key"` - SessionPublicKey string `gorm:"column:session_public_key"` + Auth AuthConfig `gorm:"serializer:json"` + Meta ServiceMeta `gorm:"embedded;embeddedPrefix:meta_"` + SessionPrivateKey string `gorm:"column:session_private_key"` + SessionPublicKey string `gorm:"column:session_public_key"` } -func NewReverseProxy(accountID, name, domain, proxyCluster string, targets []*Target, enabled bool) *ReverseProxy { +func NewService(accountID, name, domain, proxyCluster string, targets []*Target, enabled bool) *Service { for _, target := range targets { target.AccountID = accountID } - rp := &ReverseProxy{ + s := &Service{ AccountID: accountID, Name: name, Domain: domain, @@ -147,92 +147,92 @@ func NewReverseProxy(accountID, name, domain, proxyCluster string, targets []*Ta Targets: targets, Enabled: enabled, } - rp.InitNewRecord() - return rp + s.InitNewRecord() + return s } // InitNewRecord generates a new unique ID and resets metadata for a newly created -// ReverseProxy record. This overwrites any existing ID and Meta fields and should +// Service record. This overwrites any existing ID and Meta fields and should // only be called during initial creation, not for updates. -func (r *ReverseProxy) InitNewRecord() { - r.ID = xid.New().String() - r.Meta = ReverseProxyMeta{ +func (s *Service) InitNewRecord() { + s.ID = xid.New().String() + s.Meta = ServiceMeta{ CreatedAt: time.Now(), Status: string(StatusPending), } } -func (r *ReverseProxy) ToAPIResponse() *api.ReverseProxy { - r.Auth.ClearSecrets() +func (s *Service) ToAPIResponse() *api.Service { + s.Auth.ClearSecrets() - authConfig := api.ReverseProxyAuthConfig{} + authConfig := api.ServiceAuthConfig{} - if r.Auth.PasswordAuth != nil { + if s.Auth.PasswordAuth != nil { authConfig.PasswordAuth = &api.PasswordAuthConfig{ - Enabled: r.Auth.PasswordAuth.Enabled, - Password: r.Auth.PasswordAuth.Password, + Enabled: s.Auth.PasswordAuth.Enabled, + Password: s.Auth.PasswordAuth.Password, } } - if r.Auth.PinAuth != nil { + if s.Auth.PinAuth != nil { authConfig.PinAuth = &api.PINAuthConfig{ - Enabled: r.Auth.PinAuth.Enabled, - Pin: r.Auth.PinAuth.Pin, + Enabled: s.Auth.PinAuth.Enabled, + Pin: s.Auth.PinAuth.Pin, } } - if r.Auth.BearerAuth != nil { + if s.Auth.BearerAuth != nil { authConfig.BearerAuth = &api.BearerAuthConfig{ - Enabled: r.Auth.BearerAuth.Enabled, - DistributionGroups: &r.Auth.BearerAuth.DistributionGroups, + Enabled: s.Auth.BearerAuth.Enabled, + DistributionGroups: &s.Auth.BearerAuth.DistributionGroups, } } // Convert internal targets to API targets - apiTargets := make([]api.ReverseProxyTarget, 0, len(r.Targets)) - for _, target := range r.Targets { - apiTargets = append(apiTargets, api.ReverseProxyTarget{ + apiTargets := make([]api.ServiceTarget, 0, len(s.Targets)) + for _, target := range s.Targets { + apiTargets = append(apiTargets, api.ServiceTarget{ Path: target.Path, Host: &target.Host, Port: target.Port, - Protocol: api.ReverseProxyTargetProtocol(target.Protocol), + Protocol: api.ServiceTargetProtocol(target.Protocol), TargetId: target.TargetId, - TargetType: api.ReverseProxyTargetTargetType(target.TargetType), + TargetType: api.ServiceTargetTargetType(target.TargetType), Enabled: target.Enabled, }) } - meta := api.ReverseProxyMeta{ - CreatedAt: r.Meta.CreatedAt, - Status: api.ReverseProxyMetaStatus(r.Meta.Status), + meta := api.ServiceMeta{ + CreatedAt: s.Meta.CreatedAt, + Status: api.ServiceMetaStatus(s.Meta.Status), } - if !r.Meta.CertificateIssuedAt.IsZero() { - meta.CertificateIssuedAt = &r.Meta.CertificateIssuedAt + if !s.Meta.CertificateIssuedAt.IsZero() { + meta.CertificateIssuedAt = &s.Meta.CertificateIssuedAt } - resp := &api.ReverseProxy{ - Id: r.ID, - Name: r.Name, - Domain: r.Domain, + resp := &api.Service{ + Id: s.ID, + Name: s.Name, + Domain: s.Domain, Targets: apiTargets, - Enabled: r.Enabled, - PassHostHeader: &r.PassHostHeader, - RewriteRedirects: &r.RewriteRedirects, + Enabled: s.Enabled, + PassHostHeader: &s.PassHostHeader, + RewriteRedirects: &s.RewriteRedirects, Auth: authConfig, Meta: meta, } - if r.ProxyCluster != "" { - resp.ProxyCluster = &r.ProxyCluster + if s.ProxyCluster != "" { + resp.ProxyCluster = &s.ProxyCluster } return resp } -func (r *ReverseProxy) ToProtoMapping(operation Operation, authToken string, oidcConfig OIDCValidationConfig) *proto.ProxyMapping { - pathMappings := make([]*proto.PathMapping, 0, len(r.Targets)) - for _, target := range r.Targets { +func (s *Service) ToProtoMapping(operation Operation, authToken string, oidcConfig OIDCValidationConfig) *proto.ProxyMapping { + pathMappings := make([]*proto.PathMapping, 0, len(s.Targets)) + for _, target := range s.Targets { if !target.Enabled { continue } @@ -260,32 +260,32 @@ func (r *ReverseProxy) ToProtoMapping(operation Operation, authToken string, oid } auth := &proto.Authentication{ - SessionKey: r.SessionPublicKey, + SessionKey: s.SessionPublicKey, MaxSessionAgeSeconds: int64((time.Hour * 24).Seconds()), } - if r.Auth.PasswordAuth != nil && r.Auth.PasswordAuth.Enabled { + if s.Auth.PasswordAuth != nil && s.Auth.PasswordAuth.Enabled { auth.Password = true } - if r.Auth.PinAuth != nil && r.Auth.PinAuth.Enabled { + if s.Auth.PinAuth != nil && s.Auth.PinAuth.Enabled { auth.Pin = true } - if r.Auth.BearerAuth != nil && r.Auth.BearerAuth.Enabled { + if s.Auth.BearerAuth != nil && s.Auth.BearerAuth.Enabled { auth.Oidc = true } return &proto.ProxyMapping{ Type: operationToProtoType(operation), - Id: r.ID, - Domain: r.Domain, + Id: s.ID, + Domain: s.Domain, Path: pathMappings, AuthToken: authToken, Auth: auth, - AccountId: r.AccountID, - PassHostHeader: r.PassHostHeader, - RewriteRedirects: r.RewriteRedirects, + AccountId: s.AccountID, + PassHostHeader: s.PassHostHeader, + RewriteRedirects: s.RewriteRedirects, } } @@ -309,10 +309,10 @@ func isDefaultPort(scheme string, port int) bool { return (scheme == "https" && port == 443) || (scheme == "http" && port == 80) } -func (r *ReverseProxy) FromAPIRequest(req *api.ReverseProxyRequest, accountID string) { - r.Name = req.Name - r.Domain = req.Domain - r.AccountID = accountID +func (s *Service) FromAPIRequest(req *api.ServiceRequest, accountID string) { + s.Name = req.Name + s.Domain = req.Domain + s.AccountID = accountID targets := make([]*Target, 0, len(req.Targets)) for _, apiTarget := range req.Targets { @@ -330,27 +330,27 @@ func (r *ReverseProxy) FromAPIRequest(req *api.ReverseProxyRequest, accountID st } targets = append(targets, target) } - r.Targets = targets + s.Targets = targets - r.Enabled = req.Enabled + s.Enabled = req.Enabled if req.PassHostHeader != nil { - r.PassHostHeader = *req.PassHostHeader + s.PassHostHeader = *req.PassHostHeader } if req.RewriteRedirects != nil { - r.RewriteRedirects = *req.RewriteRedirects + s.RewriteRedirects = *req.RewriteRedirects } if req.Auth.PasswordAuth != nil { - r.Auth.PasswordAuth = &PasswordAuthConfig{ + s.Auth.PasswordAuth = &PasswordAuthConfig{ Enabled: req.Auth.PasswordAuth.Enabled, Password: req.Auth.PasswordAuth.Password, } } if req.Auth.PinAuth != nil { - r.Auth.PinAuth = &PINAuthConfig{ + s.Auth.PinAuth = &PINAuthConfig{ Enabled: req.Auth.PinAuth.Enabled, Pin: req.Auth.PinAuth.Pin, } @@ -363,27 +363,27 @@ func (r *ReverseProxy) FromAPIRequest(req *api.ReverseProxyRequest, accountID st if req.Auth.BearerAuth.DistributionGroups != nil { bearerAuth.DistributionGroups = *req.Auth.BearerAuth.DistributionGroups } - r.Auth.BearerAuth = bearerAuth + s.Auth.BearerAuth = bearerAuth } } -func (r *ReverseProxy) Validate() error { - if r.Name == "" { - return errors.New("reverse proxy name is required") +func (s *Service) Validate() error { + if s.Name == "" { + return errors.New("service name is required") } - if len(r.Name) > 255 { - return errors.New("reverse proxy name exceeds maximum length of 255 characters") + if len(s.Name) > 255 { + return errors.New("service name exceeds maximum length of 255 characters") } - if r.Domain == "" { - return errors.New("reverse proxy domain is required") + if s.Domain == "" { + return errors.New("service domain is required") } - if len(r.Targets) == 0 { + if len(s.Targets) == 0 { return errors.New("at least one target is required") } - for i, target := range r.Targets { + for i, target := range s.Targets { switch target.TargetType { case TargetTypePeer, TargetTypeHost, TargetTypeDomain: // host field will be ignored @@ -402,42 +402,42 @@ func (r *ReverseProxy) Validate() error { return nil } -func (r *ReverseProxy) EventMeta() map[string]any { - return map[string]any{"name": r.Name, "domain": r.Domain, "proxy_cluster": r.ProxyCluster} +func (s *Service) EventMeta() map[string]any { + return map[string]any{"name": s.Name, "domain": s.Domain, "proxy_cluster": s.ProxyCluster} } -func (r *ReverseProxy) Copy() *ReverseProxy { - targets := make([]*Target, len(r.Targets)) - for i, target := range r.Targets { +func (s *Service) Copy() *Service { + targets := make([]*Target, len(s.Targets)) + for i, target := range s.Targets { targetCopy := *target targets[i] = &targetCopy } - return &ReverseProxy{ - ID: r.ID, - AccountID: r.AccountID, - Name: r.Name, - Domain: r.Domain, - ProxyCluster: r.ProxyCluster, + return &Service{ + ID: s.ID, + AccountID: s.AccountID, + Name: s.Name, + Domain: s.Domain, + ProxyCluster: s.ProxyCluster, Targets: targets, - Enabled: r.Enabled, - PassHostHeader: r.PassHostHeader, - RewriteRedirects: r.RewriteRedirects, - Auth: r.Auth, - Meta: r.Meta, - SessionPrivateKey: r.SessionPrivateKey, - SessionPublicKey: r.SessionPublicKey, + Enabled: s.Enabled, + PassHostHeader: s.PassHostHeader, + RewriteRedirects: s.RewriteRedirects, + Auth: s.Auth, + Meta: s.Meta, + SessionPrivateKey: s.SessionPrivateKey, + SessionPublicKey: s.SessionPublicKey, } } -func (r *ReverseProxy) EncryptSensitiveData(enc *crypt.FieldEncrypt) error { +func (s *Service) EncryptSensitiveData(enc *crypt.FieldEncrypt) error { if enc == nil { return nil } - if r.SessionPrivateKey != "" { + if s.SessionPrivateKey != "" { var err error - r.SessionPrivateKey, err = enc.Encrypt(r.SessionPrivateKey) + s.SessionPrivateKey, err = enc.Encrypt(s.SessionPrivateKey) if err != nil { return err } @@ -446,14 +446,14 @@ func (r *ReverseProxy) EncryptSensitiveData(enc *crypt.FieldEncrypt) error { return nil } -func (r *ReverseProxy) DecryptSensitiveData(enc *crypt.FieldEncrypt) error { +func (s *Service) DecryptSensitiveData(enc *crypt.FieldEncrypt) error { if enc == nil { return nil } - if r.SessionPrivateKey != "" { + if s.SessionPrivateKey != "" { var err error - r.SessionPrivateKey, err = enc.Decrypt(r.SessionPrivateKey) + s.SessionPrivateKey, err = enc.Decrypt(s.SessionPrivateKey) if err != nil { return err } diff --git a/management/internals/modules/reverseproxy/reverseproxy_test.go b/management/internals/modules/reverseproxy/reverseproxy_test.go index 5468cd018..546e80b31 100644 --- a/management/internals/modules/reverseproxy/reverseproxy_test.go +++ b/management/internals/modules/reverseproxy/reverseproxy_test.go @@ -13,8 +13,8 @@ import ( "github.com/netbirdio/netbird/shared/management/proto" ) -func validProxy() *ReverseProxy { - return &ReverseProxy{ +func validProxy() *Service { + return &Service{ Name: "test", Domain: "example.com", Targets: []*Target{ @@ -170,7 +170,7 @@ func TestToProtoMapping_PortInTargetURL(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - rp := &ReverseProxy{ + rp := &Service{ ID: "test-id", AccountID: "acc-1", Domain: "example.com", @@ -193,7 +193,7 @@ func TestToProtoMapping_PortInTargetURL(t *testing.T) { } func TestToProtoMapping_DisabledTargetSkipped(t *testing.T) { - rp := &ReverseProxy{ + rp := &Service{ ID: "test-id", AccountID: "acc-1", Domain: "example.com", diff --git a/management/internals/server/modules.go b/management/internals/server/modules.go index f1360dbce..0ddf02046 100644 --- a/management/internals/server/modules.go +++ b/management/internals/server/modules.go @@ -103,7 +103,7 @@ func (s *BaseServer) AccountManager() account.Manager { } s.AfterInit(func(s *BaseServer) { - accountManager.SetReverseProxyManager(s.ReverseProxyManager()) + accountManager.SetServiceManager(s.ReverseProxyManager()) }) return accountManager diff --git a/management/internals/shared/grpc/onetime_token.go b/management/internals/shared/grpc/onetime_token.go index 5dfc8848a..dcc37c639 100644 --- a/management/internals/shared/grpc/onetime_token.go +++ b/management/internals/shared/grpc/onetime_token.go @@ -13,7 +13,7 @@ import ( // OneTimeTokenStore manages short-lived, single-use authentication tokens // for proxy-to-management RPC authentication. Tokens are generated when -// a reverse proxy is created and must be used exactly once by the proxy +// a service is created and must be used exactly once by the proxy // to authenticate a subsequent RPC call. type OneTimeTokenStore struct { tokens map[string]*tokenMetadata @@ -24,10 +24,10 @@ type OneTimeTokenStore struct { // tokenMetadata stores information about a one-time token type tokenMetadata struct { - ReverseProxyID string - AccountID string - ExpiresAt time.Time - CreatedAt time.Time + ServiceID string + AccountID string + ExpiresAt time.Time + CreatedAt time.Time } // NewOneTimeTokenStore creates a new token store with automatic cleanup @@ -48,10 +48,10 @@ func NewOneTimeTokenStore(cleanupInterval time.Duration) *OneTimeTokenStore { // GenerateToken creates a new cryptographically secure one-time token // with the specified TTL. The token is associated with a specific -// accountID and reverseProxyID for validation purposes. +// accountID and serviceID for validation purposes. // // Returns the generated token string or an error if random generation fails. -func (s *OneTimeTokenStore) GenerateToken(accountID, reverseProxyID string, ttl time.Duration) (string, error) { +func (s *OneTimeTokenStore) GenerateToken(accountID, serviceID string, ttl time.Duration) (string, error) { // Generate 32 bytes (256 bits) of cryptographically secure random data randomBytes := make([]byte, 32) if _, err := rand.Read(randomBytes); err != nil { @@ -65,20 +65,20 @@ func (s *OneTimeTokenStore) GenerateToken(accountID, reverseProxyID string, ttl defer s.mu.Unlock() s.tokens[token] = &tokenMetadata{ - ReverseProxyID: reverseProxyID, - AccountID: accountID, - ExpiresAt: time.Now().Add(ttl), - CreatedAt: time.Now(), + ServiceID: serviceID, + AccountID: accountID, + ExpiresAt: time.Now().Add(ttl), + CreatedAt: time.Now(), } log.Debugf("Generated one-time token for proxy %s in account %s (expires in %s)", - reverseProxyID, accountID, ttl) + serviceID, accountID, ttl) return token, nil } // ValidateAndConsume verifies the token against the provided accountID and -// reverseProxyID, checks expiration, and then deletes it to enforce single-use. +// serviceID, checks expiration, and then deletes it to enforce single-use. // // This method uses constant-time comparison to prevent timing attacks. // @@ -87,14 +87,14 @@ func (s *OneTimeTokenStore) GenerateToken(accountID, reverseProxyID string, ttl // - Token has expired // - Account ID doesn't match // - Reverse proxy ID doesn't match -func (s *OneTimeTokenStore) ValidateAndConsume(token, accountID, reverseProxyID string) error { +func (s *OneTimeTokenStore) ValidateAndConsume(token, accountID, serviceID string) error { s.mu.Lock() defer s.mu.Unlock() metadata, exists := s.tokens[token] if !exists { log.Warnf("Token validation failed: token not found (proxy: %s, account: %s)", - reverseProxyID, accountID) + serviceID, accountID) return fmt.Errorf("invalid token") } @@ -102,7 +102,7 @@ func (s *OneTimeTokenStore) ValidateAndConsume(token, accountID, reverseProxyID if time.Now().After(metadata.ExpiresAt) { delete(s.tokens, token) log.Warnf("Token validation failed: token expired (proxy: %s, account: %s)", - reverseProxyID, accountID) + serviceID, accountID) return fmt.Errorf("token expired") } @@ -113,18 +113,18 @@ func (s *OneTimeTokenStore) ValidateAndConsume(token, accountID, reverseProxyID return fmt.Errorf("account ID mismatch") } - // Validate reverse proxy ID using constant-time comparison - if subtle.ConstantTimeCompare([]byte(metadata.ReverseProxyID), []byte(reverseProxyID)) != 1 { - log.Warnf("Token validation failed: reverse proxy ID mismatch (expected: %s, got: %s)", - metadata.ReverseProxyID, reverseProxyID) - return fmt.Errorf("reverse proxy ID mismatch") + // Validate service ID using constant-time comparison + if subtle.ConstantTimeCompare([]byte(metadata.ServiceID), []byte(serviceID)) != 1 { + log.Warnf("Token validation failed: service ID mismatch (expected: %s, got: %s)", + metadata.ServiceID, serviceID) + return fmt.Errorf("service ID mismatch") } // Delete token immediately to enforce single-use delete(s.tokens, token) log.Infof("Token validated and consumed for proxy %s in account %s", - reverseProxyID, accountID) + serviceID, accountID) return nil } diff --git a/management/internals/shared/grpc/proxy.go b/management/internals/shared/grpc/proxy.go index 6f6d66f94..53db8615d 100644 --- a/management/internals/shared/grpc/proxy.go +++ b/management/internals/shared/grpc/proxy.go @@ -176,39 +176,39 @@ func (s *ProxyServiceServer) GetMappingUpdate(req *proto.GetMappingUpdateRequest } } -// sendSnapshot sends the initial snapshot of reverse proxies to the connecting proxy. -// Only reverse proxies matching the proxy's cluster address are sent. +// sendSnapshot sends the initial snapshot of services to the connecting proxy. +// Only services matching the proxy's cluster address are sent. func (s *ProxyServiceServer) sendSnapshot(ctx context.Context, conn *proxyConnection) error { - reverseProxies, err := s.reverseProxyManager.GetGlobalReverseProxies(ctx) + services, err := s.reverseProxyManager.GetGlobalServices(ctx) if err != nil { - return fmt.Errorf("get reverse proxies from store: %w", err) + return fmt.Errorf("get services from store: %w", err) } proxyClusterAddr := extractClusterAddr(conn.address) - for _, rp := range reverseProxies { - if !rp.Enabled { + for _, service := range services { + if !service.Enabled { continue } - if rp.ProxyCluster != "" && proxyClusterAddr != "" && rp.ProxyCluster != proxyClusterAddr { + if service.ProxyCluster != "" && proxyClusterAddr != "" && service.ProxyCluster != proxyClusterAddr { continue } - // Generate one-time authentication token for each proxy in the snapshot + // Generate one-time authentication token for each service in the snapshot // Tokens are not persistent on the proxy, so we need to generate new ones on reconnection - token, err := s.tokenStore.GenerateToken(rp.AccountID, rp.ID, 5*time.Minute) + token, err := s.tokenStore.GenerateToken(service.AccountID, service.ID, 5*time.Minute) if err != nil { log.WithFields(log.Fields{ - "proxy": rp.Name, - "account": rp.AccountID, + "service": service.Name, + "account": service.AccountID, }).WithError(err).Error("Failed to generate auth token for snapshot") continue } if err := conn.stream.Send(&proto.GetMappingUpdateResponse{ Mapping: []*proto.ProxyMapping{ - rp.ToProtoMapping( + service.ToProtoMapping( reverseproxy.Create, // Initial snapshot, all records are "new" for the proxy. token, s.GetOIDCValidationConfig(), @@ -260,10 +260,10 @@ func (s *ProxyServiceServer) SendAccessLog(ctx context.Context, req *proto.SendA accessLog := req.GetLog() fields := log.Fields{ - "reverse_proxy_id": accessLog.GetServiceId(), - "account_id": accessLog.GetAccountId(), - "host": accessLog.GetHost(), - "source_ip": accessLog.GetSourceIp(), + "service_id": accessLog.GetServiceId(), + "account_id": accessLog.GetAccountId(), + "host": accessLog.GetHost(), + "source_ip": accessLog.GetSourceIp(), } if mechanism := accessLog.GetAuthMechanism(); mechanism != "" { fields["auth_mechanism"] = mechanism @@ -292,18 +292,18 @@ func (s *ProxyServiceServer) SendAccessLog(ctx context.Context, req *proto.SendA return &proto.SendAccessLogResponse{}, nil } -// SendReverseProxyUpdate broadcasts a reverse proxy update to all connected proxies. -// Management should call this when reverse proxies are created/updated/removed -func (s *ProxyServiceServer) SendReverseProxyUpdate(update *proto.ProxyMapping) { - // Send it to all connected proxies - log.Debugf("Broadcasting reverse proxy update to all connected proxies") +// SendServiceUpdate broadcasts a service update to all connected proxy servers. +// Management should call this when services are created/updated/removed +func (s *ProxyServiceServer) SendServiceUpdate(update *proto.ProxyMapping) { + // Send it to all connected proxy servers + log.Debugf("Broadcasting service update to all connected proxy servers") s.connectedProxies.Range(func(key, value interface{}) bool { conn := value.(*proxyConnection) select { case conn.sendChan <- update: - log.Debugf("Sent reverse proxy update with id %s to proxy %s", update.Id, conn.proxyID) + log.Debugf("Sent service update with id %s to proxy server %s", update.Id, conn.proxyID) default: - log.Warnf("Failed to send reverse proxy update to proxy %s (channel full)", conn.proxyID) + log.Warnf("Failed to send service update to proxy server %s (channel full)", conn.proxyID) } return true }) @@ -366,11 +366,11 @@ func (s *ProxyServiceServer) removeFromCluster(clusterAddr, proxyID string) { } } -// SendReverseProxyUpdateToCluster sends a reverse proxy update to all proxies in a specific cluster. -// If clusterAddr is empty, broadcasts to all connected proxies (backward compatibility). -func (s *ProxyServiceServer) SendReverseProxyUpdateToCluster(update *proto.ProxyMapping, clusterAddr string) { +// SendServiceUpdateToCluster sends a service update to all proxy servers in a specific cluster. +// If clusterAddr is empty, broadcasts to all connected proxy servers (backward compatibility). +func (s *ProxyServiceServer) SendServiceUpdateToCluster(update *proto.ProxyMapping, clusterAddr string) { if clusterAddr == "" { - s.SendReverseProxyUpdate(update) + s.SendServiceUpdate(update) return } @@ -380,16 +380,16 @@ func (s *ProxyServiceServer) SendReverseProxyUpdateToCluster(update *proto.Proxy return } - log.Debugf("Sending reverse proxy update to cluster %s", clusterAddr) + log.Debugf("Sending service update to cluster %s", clusterAddr) proxySet.(*sync.Map).Range(func(key, _ interface{}) bool { proxyID := key.(string) if connVal, ok := s.connectedProxies.Load(proxyID); ok { conn := connVal.(*proxyConnection) select { case conn.sendChan <- update: - log.Debugf("Sent reverse proxy update with id %s to proxy %s in cluster %s", update.Id, proxyID, clusterAddr) + log.Debugf("Sent service update with id %s to proxy %s in cluster %s", update.Id, proxyID, clusterAddr) default: - log.Warnf("Failed to send reverse proxy update to proxy %s in cluster %s (channel full)", proxyID, clusterAddr) + log.Warnf("Failed to send service update to proxy %s in cluster %s (channel full)", proxyID, clusterAddr) } } return true @@ -424,10 +424,10 @@ func (s *ProxyServiceServer) GetAvailableClusters() []ClusterInfo { } func (s *ProxyServiceServer) Authenticate(ctx context.Context, req *proto.AuthenticateRequest) (*proto.AuthenticateResponse, error) { - proxy, err := s.reverseProxyManager.GetProxyByID(ctx, req.GetAccountId(), req.GetId()) + service, err := s.reverseProxyManager.GetServiceByID(ctx, req.GetAccountId(), req.GetId()) if err != nil { // TODO: log the error - return nil, status.Errorf(codes.FailedPrecondition, "failed to get reverse proxy from store: %v", err) + return nil, status.Errorf(codes.FailedPrecondition, "failed to get service from store: %v", err) } var authenticated bool @@ -435,7 +435,7 @@ func (s *ProxyServiceServer) Authenticate(ctx context.Context, req *proto.Authen var method proxyauth.Method switch v := req.GetRequest().(type) { case *proto.AuthenticateRequest_Pin: - auth := proxy.Auth.PinAuth + auth := service.Auth.PinAuth if auth == nil || !auth.Enabled { // TODO: log // Break here and use the default authenticated == false. @@ -454,7 +454,7 @@ func (s *ProxyServiceServer) Authenticate(ctx context.Context, req *proto.Authen userId = "pin-user" method = proxyauth.MethodPIN case *proto.AuthenticateRequest_Password: - auth := proxy.Auth.PasswordAuth + auth := service.Auth.PasswordAuth if auth == nil || !auth.Enabled { // TODO: log // Break here and use the default authenticated == false. @@ -475,11 +475,11 @@ func (s *ProxyServiceServer) Authenticate(ctx context.Context, req *proto.Authen } var token string - if authenticated && proxy.SessionPrivateKey != "" { + if authenticated && service.SessionPrivateKey != "" { token, err = sessionkey.SignToken( - proxy.SessionPrivateKey, + service.SessionPrivateKey, userId, - proxy.Domain, + service.Domain, method, proxyauth.DefaultSessionExpiry, ) @@ -498,45 +498,45 @@ func (s *ProxyServiceServer) Authenticate(ctx context.Context, req *proto.Authen // SendStatusUpdate handles status updates from proxy clients func (s *ProxyServiceServer) SendStatusUpdate(ctx context.Context, req *proto.SendStatusUpdateRequest) (*proto.SendStatusUpdateResponse, error) { accountID := req.GetAccountId() - reverseProxyID := req.GetReverseProxyId() + serviceID := req.GetServiceId() protoStatus := req.GetStatus() certificateIssued := req.GetCertificateIssued() log.WithFields(log.Fields{ - "reverse_proxy_id": reverseProxyID, + "service_id": serviceID, "account_id": accountID, "status": protoStatus, "certificate_issued": certificateIssued, "error_message": req.GetErrorMessage(), - }).Debug("Status update from proxy") + }).Debug("Status update from proxy server") - if reverseProxyID == "" || accountID == "" { - return nil, status.Errorf(codes.InvalidArgument, "reverse_proxy_id and account_id are required") + if serviceID == "" || accountID == "" { + return nil, status.Errorf(codes.InvalidArgument, "service_id and account_id are required") } if certificateIssued { - if err := s.reverseProxyManager.SetCertificateIssuedAt(ctx, accountID, reverseProxyID); err != nil { + if err := s.reverseProxyManager.SetCertificateIssuedAt(ctx, accountID, serviceID); err != nil { log.WithContext(ctx).WithError(err).Error("Failed to set certificate issued timestamp") return nil, status.Errorf(codes.Internal, "failed to update certificate timestamp: %v", err) } log.WithFields(log.Fields{ - "reverse_proxy_id": reverseProxyID, - "account_id": accountID, + "service_id": serviceID, + "account_id": accountID, }).Info("Certificate issued timestamp updated") } internalStatus := protoStatusToInternal(protoStatus) - if err := s.reverseProxyManager.SetStatus(ctx, accountID, reverseProxyID, internalStatus); err != nil { - log.WithContext(ctx).WithError(err).Error("Failed to set proxy status") - return nil, status.Errorf(codes.Internal, "failed to update proxy status: %v", err) + if err := s.reverseProxyManager.SetStatus(ctx, accountID, serviceID, internalStatus); err != nil { + log.WithContext(ctx).WithError(err).Error("Failed to set service status") + return nil, status.Errorf(codes.Internal, "failed to update service status: %v", err) } log.WithFields(log.Fields{ - "reverse_proxy_id": reverseProxyID, - "account_id": accountID, - "status": internalStatus, - }).Info("Proxy status updated") + "service_id": serviceID, + "account_id": accountID, + "status": internalStatus, + }).Info("Service status updated") return &proto.SendStatusUpdateResponse{}, nil } @@ -563,30 +563,30 @@ func protoStatusToInternal(protoStatus proto.ProxyStatus) reverseproxy.ProxyStat // CreateProxyPeer handles proxy peer creation with one-time token authentication func (s *ProxyServiceServer) CreateProxyPeer(ctx context.Context, req *proto.CreateProxyPeerRequest) (*proto.CreateProxyPeerResponse, error) { - reverseProxyID := req.GetReverseProxyId() + serviceID := req.GetServiceId() accountID := req.GetAccountId() token := req.GetToken() cluster := req.GetCluster() key := req.WireguardPublicKey log.WithFields(log.Fields{ - "reverse_proxy_id": reverseProxyID, - "account_id": accountID, - "cluster": cluster, + "service_id": serviceID, + "account_id": accountID, + "cluster": cluster, }).Debug("CreateProxyPeer request received") - if reverseProxyID == "" || accountID == "" || token == "" { + if serviceID == "" || accountID == "" || token == "" { log.Warn("CreateProxyPeer: missing required fields") return &proto.CreateProxyPeerResponse{ Success: false, - ErrorMessage: strPtr("missing required fields: reverse_proxy_id, account_id, and token are required"), + ErrorMessage: strPtr("missing required fields: service_id, account_id, and token are required"), }, nil } - if err := s.tokenStore.ValidateAndConsume(token, accountID, reverseProxyID); err != nil { + if err := s.tokenStore.ValidateAndConsume(token, accountID, serviceID); err != nil { log.WithFields(log.Fields{ - "reverse_proxy_id": reverseProxyID, - "account_id": accountID, + "service_id": serviceID, + "account_id": accountID, }).WithError(err).Warn("CreateProxyPeer: token validation failed") return &proto.CreateProxyPeerResponse{ Success: false, @@ -597,8 +597,8 @@ func (s *ProxyServiceServer) CreateProxyPeer(ctx context.Context, req *proto.Cre err := s.peersManager.CreateProxyPeer(ctx, accountID, key, cluster) if err != nil { log.WithFields(log.Fields{ - "reverse_proxy_id": reverseProxyID, - "account_id": accountID, + "service_id": serviceID, + "account_id": accountID, }).WithError(err).Error("CreateProxyPeer: failed to create proxy peer") return &proto.CreateProxyPeerResponse{ Success: false, @@ -622,22 +622,22 @@ func (s *ProxyServiceServer) GetOIDCURL(ctx context.Context, req *proto.GetOIDCU // TODO: log return nil, status.Errorf(codes.InvalidArgument, "failed to parse redirect url: %v", err) } - // Validate redirectURL against known proxy endpoints to avoid abuse of OIDC redirection. - proxies, err := s.reverseProxyManager.GetAccountReverseProxies(ctx, req.GetAccountId()) + // Validate redirectURL against known service endpoints to avoid abuse of OIDC redirection. + services, err := s.reverseProxyManager.GetAccountServices(ctx, req.GetAccountId()) if err != nil { // TODO: log - return nil, status.Errorf(codes.FailedPrecondition, "failed to get reverse proxy from store: %v", err) + return nil, status.Errorf(codes.FailedPrecondition, "failed to get services from store: %v", err) } var found bool - for _, proxy := range proxies { - if proxy.Domain == redirectURL.Hostname() { + for _, service := range services { + if service.Domain == redirectURL.Hostname() { found = true break } } if !found { // TODO: log - return nil, status.Errorf(codes.FailedPrecondition, "reverse proxy not found in store") + return nil, status.Errorf(codes.FailedPrecondition, "service not found in store") } provider, err := oidc.NewProvider(ctx, s.oidcConfig.Issuer) @@ -728,29 +728,29 @@ func (s *ProxyServiceServer) ValidateState(state string) (verifier, redirectURL // GenerateSessionToken creates a signed session JWT for the given domain and user. func (s *ProxyServiceServer) GenerateSessionToken(ctx context.Context, domain, userID string, method proxyauth.Method) (string, error) { - // Find the proxy by domain to get its signing key - proxies, err := s.reverseProxyManager.GetGlobalReverseProxies(ctx) + // Find the service by domain to get its signing key + services, err := s.reverseProxyManager.GetGlobalServices(ctx) if err != nil { - return "", fmt.Errorf("get reverse proxies: %w", err) + return "", fmt.Errorf("get services: %w", err) } - var proxy *reverseproxy.ReverseProxy - for _, p := range proxies { - if p.Domain == domain { - proxy = p + var service *reverseproxy.Service + for _, svc := range services { + if svc.Domain == domain { + service = svc break } } - if proxy == nil { - return "", fmt.Errorf("reverse proxy not found for domain: %s", domain) + if service == nil { + return "", fmt.Errorf("service not found for domain: %s", domain) } - if proxy.SessionPrivateKey == "" { + if service.SessionPrivateKey == "" { return "", fmt.Errorf("no session key configured for domain: %s", domain) } return sessionkey.SignToken( - proxy.SessionPrivateKey, + service.SessionPrivateKey, userID, domain, method, @@ -758,8 +758,8 @@ func (s *ProxyServiceServer) GenerateSessionToken(ctx context.Context, domain, u ) } -// ValidateUserGroupAccess checks if a user has access to a reverse proxy. -// It looks up the proxy within the user's account only, then optionally checks +// ValidateUserGroupAccess checks if a user has access to a service. +// It looks up the service within the user's account only, then optionally checks // group membership if BearerAuth with DistributionGroups is configured. func (s *ProxyServiceServer) ValidateUserGroupAccess(ctx context.Context, domain, userID string) error { user, err := s.usersManager.GetUser(ctx, userID) @@ -767,16 +767,16 @@ func (s *ProxyServiceServer) ValidateUserGroupAccess(ctx context.Context, domain return fmt.Errorf("user not found: %s", userID) } - proxy, err := s.getAccountProxyByDomain(ctx, user.AccountID, domain) + service, err := s.getAccountServiceByDomain(ctx, user.AccountID, domain) if err != nil { return err } - if proxy.Auth.BearerAuth == nil || !proxy.Auth.BearerAuth.Enabled { + if service.Auth.BearerAuth == nil || !service.Auth.BearerAuth.Enabled { return nil } - allowedGroups := proxy.Auth.BearerAuth.DistributionGroups + allowedGroups := service.Auth.BearerAuth.DistributionGroups if len(allowedGroups) == 0 { return nil } @@ -800,19 +800,19 @@ func (s *ProxyServiceServer) ValidateUserGroupAccess(ctx context.Context, domain return fmt.Errorf("user %s not in allowed groups for domain %s", user.Id, domain) } -func (s *ProxyServiceServer) getAccountProxyByDomain(ctx context.Context, accountID, domain string) (*reverseproxy.ReverseProxy, error) { - proxies, err := s.reverseProxyManager.GetAccountReverseProxies(ctx, accountID) +func (s *ProxyServiceServer) getAccountServiceByDomain(ctx context.Context, accountID, domain string) (*reverseproxy.Service, error) { + services, err := s.reverseProxyManager.GetAccountServices(ctx, accountID) if err != nil { - return nil, fmt.Errorf("get account reverse proxies: %w", err) + return nil, fmt.Errorf("get account services: %w", err) } - for _, proxy := range proxies { - if proxy.Domain == domain { - return proxy, nil + for _, service := range services { + if service.Domain == domain { + return service, nil } } - return nil, fmt.Errorf("reverse proxy not found for domain %s in account %s", domain, accountID) + return nil, fmt.Errorf("service not found for domain %s in account %s", domain, accountID) } // ValidateSession validates a session token and checks if the user has access to the domain. @@ -827,19 +827,19 @@ func (s *ProxyServiceServer) ValidateSession(ctx context.Context, req *proto.Val }, nil } - proxy, err := s.getProxyByDomain(ctx, domain) + service, err := s.getServiceByDomain(ctx, domain) if err != nil { log.WithFields(log.Fields{ "domain": domain, "error": err.Error(), - }).Debug("ValidateSession: proxy not found") + }).Debug("ValidateSession: service not found") return &proto.ValidateSessionResponse{ Valid: false, - DeniedReason: "proxy_not_found", + DeniedReason: "service_not_found", }, nil } - pubKeyBytes, err := base64.StdEncoding.DecodeString(proxy.SessionPublicKey) + pubKeyBytes, err := base64.StdEncoding.DecodeString(service.SessionPublicKey) if err != nil { log.WithFields(log.Fields{ "domain": domain, @@ -847,7 +847,7 @@ func (s *ProxyServiceServer) ValidateSession(ctx context.Context, req *proto.Val }).Error("ValidateSession: decode public key") return &proto.ValidateSessionResponse{ Valid: false, - DeniedReason: "invalid_proxy_config", + DeniedReason: "invalid_service_config", }, nil } @@ -876,12 +876,12 @@ func (s *ProxyServiceServer) ValidateSession(ctx context.Context, req *proto.Val }, nil } - if user.AccountID != proxy.AccountID { + if user.AccountID != service.AccountID { log.WithFields(log.Fields{ - "domain": domain, - "user_id": userID, - "user_account": user.AccountID, - "proxy_account": proxy.AccountID, + "domain": domain, + "user_id": userID, + "user_account": user.AccountID, + "service_account": service.AccountID, }).Debug("ValidateSession: user account mismatch") return &proto.ValidateSessionResponse{ Valid: false, @@ -889,7 +889,7 @@ func (s *ProxyServiceServer) ValidateSession(ctx context.Context, req *proto.Val }, nil } - if err := s.checkGroupAccess(proxy, user); err != nil { + if err := s.checkGroupAccess(service, user); err != nil { log.WithFields(log.Fields{ "domain": domain, "user_id": userID, @@ -916,27 +916,27 @@ func (s *ProxyServiceServer) ValidateSession(ctx context.Context, req *proto.Val }, nil } -func (s *ProxyServiceServer) getProxyByDomain(ctx context.Context, domain string) (*reverseproxy.ReverseProxy, error) { - proxies, err := s.reverseProxyManager.GetGlobalReverseProxies(ctx) +func (s *ProxyServiceServer) getServiceByDomain(ctx context.Context, domain string) (*reverseproxy.Service, error) { + services, err := s.reverseProxyManager.GetGlobalServices(ctx) if err != nil { - return nil, fmt.Errorf("get reverse proxies: %w", err) + return nil, fmt.Errorf("get services: %w", err) } - for _, proxy := range proxies { - if proxy.Domain == domain { - return proxy, nil + for _, service := range services { + if service.Domain == domain { + return service, nil } } - return nil, fmt.Errorf("reverse proxy not found for domain: %s", domain) + return nil, fmt.Errorf("service not found for domain: %s", domain) } -func (s *ProxyServiceServer) checkGroupAccess(proxy *reverseproxy.ReverseProxy, user *types.User) error { - if proxy.Auth.BearerAuth == nil || !proxy.Auth.BearerAuth.Enabled { +func (s *ProxyServiceServer) checkGroupAccess(service *reverseproxy.Service, user *types.User) error { + if service.Auth.BearerAuth == nil || !service.Auth.BearerAuth.Enabled { return nil } - allowedGroups := proxy.Auth.BearerAuth.DistributionGroups + allowedGroups := service.Auth.BearerAuth.DistributionGroups if len(allowedGroups) == 0 { return nil } diff --git a/management/internals/shared/grpc/proxy_group_access_test.go b/management/internals/shared/grpc/proxy_group_access_test.go index 060be00f4..56afb6490 100644 --- a/management/internals/shared/grpc/proxy_group_access_test.go +++ b/management/internals/shared/grpc/proxy_group_access_test.go @@ -13,38 +13,38 @@ import ( ) type mockReverseProxyManager struct { - proxiesByAccount map[string][]*reverseproxy.ReverseProxy + proxiesByAccount map[string][]*reverseproxy.Service err error } -func (m *mockReverseProxyManager) GetAccountReverseProxies(ctx context.Context, accountID string) ([]*reverseproxy.ReverseProxy, error) { +func (m *mockReverseProxyManager) GetAccountServices(ctx context.Context, accountID string) ([]*reverseproxy.Service, error) { if m.err != nil { return nil, m.err } return m.proxiesByAccount[accountID], nil } -func (m *mockReverseProxyManager) GetGlobalReverseProxies(ctx context.Context) ([]*reverseproxy.ReverseProxy, error) { +func (m *mockReverseProxyManager) GetGlobalServices(ctx context.Context) ([]*reverseproxy.Service, error) { return nil, nil } -func (m *mockReverseProxyManager) GetAllReverseProxies(ctx context.Context, accountID, userID string) ([]*reverseproxy.ReverseProxy, error) { +func (m *mockReverseProxyManager) GetAllServices(ctx context.Context, accountID, userID string) ([]*reverseproxy.Service, error) { return nil, nil } -func (m *mockReverseProxyManager) GetReverseProxy(ctx context.Context, accountID, userID, reverseProxyID string) (*reverseproxy.ReverseProxy, error) { +func (m *mockReverseProxyManager) GetService(ctx context.Context, accountID, userID, reverseProxyID string) (*reverseproxy.Service, error) { return nil, nil } -func (m *mockReverseProxyManager) CreateReverseProxy(ctx context.Context, accountID, userID string, rp *reverseproxy.ReverseProxy) (*reverseproxy.ReverseProxy, error) { +func (m *mockReverseProxyManager) CreateService(ctx context.Context, accountID, userID string, rp *reverseproxy.Service) (*reverseproxy.Service, error) { return nil, nil } -func (m *mockReverseProxyManager) UpdateReverseProxy(ctx context.Context, accountID, userID string, rp *reverseproxy.ReverseProxy) (*reverseproxy.ReverseProxy, error) { +func (m *mockReverseProxyManager) UpdateService(ctx context.Context, accountID, userID string, rp *reverseproxy.Service) (*reverseproxy.Service, error) { return nil, nil } -func (m *mockReverseProxyManager) DeleteReverseProxy(ctx context.Context, accountID, userID, reverseProxyID string) error { +func (m *mockReverseProxyManager) DeleteService(ctx context.Context, accountID, userID, reverseProxyID string) error { return nil } @@ -56,19 +56,19 @@ func (m *mockReverseProxyManager) SetStatus(ctx context.Context, accountID, reve return nil } -func (m *mockReverseProxyManager) ReloadAllReverseProxiesForAccount(ctx context.Context, accountID string) error { +func (m *mockReverseProxyManager) ReloadAllServicesForAccount(ctx context.Context, accountID string) error { return nil } -func (m *mockReverseProxyManager) ReloadReverseProxy(ctx context.Context, accountID, reverseProxyID string) error { +func (m *mockReverseProxyManager) ReloadService(ctx context.Context, accountID, reverseProxyID string) error { return nil } -func (m *mockReverseProxyManager) GetProxyByID(ctx context.Context, accountID, reverseProxyID string) (*reverseproxy.ReverseProxy, error) { +func (m *mockReverseProxyManager) GetServiceByID(ctx context.Context, accountID, reverseProxyID string) (*reverseproxy.Service, error) { return nil, nil } -func (m *mockReverseProxyManager) GetProxyIDByTargetID(_ context.Context, _, _ string) (string, error) { +func (m *mockReverseProxyManager) GetServiceIDByTargetID(_ context.Context, _, _ string) (string, error) { return "", nil } @@ -93,7 +93,7 @@ func TestValidateUserGroupAccess(t *testing.T) { name string domain string userID string - proxiesByAccount map[string][]*reverseproxy.ReverseProxy + proxiesByAccount map[string][]*reverseproxy.Service users map[string]*types.User proxyErr error userErr error @@ -104,7 +104,7 @@ func TestValidateUserGroupAccess(t *testing.T) { name: "user not found", domain: "app.example.com", userID: "unknown-user", - proxiesByAccount: map[string][]*reverseproxy.ReverseProxy{ + proxiesByAccount: map[string][]*reverseproxy.Service{ "account1": {{Domain: "app.example.com", AccountID: "account1"}}, }, users: map[string]*types.User{}, @@ -115,7 +115,7 @@ func TestValidateUserGroupAccess(t *testing.T) { name: "proxy not found in user's account", domain: "app.example.com", userID: "user1", - proxiesByAccount: map[string][]*reverseproxy.ReverseProxy{}, + proxiesByAccount: map[string][]*reverseproxy.Service{}, users: map[string]*types.User{ "user1": {Id: "user1", AccountID: "account1"}, }, @@ -126,7 +126,7 @@ func TestValidateUserGroupAccess(t *testing.T) { name: "proxy exists in different account - not accessible", domain: "app.example.com", userID: "user1", - proxiesByAccount: map[string][]*reverseproxy.ReverseProxy{ + proxiesByAccount: map[string][]*reverseproxy.Service{ "account2": {{Domain: "app.example.com", AccountID: "account2"}}, }, users: map[string]*types.User{ @@ -139,7 +139,7 @@ func TestValidateUserGroupAccess(t *testing.T) { name: "no bearer auth configured - same account allows access", domain: "app.example.com", userID: "user1", - proxiesByAccount: map[string][]*reverseproxy.ReverseProxy{ + proxiesByAccount: map[string][]*reverseproxy.Service{ "account1": {{Domain: "app.example.com", AccountID: "account1", Auth: reverseproxy.AuthConfig{}}}, }, users: map[string]*types.User{ @@ -151,7 +151,7 @@ func TestValidateUserGroupAccess(t *testing.T) { name: "bearer auth disabled - same account allows access", domain: "app.example.com", userID: "user1", - proxiesByAccount: map[string][]*reverseproxy.ReverseProxy{ + proxiesByAccount: map[string][]*reverseproxy.Service{ "account1": {{ Domain: "app.example.com", AccountID: "account1", @@ -169,7 +169,7 @@ func TestValidateUserGroupAccess(t *testing.T) { name: "bearer auth enabled but no groups configured - same account allows access", domain: "app.example.com", userID: "user1", - proxiesByAccount: map[string][]*reverseproxy.ReverseProxy{ + proxiesByAccount: map[string][]*reverseproxy.Service{ "account1": {{ Domain: "app.example.com", AccountID: "account1", @@ -190,7 +190,7 @@ func TestValidateUserGroupAccess(t *testing.T) { name: "user not in allowed groups", domain: "app.example.com", userID: "user1", - proxiesByAccount: map[string][]*reverseproxy.ReverseProxy{ + proxiesByAccount: map[string][]*reverseproxy.Service{ "account1": {{ Domain: "app.example.com", AccountID: "account1", @@ -212,7 +212,7 @@ func TestValidateUserGroupAccess(t *testing.T) { name: "user in one of the allowed groups - allow access", domain: "app.example.com", userID: "user1", - proxiesByAccount: map[string][]*reverseproxy.ReverseProxy{ + proxiesByAccount: map[string][]*reverseproxy.Service{ "account1": {{ Domain: "app.example.com", AccountID: "account1", @@ -233,7 +233,7 @@ func TestValidateUserGroupAccess(t *testing.T) { name: "user in all allowed groups - allow access", domain: "app.example.com", userID: "user1", - proxiesByAccount: map[string][]*reverseproxy.ReverseProxy{ + proxiesByAccount: map[string][]*reverseproxy.Service{ "account1": {{ Domain: "app.example.com", AccountID: "account1", @@ -266,7 +266,7 @@ func TestValidateUserGroupAccess(t *testing.T) { name: "multiple proxies in account - finds correct one", domain: "app2.example.com", userID: "user1", - proxiesByAccount: map[string][]*reverseproxy.ReverseProxy{ + proxiesByAccount: map[string][]*reverseproxy.Service{ "account1": { {Domain: "app1.example.com", AccountID: "account1"}, {Domain: "app2.example.com", AccountID: "account1", Auth: reverseproxy.AuthConfig{}}, @@ -310,7 +310,7 @@ func TestGetAccountProxyByDomain(t *testing.T) { name string accountID string domain string - proxiesByAccount map[string][]*reverseproxy.ReverseProxy + proxiesByAccount map[string][]*reverseproxy.Service err error expectProxy bool expectErr bool @@ -319,7 +319,7 @@ func TestGetAccountProxyByDomain(t *testing.T) { name: "proxy found", accountID: "account1", domain: "app.example.com", - proxiesByAccount: map[string][]*reverseproxy.ReverseProxy{ + proxiesByAccount: map[string][]*reverseproxy.Service{ "account1": { {Domain: "other.example.com", AccountID: "account1"}, {Domain: "app.example.com", AccountID: "account1"}, @@ -332,7 +332,7 @@ func TestGetAccountProxyByDomain(t *testing.T) { name: "proxy not found in account", accountID: "account1", domain: "unknown.example.com", - proxiesByAccount: map[string][]*reverseproxy.ReverseProxy{ + proxiesByAccount: map[string][]*reverseproxy.Service{ "account1": {{Domain: "app.example.com", AccountID: "account1"}}, }, expectProxy: false, @@ -342,7 +342,7 @@ func TestGetAccountProxyByDomain(t *testing.T) { name: "empty proxy list for account", accountID: "account1", domain: "app.example.com", - proxiesByAccount: map[string][]*reverseproxy.ReverseProxy{}, + proxiesByAccount: map[string][]*reverseproxy.Service{}, expectProxy: false, expectErr: true, }, diff --git a/management/internals/shared/grpc/validate_session_test.go b/management/internals/shared/grpc/validate_session_test.go index 2047600a1..f76d3ada0 100644 --- a/management/internals/shared/grpc/validate_session_test.go +++ b/management/internals/shared/grpc/validate_session_test.go @@ -54,7 +54,7 @@ func createTestProxies(t *testing.T, ctx context.Context, testStore store.Store) pubKey, privKey := generateSessionKeyPair(t) - testProxy := &reverseproxy.ReverseProxy{ + testProxy := &reverseproxy.Service{ ID: "testProxyId", AccountID: "testAccountId", Name: "Test Proxy", @@ -68,9 +68,9 @@ func createTestProxies(t *testing.T, ctx context.Context, testStore store.Store) }, }, } - require.NoError(t, testStore.CreateReverseProxy(ctx, testProxy)) + require.NoError(t, testStore.CreateService(ctx, testProxy)) - restrictedProxy := &reverseproxy.ReverseProxy{ + restrictedProxy := &reverseproxy.Service{ ID: "restrictedProxyId", AccountID: "testAccountId", Name: "Restricted Proxy", @@ -85,7 +85,7 @@ func createTestProxies(t *testing.T, ctx context.Context, testStore store.Store) }, }, } - require.NoError(t, testStore.CreateReverseProxy(ctx, restrictedProxy)) + require.NoError(t, testStore.CreateService(ctx, restrictedProxy)) } func generateSessionKeyPair(t *testing.T) (string, string) { @@ -106,7 +106,7 @@ func TestValidateSession_UserAllowed(t *testing.T) { setup := setupValidateSessionTest(t) defer setup.cleanup() - proxy, err := setup.store.GetReverseProxyByID(context.Background(), store.LockingStrengthNone, "testAccountId", "testProxyId") + proxy, err := setup.store.GetServiceByID(context.Background(), store.LockingStrengthNone, "testAccountId", "testProxyId") require.NoError(t, err) token := createSessionToken(t, proxy.SessionPrivateKey, "allowedUserId", "test-proxy.example.com") @@ -126,7 +126,7 @@ func TestValidateSession_UserNotInAllowedGroup(t *testing.T) { setup := setupValidateSessionTest(t) defer setup.cleanup() - proxy, err := setup.store.GetReverseProxyByID(context.Background(), store.LockingStrengthNone, "testAccountId", "restrictedProxyId") + proxy, err := setup.store.GetServiceByID(context.Background(), store.LockingStrengthNone, "testAccountId", "restrictedProxyId") require.NoError(t, err) token := createSessionToken(t, proxy.SessionPrivateKey, "nonGroupUserId", "restricted-proxy.example.com") @@ -146,7 +146,7 @@ func TestValidateSession_UserInDifferentAccount(t *testing.T) { setup := setupValidateSessionTest(t) defer setup.cleanup() - proxy, err := setup.store.GetReverseProxyByID(context.Background(), store.LockingStrengthNone, "testAccountId", "testProxyId") + proxy, err := setup.store.GetServiceByID(context.Background(), store.LockingStrengthNone, "testAccountId", "testProxyId") require.NoError(t, err) token := createSessionToken(t, proxy.SessionPrivateKey, "otherAccountUserId", "test-proxy.example.com") @@ -165,7 +165,7 @@ func TestValidateSession_UserNotFound(t *testing.T) { setup := setupValidateSessionTest(t) defer setup.cleanup() - proxy, err := setup.store.GetReverseProxyByID(context.Background(), store.LockingStrengthNone, "testAccountId", "testProxyId") + proxy, err := setup.store.GetServiceByID(context.Background(), store.LockingStrengthNone, "testAccountId", "testProxyId") require.NoError(t, err) token := createSessionToken(t, proxy.SessionPrivateKey, "nonExistentUserId", "test-proxy.example.com") @@ -184,7 +184,7 @@ func TestValidateSession_ProxyNotFound(t *testing.T) { setup := setupValidateSessionTest(t) defer setup.cleanup() - proxy, err := setup.store.GetReverseProxyByID(context.Background(), store.LockingStrengthNone, "testAccountId", "testProxyId") + proxy, err := setup.store.GetServiceByID(context.Background(), store.LockingStrengthNone, "testAccountId", "testProxyId") require.NoError(t, err) token := createSessionToken(t, proxy.SessionPrivateKey, "allowedUserId", "unknown-proxy.example.com") @@ -243,23 +243,23 @@ type testValidateSessionProxyManager struct { store store.Store } -func (m *testValidateSessionProxyManager) GetAllReverseProxies(_ context.Context, _, _ string) ([]*reverseproxy.ReverseProxy, error) { +func (m *testValidateSessionProxyManager) GetAllServices(_ context.Context, _, _ string) ([]*reverseproxy.Service, error) { return nil, nil } -func (m *testValidateSessionProxyManager) GetReverseProxy(_ context.Context, _, _, _ string) (*reverseproxy.ReverseProxy, error) { +func (m *testValidateSessionProxyManager) GetService(_ context.Context, _, _, _ string) (*reverseproxy.Service, error) { return nil, nil } -func (m *testValidateSessionProxyManager) CreateReverseProxy(_ context.Context, _, _ string, _ *reverseproxy.ReverseProxy) (*reverseproxy.ReverseProxy, error) { +func (m *testValidateSessionProxyManager) CreateService(_ context.Context, _, _ string, _ *reverseproxy.Service) (*reverseproxy.Service, error) { return nil, nil } -func (m *testValidateSessionProxyManager) UpdateReverseProxy(_ context.Context, _, _ string, _ *reverseproxy.ReverseProxy) (*reverseproxy.ReverseProxy, error) { +func (m *testValidateSessionProxyManager) UpdateService(_ context.Context, _, _ string, _ *reverseproxy.Service) (*reverseproxy.Service, error) { return nil, nil } -func (m *testValidateSessionProxyManager) DeleteReverseProxy(_ context.Context, _, _, _ string) error { +func (m *testValidateSessionProxyManager) DeleteService(_ context.Context, _, _, _ string) error { return nil } @@ -271,27 +271,27 @@ func (m *testValidateSessionProxyManager) SetStatus(_ context.Context, _, _ stri return nil } -func (m *testValidateSessionProxyManager) ReloadAllReverseProxiesForAccount(_ context.Context, _ string) error { +func (m *testValidateSessionProxyManager) ReloadAllServicesForAccount(_ context.Context, _ string) error { return nil } -func (m *testValidateSessionProxyManager) ReloadReverseProxy(_ context.Context, _, _ string) error { +func (m *testValidateSessionProxyManager) ReloadService(_ context.Context, _, _ string) error { return nil } -func (m *testValidateSessionProxyManager) GetGlobalReverseProxies(ctx context.Context) ([]*reverseproxy.ReverseProxy, error) { - return m.store.GetReverseProxies(ctx, store.LockingStrengthNone) +func (m *testValidateSessionProxyManager) GetGlobalServices(ctx context.Context) ([]*reverseproxy.Service, error) { + return m.store.GetServices(ctx, store.LockingStrengthNone) } -func (m *testValidateSessionProxyManager) GetProxyByID(ctx context.Context, accountID, proxyID string) (*reverseproxy.ReverseProxy, error) { - return m.store.GetReverseProxyByID(ctx, store.LockingStrengthNone, accountID, proxyID) +func (m *testValidateSessionProxyManager) GetServiceByID(ctx context.Context, accountID, proxyID string) (*reverseproxy.Service, error) { + return m.store.GetServiceByID(ctx, store.LockingStrengthNone, accountID, proxyID) } -func (m *testValidateSessionProxyManager) GetAccountReverseProxies(ctx context.Context, accountID string) ([]*reverseproxy.ReverseProxy, error) { - return m.store.GetAccountReverseProxies(ctx, store.LockingStrengthNone, accountID) +func (m *testValidateSessionProxyManager) GetAccountServices(ctx context.Context, accountID string) ([]*reverseproxy.Service, error) { + return m.store.GetAccountServices(ctx, store.LockingStrengthNone, accountID) } -func (m *testValidateSessionProxyManager) GetProxyIDByTargetID(_ context.Context, _, _ string) (string, error) { +func (m *testValidateSessionProxyManager) GetServiceIDByTargetID(_ context.Context, _, _ string) (string, error) { return "", nil } diff --git a/management/server/account.go b/management/server/account.go index 30b129856..7b858c223 100644 --- a/management/server/account.go +++ b/management/server/account.go @@ -115,8 +115,8 @@ type DefaultAccountManager struct { var _ account.Manager = (*DefaultAccountManager)(nil) -func (am *DefaultAccountManager) SetReverseProxyManager(reverseProxyManager reverseproxy.Manager) { - am.reverseProxyManager = reverseProxyManager +func (am *DefaultAccountManager) SetServiceManager(serviceManager reverseproxy.Manager) { + am.reverseProxyManager = serviceManager } func isUniqueConstraintError(err error) bool { @@ -327,8 +327,8 @@ func (am *DefaultAccountManager) UpdateAccountSettings(ctx context.Context, acco if err = am.reallocateAccountPeerIPs(ctx, transaction, accountID, newSettings.NetworkRange); err != nil { return err } - if err = am.reverseProxyManager.ReloadAllReverseProxiesForAccount(ctx, accountID); err != nil { - log.WithContext(ctx).Warnf("failed to reload all reverse proxy for account %s: %v", accountID, err) + if err = am.reverseProxyManager.ReloadAllServicesForAccount(ctx, accountID); err != nil { + log.WithContext(ctx).Warnf("failed to reload all services for account %s: %v", accountID, err) } updateAccountPeers = true } diff --git a/management/server/account/manager.go b/management/server/account/manager.go index ae92d679e..207ab71d6 100644 --- a/management/server/account/manager.go +++ b/management/server/account/manager.go @@ -140,5 +140,5 @@ type Manager interface { CreatePeerJob(ctx context.Context, accountID, peerID, userID string, job *types.Job) error GetAllPeerJobs(ctx context.Context, accountID, userID, peerID string) ([]*types.Job, error) GetPeerJobByID(ctx context.Context, accountID, userID, peerID, jobID string) (*types.Job, error) - SetReverseProxyManager(reverseProxyManager reverseproxy.Manager) + SetServiceManager(serviceManager reverseproxy.Manager) } diff --git a/management/server/activity/codes.go b/management/server/activity/codes.go index 74f1c461a..e1b7e5300 100644 --- a/management/server/activity/codes.go +++ b/management/server/activity/codes.go @@ -204,9 +204,9 @@ const ( UserInviteLinkRegenerated Activity = 106 UserInviteLinkDeleted Activity = 107 - ReverseProxyCreated Activity = 108 - ReverseProxyUpdated Activity = 109 - ReverseProxyDeleted Activity = 110 + ServiceCreated Activity = 108 + ServiceUpdated Activity = 109 + ServiceDeleted Activity = 110 AccountDeleted Activity = 99999 ) @@ -342,9 +342,9 @@ var activityMap = map[Activity]Code{ UserInviteLinkRegenerated: {"User invite link regenerated", "user.invite.link.regenerate"}, UserInviteLinkDeleted: {"User invite link deleted", "user.invite.link.delete"}, - ReverseProxyCreated: {"Reverse proxy created", "reverseproxy.create"}, - ReverseProxyUpdated: {"Reverse proxy updated", "reverseproxy.update"}, - ReverseProxyDeleted: {"Reverse proxy deleted", "reverseproxy.delete"}, + ServiceCreated: {"Service created", "service.create"}, + ServiceUpdated: {"Service updated", "service.update"}, + ServiceDeleted: {"Service deleted", "service.delete"}, } // StringCode returns a string code of the activity diff --git a/management/server/http/handlers/proxy/auth_callback_integration_test.go b/management/server/http/handlers/proxy/auth_callback_integration_test.go index 59f9f8d14..1317c27cd 100644 --- a/management/server/http/handlers/proxy/auth_callback_integration_test.go +++ b/management/server/http/handlers/proxy/auth_callback_integration_test.go @@ -198,7 +198,7 @@ func setupAuthCallbackTest(t *testing.T) *testSetup { usersManager, ) - proxyService.SetProxyManager(&testReverseProxyManager{store: testStore}) + proxyService.SetProxyManager(&testServiceManager{store: testStore}) handler := NewAuthCallbackHandler(proxyService) @@ -227,7 +227,7 @@ func createTestReverseProxies(t *testing.T, ctx context.Context, testStore store pubKey := base64.StdEncoding.EncodeToString(pub) privKey := base64.StdEncoding.EncodeToString(priv) - testProxy := &reverseproxy.ReverseProxy{ + testProxy := &reverseproxy.Service{ ID: "testProxyId", AccountID: "testAccountId", Name: "Test Proxy", @@ -251,9 +251,9 @@ func createTestReverseProxies(t *testing.T, ctx context.Context, testStore store SessionPrivateKey: privKey, SessionPublicKey: pubKey, } - require.NoError(t, testStore.CreateReverseProxy(ctx, testProxy)) + require.NoError(t, testStore.CreateService(ctx, testProxy)) - restrictedProxy := &reverseproxy.ReverseProxy{ + restrictedProxy := &reverseproxy.Service{ ID: "restrictedProxyId", AccountID: "testAccountId", Name: "Restricted Proxy", @@ -277,9 +277,9 @@ func createTestReverseProxies(t *testing.T, ctx context.Context, testStore store SessionPrivateKey: privKey, SessionPublicKey: pubKey, } - require.NoError(t, testStore.CreateReverseProxy(ctx, restrictedProxy)) + require.NoError(t, testStore.CreateService(ctx, restrictedProxy)) - noAuthProxy := &reverseproxy.ReverseProxy{ + noAuthProxy := &reverseproxy.Service{ ID: "noAuthProxyId", AccountID: "testAccountId", Name: "No Auth Proxy", @@ -302,7 +302,7 @@ func createTestReverseProxies(t *testing.T, ctx context.Context, testStore store SessionPrivateKey: privKey, SessionPublicKey: pubKey, } - require.NoError(t, testStore.CreateReverseProxy(ctx, noAuthProxy)) + require.NoError(t, testStore.CreateService(ctx, noAuthProxy)) } func strPtr(s string) *string { @@ -340,60 +340,60 @@ func createTestAccountsAndUsers(t *testing.T, ctx context.Context, testStore sto require.NoError(t, testStore.SaveUser(ctx, allowedUser)) } -// testReverseProxyManager is a minimal implementation for testing. -type testReverseProxyManager struct { +// testServiceManager is a minimal implementation for testing. +type testServiceManager struct { store store.Store } -func (m *testReverseProxyManager) GetAllReverseProxies(_ context.Context, _, _ string) ([]*reverseproxy.ReverseProxy, error) { +func (m *testServiceManager) GetAllServices(_ context.Context, _, _ string) ([]*reverseproxy.Service, error) { return nil, nil } -func (m *testReverseProxyManager) GetReverseProxy(_ context.Context, _, _, _ string) (*reverseproxy.ReverseProxy, error) { +func (m *testServiceManager) GetService(_ context.Context, _, _, _ string) (*reverseproxy.Service, error) { return nil, nil } -func (m *testReverseProxyManager) CreateReverseProxy(_ context.Context, _, _ string, _ *reverseproxy.ReverseProxy) (*reverseproxy.ReverseProxy, error) { +func (m *testServiceManager) CreateService(_ context.Context, _, _ string, _ *reverseproxy.Service) (*reverseproxy.Service, error) { return nil, nil } -func (m *testReverseProxyManager) UpdateReverseProxy(_ context.Context, _, _ string, _ *reverseproxy.ReverseProxy) (*reverseproxy.ReverseProxy, error) { +func (m *testServiceManager) UpdateService(_ context.Context, _, _ string, _ *reverseproxy.Service) (*reverseproxy.Service, error) { return nil, nil } -func (m *testReverseProxyManager) DeleteReverseProxy(_ context.Context, _, _, _ string) error { +func (m *testServiceManager) DeleteService(_ context.Context, _, _, _ string) error { return nil } -func (m *testReverseProxyManager) SetCertificateIssuedAt(_ context.Context, _, _ string) error { +func (m *testServiceManager) SetCertificateIssuedAt(_ context.Context, _, _ string) error { return nil } -func (m *testReverseProxyManager) SetStatus(_ context.Context, _, _ string, _ reverseproxy.ProxyStatus) error { +func (m *testServiceManager) SetStatus(_ context.Context, _, _ string, _ reverseproxy.ProxyStatus) error { return nil } -func (m *testReverseProxyManager) ReloadAllReverseProxiesForAccount(_ context.Context, _ string) error { +func (m *testServiceManager) ReloadAllServicesForAccount(_ context.Context, _ string) error { return nil } -func (m *testReverseProxyManager) ReloadReverseProxy(_ context.Context, _, _ string) error { +func (m *testServiceManager) ReloadService(_ context.Context, _, _ string) error { return nil } -func (m *testReverseProxyManager) GetGlobalReverseProxies(ctx context.Context) ([]*reverseproxy.ReverseProxy, error) { +func (m *testServiceManager) GetGlobalServices(ctx context.Context) ([]*reverseproxy.Service, error) { return m.store.GetReverseProxies(ctx, store.LockingStrengthNone) } -func (m *testReverseProxyManager) GetProxyByID(ctx context.Context, accountID, proxyID string) (*reverseproxy.ReverseProxy, error) { - return m.store.GetReverseProxyByID(ctx, store.LockingStrengthNone, accountID, proxyID) +func (m *testServiceManager) GetServiceByID(ctx context.Context, accountID, proxyID string) (*reverseproxy.Service, error) { + return m.store.GetServiceByID(ctx, store.LockingStrengthNone, accountID, proxyID) } -func (m *testReverseProxyManager) GetAccountReverseProxies(ctx context.Context, accountID string) ([]*reverseproxy.ReverseProxy, error) { - return m.store.GetAccountReverseProxies(ctx, store.LockingStrengthNone, accountID) +func (m *testServiceManager) GetAccountServices(ctx context.Context, accountID string) ([]*reverseproxy.Service, error) { + return m.store.GetAccountServices(ctx, store.LockingStrengthNone, accountID) } -func (m *testReverseProxyManager) GetProxyIDByTargetID(_ context.Context, _, _ string) (string, error) { +func (m *testServiceManager) GetServiceIDByTargetID(_ context.Context, _, _ string) (string, error) { return "", nil } @@ -446,7 +446,7 @@ func TestAuthCallback_ProxyNotFound(t *testing.T) { state := createTestState(t, setup.proxyService, "https://test-proxy.example.com/") - require.NoError(t, setup.store.DeleteReverseProxy(context.Background(), "testAccountId", "testProxyId")) + require.NoError(t, setup.store.DeleteService(context.Background(), "testAccountId", "testProxyId")) req := httptest.NewRequest(http.MethodGet, "/reverse-proxy/callback?code=test-auth-code&state="+url.QueryEscape(state), nil) rec := httptest.NewRecorder() diff --git a/management/server/mock_server/account_mock.go b/management/server/mock_server/account_mock.go index 8471d0a94..032b1150f 100644 --- a/management/server/mock_server/account_mock.go +++ b/management/server/mock_server/account_mock.go @@ -12,6 +12,7 @@ import ( "google.golang.org/grpc/status" nbdns "github.com/netbirdio/netbird/dns" + "github.com/netbirdio/netbird/management/internals/modules/reverseproxy" "github.com/netbirdio/netbird/management/server/account" "github.com/netbirdio/netbird/management/server/activity" "github.com/netbirdio/netbird/management/server/idp" @@ -147,6 +148,10 @@ type MockAccountManager struct { DeleteUserInviteFunc func(ctx context.Context, accountID, initiatorUserID, inviteID string) error } +func (am *MockAccountManager) SetServiceManager(serviceManager reverseproxy.Manager) { + // Mock implementation - no-op +} + func (am *MockAccountManager) CreatePeerJob(ctx context.Context, accountID, peerID, userID string, job *types.Job) error { if am.CreatePeerJobFunc != nil { return am.CreatePeerJobFunc(ctx, accountID, peerID, userID, job) diff --git a/management/server/networks/resources/manager.go b/management/server/networks/resources/manager.go index decc61801..843ca93e5 100644 --- a/management/server/networks/resources/manager.go +++ b/management/server/networks/resources/manager.go @@ -264,7 +264,7 @@ func (m *managerImpl) UpdateResource(ctx context.Context, userID string, resourc // TODO: optimize to only reload reverse proxies that are affected by the resource update instead of all of them go func() { - err := m.reverseProxyManager.ReloadAllReverseProxiesForAccount(ctx, resource.AccountID) + err := m.reverseProxyManager.ReloadAllServicesForAccount(ctx, resource.AccountID) if err != nil { log.WithContext(ctx).Warnf("failed to reload all proxies for account: %v", err) } @@ -322,12 +322,12 @@ func (m *managerImpl) DeleteResource(ctx context.Context, accountID, userID, net return status.NewPermissionDeniedError() } - proxyID, err := m.reverseProxyManager.GetProxyIDByTargetID(ctx, accountID, resourceID) + serviceID, err := m.reverseProxyManager.GetServiceIDByTargetID(ctx, accountID, resourceID) if err != nil { - return fmt.Errorf("failed to check if resource is used by reverse proxy: %w", err) + return fmt.Errorf("failed to check if resource is used by service: %w", err) } - if proxyID != "" { - return status.NewResourceInUseError(resourceID, proxyID) + if serviceID != "" { + return status.NewResourceInUseError(resourceID, serviceID) } var events []func() diff --git a/management/server/peer.go b/management/server/peer.go index 1297662e8..86e76e13d 100644 --- a/management/server/peer.go +++ b/management/server/peer.go @@ -489,12 +489,12 @@ func (am *DefaultAccountManager) DeletePeer(ctx context.Context, accountID, peer var settings *types.Settings var eventsToStore []func() - proxyID, err := am.reverseProxyManager.GetProxyIDByTargetID(ctx, accountID, peerID) + serviceID, err := am.reverseProxyManager.GetServiceIDByTargetID(ctx, accountID, peerID) if err != nil { - return fmt.Errorf("failed to check if resource is used by reverse proxy: %w", err) + return fmt.Errorf("failed to check if resource is used by service: %w", err) } - if proxyID != "" { - return status.NewPeerInUseError(peerID, proxyID) + if serviceID != "" { + return status.NewPeerInUseError(peerID, serviceID) } err = am.Store.ExecuteInTransaction(ctx, func(transaction store.Store) error { diff --git a/management/server/store/sql_store.go b/management/server/store/sql_store.go index 4262764c3..98b1cd21e 100644 --- a/management/server/store/sql_store.go +++ b/management/server/store/sql_store.go @@ -131,7 +131,7 @@ func NewSqlStore(ctx context.Context, db *gorm.DB, storeEngine types.Engine, met &types.Account{}, &types.Policy{}, &types.PolicyRule{}, &route.Route{}, &nbdns.NameServerGroup{}, &installation{}, &types.ExtraSettings{}, &posture.Checks{}, &nbpeer.NetworkAddress{}, &networkTypes.Network{}, &routerTypes.NetworkRouter{}, &resourceTypes.NetworkResource{}, &types.AccountOnboarding{}, - &types.Job{}, &zones.Zone{}, &records.Record{}, &types.UserInviteRecord{}, &reverseproxy.ReverseProxy{}, &reverseproxy.Target{}, &domain.Domain{}, + &types.Job{}, &zones.Zone{}, &records.Record{}, &types.UserInviteRecord{}, &reverseproxy.Service{}, &reverseproxy.Target{}, &domain.Domain{}, &accesslogs.AccessLogEntry{}, ) if err != nil { @@ -1281,12 +1281,12 @@ func (s *SqlStore) getAccountPgx(ctx context.Context, accountID string) (*types. wg.Add(1) go func() { defer wg.Done() - proxies, err := s.getProxies(ctx, accountID) + services, err := s.getServices(ctx, accountID) if err != nil { errChan <- err return } - account.ReverseProxies = proxies + account.Services = services }() wg.Add(1) @@ -2063,39 +2063,39 @@ func (s *SqlStore) getPostureChecks(ctx context.Context, accountID string) ([]*p return checks, nil } -func (s *SqlStore) getProxies(ctx context.Context, accountID string) ([]*reverseproxy.ReverseProxy, error) { - const proxyQuery = `SELECT id, account_id, name, domain, enabled, auth, +func (s *SqlStore) getServices(ctx context.Context, accountID string) ([]*reverseproxy.Service, error) { + const serviceQuery = `SELECT id, account_id, name, domain, enabled, auth, meta_created_at, meta_certificate_issued_at, meta_status, proxy_cluster, pass_host_header, rewrite_redirects, session_private_key, session_public_key - FROM reverse_proxies WHERE account_id = $1` + FROM services WHERE account_id = $1` - const targetsQuery = `SELECT id, account_id, reverse_proxy_id, path, host, port, protocol, + const targetsQuery = `SELECT id, account_id, service_id, path, host, port, protocol, target_id, target_type, enabled - FROM targets WHERE reverse_proxy_id = ANY($1)` + FROM targets WHERE service_id = ANY($1)` - proxyRows, err := s.pool.Query(ctx, proxyQuery, accountID) + serviceRows, err := s.pool.Query(ctx, serviceQuery, accountID) if err != nil { return nil, err } - proxies, err := pgx.CollectRows(proxyRows, func(row pgx.CollectableRow) (*reverseproxy.ReverseProxy, error) { - var p reverseproxy.ReverseProxy + services, err := pgx.CollectRows(serviceRows, func(row pgx.CollectableRow) (*reverseproxy.Service, error) { + var s reverseproxy.Service var auth []byte var createdAt, certIssuedAt sql.NullTime var status, proxyCluster, sessionPrivateKey, sessionPublicKey sql.NullString err := row.Scan( - &p.ID, - &p.AccountID, - &p.Name, - &p.Domain, - &p.Enabled, + &s.ID, + &s.AccountID, + &s.Name, + &s.Domain, + &s.Enabled, &auth, &createdAt, &certIssuedAt, &status, &proxyCluster, - &p.PassHostHeader, - &p.RewriteRedirects, + &s.PassHostHeader, + &s.RewriteRedirects, &sessionPrivateKey, &sessionPublicKey, ) @@ -2104,50 +2104,50 @@ func (s *SqlStore) getProxies(ctx context.Context, accountID string) ([]*reverse } if auth != nil { - if err := json.Unmarshal(auth, &p.Auth); err != nil { + if err := json.Unmarshal(auth, &s.Auth); err != nil { return nil, err } } - p.Meta = reverseproxy.ReverseProxyMeta{} + s.Meta = reverseproxy.ServiceMeta{} if createdAt.Valid { - p.Meta.CreatedAt = createdAt.Time + s.Meta.CreatedAt = createdAt.Time } if certIssuedAt.Valid { - p.Meta.CertificateIssuedAt = certIssuedAt.Time + s.Meta.CertificateIssuedAt = certIssuedAt.Time } if status.Valid { - p.Meta.Status = status.String + s.Meta.Status = status.String } if proxyCluster.Valid { - p.ProxyCluster = proxyCluster.String + s.ProxyCluster = proxyCluster.String } if sessionPrivateKey.Valid { - p.SessionPrivateKey = sessionPrivateKey.String + s.SessionPrivateKey = sessionPrivateKey.String } if sessionPublicKey.Valid { - p.SessionPublicKey = sessionPublicKey.String + s.SessionPublicKey = sessionPublicKey.String } - p.Targets = []*reverseproxy.Target{} - return &p, nil + s.Targets = []*reverseproxy.Target{} + return &s, nil }) if err != nil { return nil, err } - if len(proxies) == 0 { - return proxies, nil + if len(services) == 0 { + return services, nil } - proxyIDs := make([]string, len(proxies)) - proxyMap := make(map[string]*reverseproxy.ReverseProxy) - for i, p := range proxies { - proxyIDs[i] = p.ID - proxyMap[p.ID] = p + serviceIDs := make([]string, len(services)) + serviceMap := make(map[string]*reverseproxy.Service) + for i, s := range services { + serviceIDs[i] = s.ID + serviceMap[s.ID] = s } - targetRows, err := s.pool.Query(ctx, targetsQuery, proxyIDs) + targetRows, err := s.pool.Query(ctx, targetsQuery, serviceIDs) if err != nil { return nil, err } @@ -2158,7 +2158,7 @@ func (s *SqlStore) getProxies(ctx context.Context, accountID string) ([]*reverse err := row.Scan( &t.ID, &t.AccountID, - &t.ReverseProxyID, + &t.ServiceID, &path, &t.Host, &t.Port, @@ -2180,12 +2180,12 @@ func (s *SqlStore) getProxies(ctx context.Context, accountID string) ([]*reverse } for _, target := range targets { - if proxy, ok := proxyMap[target.ReverseProxyID]; ok { - proxy.Targets = append(proxy.Targets, target) + if service, ok := serviceMap[target.ServiceID]; ok { + service.Targets = append(service.Targets, target) } } - return proxies, nil + return services, nil } func (s *SqlStore) getNetworks(ctx context.Context, accountID string) ([]*networkTypes.Network, error) { @@ -4825,35 +4825,35 @@ func (s *SqlStore) GetPeerIDByKey(ctx context.Context, lockStrength LockingStren return peerID, nil } -func (s *SqlStore) CreateReverseProxy(ctx context.Context, proxy *reverseproxy.ReverseProxy) error { - proxyCopy := proxy.Copy() - if err := proxyCopy.EncryptSensitiveData(s.fieldEncrypt); err != nil { - return fmt.Errorf("encrypt reverse proxy data: %w", err) +func (s *SqlStore) CreateService(ctx context.Context, service *reverseproxy.Service) error { + serviceCopy := service.Copy() + if err := serviceCopy.EncryptSensitiveData(s.fieldEncrypt); err != nil { + return fmt.Errorf("encrypt service data: %w", err) } - result := s.db.Create(proxyCopy) + result := s.db.Create(serviceCopy) if result.Error != nil { - log.WithContext(ctx).Errorf("failed to create reverse proxy to store: %v", result.Error) - return status.Errorf(status.Internal, "failed to create reverse proxy to store") + log.WithContext(ctx).Errorf("failed to create service to store: %v", result.Error) + return status.Errorf(status.Internal, "failed to create service to store") } return nil } -func (s *SqlStore) UpdateReverseProxy(ctx context.Context, proxy *reverseproxy.ReverseProxy) error { - proxyCopy := proxy.Copy() - if err := proxyCopy.EncryptSensitiveData(s.fieldEncrypt); err != nil { - return fmt.Errorf("encrypt reverse proxy data: %w", err) +func (s *SqlStore) UpdateService(ctx context.Context, service *reverseproxy.Service) error { + serviceCopy := service.Copy() + if err := serviceCopy.EncryptSensitiveData(s.fieldEncrypt); err != nil { + return fmt.Errorf("encrypt service data: %w", err) } - // Use a transaction to ensure atomic updates of the proxy and its targets + // Use a transaction to ensure atomic updates of the service and its targets err := s.db.Transaction(func(tx *gorm.DB) error { // Delete existing targets - if err := tx.Where("reverse_proxy_id = ?", proxyCopy.ID).Delete(&reverseproxy.Target{}).Error; err != nil { + if err := tx.Where("service_id = ?", serviceCopy.ID).Delete(&reverseproxy.Target{}).Error; err != nil { return err } - // Update the proxy and create new targets - if err := tx.Session(&gorm.Session{FullSaveAssociations: true}).Save(proxyCopy).Error; err != nil { + // Update the service and create new targets + if err := tx.Session(&gorm.Session{FullSaveAssociations: true}).Save(serviceCopy).Error; err != nil { return err } @@ -4861,112 +4861,112 @@ func (s *SqlStore) UpdateReverseProxy(ctx context.Context, proxy *reverseproxy.R }) if err != nil { - log.WithContext(ctx).Errorf("failed to update reverse proxy to store: %v", err) - return status.Errorf(status.Internal, "failed to update reverse proxy to store") + log.WithContext(ctx).Errorf("failed to update service to store: %v", err) + return status.Errorf(status.Internal, "failed to update service to store") } return nil } -func (s *SqlStore) DeleteReverseProxy(ctx context.Context, accountID, proxyID string) error { - result := s.db.Delete(&reverseproxy.ReverseProxy{}, accountAndIDQueryCondition, accountID, proxyID) +func (s *SqlStore) DeleteService(ctx context.Context, accountID, serviceID string) error { + result := s.db.Delete(&reverseproxy.Service{}, accountAndIDQueryCondition, accountID, serviceID) if result.Error != nil { - log.WithContext(ctx).Errorf("failed to delete reverse proxy from store: %v", result.Error) - return status.Errorf(status.Internal, "failed to delete reverse proxy from store") + log.WithContext(ctx).Errorf("failed to delete service from store: %v", result.Error) + return status.Errorf(status.Internal, "failed to delete service from store") } if result.RowsAffected == 0 { - return status.Errorf(status.NotFound, "reverse proxy %s not found", proxyID) + return status.Errorf(status.NotFound, "service %s not found", serviceID) } return nil } -func (s *SqlStore) GetReverseProxyByID(ctx context.Context, lockStrength LockingStrength, accountID, proxyID string) (*reverseproxy.ReverseProxy, error) { +func (s *SqlStore) GetServiceByID(ctx context.Context, lockStrength LockingStrength, accountID, serviceID string) (*reverseproxy.Service, error) { tx := s.db.Preload("Targets") if lockStrength != LockingStrengthNone { tx = tx.Clauses(clause.Locking{Strength: string(lockStrength)}) } - var proxy *reverseproxy.ReverseProxy - result := tx.Take(&proxy, accountAndIDQueryCondition, accountID, proxyID) + var service *reverseproxy.Service + result := tx.Take(&service, accountAndIDQueryCondition, accountID, serviceID) if result.Error != nil { if errors.Is(result.Error, gorm.ErrRecordNotFound) { - return nil, status.Errorf(status.NotFound, "reverse proxy %s not found", proxyID) + return nil, status.Errorf(status.NotFound, "service %s not found", serviceID) } - log.WithContext(ctx).Errorf("failed to get reverse proxy from store: %v", result.Error) - return nil, status.Errorf(status.Internal, "failed to get reverse proxy from store") + log.WithContext(ctx).Errorf("failed to get service from store: %v", result.Error) + return nil, status.Errorf(status.Internal, "failed to get service from store") } - if err := proxy.DecryptSensitiveData(s.fieldEncrypt); err != nil { - return nil, fmt.Errorf("decrypt reverse proxy data: %w", err) + if err := service.DecryptSensitiveData(s.fieldEncrypt); err != nil { + return nil, fmt.Errorf("decrypt service data: %w", err) } - return proxy, nil + return service, nil } -func (s *SqlStore) GetReverseProxyByDomain(ctx context.Context, accountID, domain string) (*reverseproxy.ReverseProxy, error) { - var proxy *reverseproxy.ReverseProxy - result := s.db.Preload("Targets").Where("account_id = ? AND domain = ?", accountID, domain).First(&proxy) +func (s *SqlStore) GetServiceByDomain(ctx context.Context, accountID, domain string) (*reverseproxy.Service, error) { + var service *reverseproxy.Service + result := s.db.Preload("Targets").Where("account_id = ? AND domain = ?", accountID, domain).First(&service) if result.Error != nil { if errors.Is(result.Error, gorm.ErrRecordNotFound) { - return nil, status.Errorf(status.NotFound, "reverse proxy with domain %s not found", domain) + return nil, status.Errorf(status.NotFound, "service with domain %s not found", domain) } - log.WithContext(ctx).Errorf("failed to get reverse proxy by domain from store: %v", result.Error) - return nil, status.Errorf(status.Internal, "failed to get reverse proxy by domain from store") + log.WithContext(ctx).Errorf("failed to get service by domain from store: %v", result.Error) + return nil, status.Errorf(status.Internal, "failed to get service by domain from store") } - if err := proxy.DecryptSensitiveData(s.fieldEncrypt); err != nil { - return nil, fmt.Errorf("decrypt reverse proxy data: %w", err) + if err := service.DecryptSensitiveData(s.fieldEncrypt); err != nil { + return nil, fmt.Errorf("decrypt service data: %w", err) } - return proxy, nil + return service, nil } -func (s *SqlStore) GetReverseProxies(ctx context.Context, lockStrength LockingStrength) ([]*reverseproxy.ReverseProxy, error) { +func (s *SqlStore) GetServices(ctx context.Context, lockStrength LockingStrength) ([]*reverseproxy.Service, error) { tx := s.db.Preload("Targets") if lockStrength != LockingStrengthNone { tx = tx.Clauses(clause.Locking{Strength: string(lockStrength)}) } - var proxyList []*reverseproxy.ReverseProxy - result := tx.Find(&proxyList) + var serviceList []*reverseproxy.Service + result := tx.Find(&serviceList) if result.Error != nil { - log.WithContext(ctx).Errorf("failed to get reverse proxy from the store: %s", result.Error) - return nil, status.Errorf(status.Internal, "failed to get reverse proxy from store") + log.WithContext(ctx).Errorf("failed to get services from the store: %s", result.Error) + return nil, status.Errorf(status.Internal, "failed to get services from store") } - for _, proxy := range proxyList { - if err := proxy.DecryptSensitiveData(s.fieldEncrypt); err != nil { - return nil, fmt.Errorf("decrypt reverse proxy data: %w", err) + for _, service := range serviceList { + if err := service.DecryptSensitiveData(s.fieldEncrypt); err != nil { + return nil, fmt.Errorf("decrypt service data: %w", err) } } - return proxyList, nil + return serviceList, nil } -func (s *SqlStore) GetAccountReverseProxies(ctx context.Context, lockStrength LockingStrength, accountID string) ([]*reverseproxy.ReverseProxy, error) { +func (s *SqlStore) GetAccountServices(ctx context.Context, lockStrength LockingStrength, accountID string) ([]*reverseproxy.Service, error) { tx := s.db.Preload("Targets") if lockStrength != LockingStrengthNone { tx = tx.Clauses(clause.Locking{Strength: string(lockStrength)}) } - var proxyList []*reverseproxy.ReverseProxy - result := tx.Find(&proxyList, accountIDCondition, accountID) + var serviceList []*reverseproxy.Service + result := tx.Find(&serviceList, accountIDCondition, accountID) if result.Error != nil { - log.WithContext(ctx).Errorf("failed to get reverse proxy from the store: %s", result.Error) - return nil, status.Errorf(status.Internal, "failed to get reverse proxy from store") + log.WithContext(ctx).Errorf("failed to get services from the store: %s", result.Error) + return nil, status.Errorf(status.Internal, "failed to get services from store") } - for _, proxy := range proxyList { - if err := proxy.DecryptSensitiveData(s.fieldEncrypt); err != nil { - return nil, fmt.Errorf("decrypt reverse proxy data: %w", err) + for _, service := range serviceList { + if err := service.DecryptSensitiveData(s.fieldEncrypt); err != nil { + return nil, fmt.Errorf("decrypt service data: %w", err) } } - return proxyList, nil + return serviceList, nil } func (s *SqlStore) GetCustomDomain(ctx context.Context, accountID string, domainID string) (*domain.Domain, error) { @@ -4976,11 +4976,11 @@ func (s *SqlStore) GetCustomDomain(ctx context.Context, accountID string, domain result := tx.Take(&customDomain, accountAndIDQueryCondition, accountID, domainID) if result.Error != nil { if errors.Is(result.Error, gorm.ErrRecordNotFound) { - return nil, status.Errorf(status.NotFound, "reverse proxy custom domain %s not found", domainID) + return nil, status.Errorf(status.NotFound, "custom domain %s not found", domainID) } - log.WithContext(ctx).Errorf("failed to get reverse proxy custom domain from store: %v", result.Error) - return nil, status.Errorf(status.Internal, "failed to get reverse proxy custom domain from store") + log.WithContext(ctx).Errorf("failed to get custom domain from store: %v", result.Error) + return nil, status.Errorf(status.Internal, "failed to get custom domain from store") } return customDomain, nil @@ -5051,10 +5051,10 @@ func (s *SqlStore) CreateAccessLog(ctx context.Context, logEntry *accesslogs.Acc result := s.db.Create(logEntry) if result.Error != nil { log.WithContext(ctx).WithFields(log.Fields{ - "proxy_id": logEntry.ProxyID, - "method": logEntry.Method, - "host": logEntry.Host, - "path": logEntry.Path, + "service_id": logEntry.ServiceID, + "method": logEntry.Method, + "host": logEntry.Host, + "path": logEntry.Path, }).Errorf("failed to create access log entry in store: %v", result.Error) return status.Errorf(status.Internal, "failed to create access log entry in store") } @@ -5154,7 +5154,7 @@ func (s *SqlStore) applyAccessLogFilters(query *gorm.DB, filter accesslogs.Acces return query } -func (s *SqlStore) GetReverseProxyTargetByTargetID(ctx context.Context, lockStrength LockingStrength, accountID string, targetID string) (*reverseproxy.Target, error) { +func (s *SqlStore) GetServiceTargetByTargetID(ctx context.Context, lockStrength LockingStrength, accountID string, targetID string) (*reverseproxy.Target, error) { tx := s.db if lockStrength != LockingStrengthNone { tx = tx.Clauses(clause.Locking{Strength: string(lockStrength)}) @@ -5164,11 +5164,11 @@ func (s *SqlStore) GetReverseProxyTargetByTargetID(ctx context.Context, lockStre result := tx.Take(&target, "account_id = ? AND target_id = ?", accountID, targetID) if result.Error != nil { if errors.Is(result.Error, gorm.ErrRecordNotFound) { - return nil, status.Errorf(status.NotFound, "reverse proxy target with ID %s not found", targetID) + return nil, status.Errorf(status.NotFound, "service target with ID %s not found", targetID) } - log.WithContext(ctx).Errorf("failed to get reverse proxy target from store: %v", result.Error) - return nil, status.Errorf(status.Internal, "failed to get reverse proxy target from store") + log.WithContext(ctx).Errorf("failed to get service target from store: %v", result.Error) + return nil, status.Errorf(status.Internal, "failed to get service target from store") } return target, nil diff --git a/management/server/store/store.go b/management/server/store/store.go index 6afad460f..df4f8cf4d 100644 --- a/management/server/store/store.go +++ b/management/server/store/store.go @@ -250,13 +250,13 @@ type Store interface { MarkAllPendingJobsAsFailed(ctx context.Context, accountID, peerID, reason string) error GetPeerIDByKey(ctx context.Context, lockStrength LockingStrength, key string) (string, error) - CreateReverseProxy(ctx context.Context, service *reverseproxy.ReverseProxy) error - UpdateReverseProxy(ctx context.Context, service *reverseproxy.ReverseProxy) error - DeleteReverseProxy(ctx context.Context, accountID, serviceID string) error - GetReverseProxyByID(ctx context.Context, lockStrength LockingStrength, accountID, serviceID string) (*reverseproxy.ReverseProxy, error) - GetReverseProxyByDomain(ctx context.Context, accountID, domain string) (*reverseproxy.ReverseProxy, error) - GetReverseProxies(ctx context.Context, lockStrength LockingStrength) ([]*reverseproxy.ReverseProxy, error) - GetAccountReverseProxies(ctx context.Context, lockStrength LockingStrength, accountID string) ([]*reverseproxy.ReverseProxy, error) + CreateService(ctx context.Context, service *reverseproxy.Service) error + UpdateService(ctx context.Context, service *reverseproxy.Service) error + DeleteService(ctx context.Context, accountID, serviceID string) error + GetServiceByID(ctx context.Context, lockStrength LockingStrength, accountID, serviceID string) (*reverseproxy.Service, error) + GetServiceByDomain(ctx context.Context, accountID, domain string) (*reverseproxy.Service, error) + GetServices(ctx context.Context, lockStrength LockingStrength) ([]*reverseproxy.Service, error) + GetAccountServices(ctx context.Context, lockStrength LockingStrength, accountID string) ([]*reverseproxy.Service, error) GetCustomDomain(ctx context.Context, accountID string, domainID string) (*domain.Domain, error) ListFreeDomains(ctx context.Context, accountID string) ([]string, error) @@ -267,7 +267,7 @@ type Store interface { CreateAccessLog(ctx context.Context, log *accesslogs.AccessLogEntry) error GetAccountAccessLogs(ctx context.Context, lockStrength LockingStrength, accountID string, filter accesslogs.AccessLogFilter) ([]*accesslogs.AccessLogEntry, int64, error) - GetReverseProxyTargetByTargetID(ctx context.Context, lockStrength LockingStrength, accountID string, targetID string) (*reverseproxy.Target, error) + GetServiceTargetByTargetID(ctx context.Context, lockStrength LockingStrength, accountID string, targetID string) (*reverseproxy.Target, error) } const ( diff --git a/management/server/types/account.go b/management/server/types/account.go index f7efd5e57..c992c07aa 100644 --- a/management/server/types/account.go +++ b/management/server/types/account.go @@ -100,7 +100,7 @@ type Account struct { NameServerGroupsG []nbdns.NameServerGroup `json:"-" gorm:"foreignKey:AccountID;references:id"` DNSSettings DNSSettings `gorm:"embedded;embeddedPrefix:dns_settings_"` PostureChecks []*posture.Checks `gorm:"foreignKey:AccountID;references:id"` - ReverseProxies []*reverseproxy.ReverseProxy `gorm:"foreignKey:AccountID;references:id"` + Services []*reverseproxy.Service `gorm:"foreignKey:AccountID;references:id"` // Settings is a dictionary of Account settings Settings *Settings `gorm:"embedded;embeddedPrefix:settings_"` Networks []*networkTypes.Network `gorm:"foreignKey:AccountID;references:id"` @@ -377,7 +377,7 @@ func (a *Account) GetPeerNetworkMap( // GetProxyConnectionResources returns ACL peers for the proxy-embedded peer based on exposed services. // No firewall rules are generated here; the proxy peer is always a new on-demand client with a stateful // firewall, so OUT rules are unnecessary. Inbound rules are handled on the target/router peer side. -func (a *Account) GetProxyConnectionResources(ctx context.Context, exposedServices map[string][]*reverseproxy.ReverseProxy) []*nbpeer.Peer { +func (a *Account) GetProxyConnectionResources(ctx context.Context, exposedServices map[string][]*reverseproxy.Service) []*nbpeer.Peer { var aclPeers []*nbpeer.Peer for _, peerServices := range exposedServices { @@ -406,7 +406,7 @@ func (a *Account) GetProxyConnectionResources(ctx context.Context, exposedServic // GetPeerProxyResources returns ACL peers and inbound firewall rules for a peer that is targeted by reverse proxy services. // Only IN rules are generated; OUT rules are omitted since proxy peers are always new clients with stateful firewalls. // Rules use PortRange only (not the legacy Port field) as this feature only targets current peer versions. -func (a *Account) GetPeerProxyResources(peerID string, services []*reverseproxy.ReverseProxy, proxyPeers []*nbpeer.Peer) ([]*nbpeer.Peer, []*FirewallRule) { +func (a *Account) GetPeerProxyResources(peerID string, services []*reverseproxy.Service, proxyPeers []*nbpeer.Peer) ([]*nbpeer.Peer, []*FirewallRule) { var aclPeers []*nbpeer.Peer var firewallRules []*FirewallRule @@ -1858,7 +1858,7 @@ func (a *Account) GetProxyPeers() map[string][]*nbpeer.Peer { return proxyPeers } -func (a *Account) GetPeerProxyRoutes(ctx context.Context, peer *nbpeer.Peer, proxies map[string][]*reverseproxy.ReverseProxy, resourcesMap map[string]*resourceTypes.NetworkResource, routers map[string]map[string]*routerTypes.NetworkRouter, proxyPeers []*nbpeer.Peer) ([]*route.Route, []*RouteFirewallRule, []*nbpeer.Peer) { +func (a *Account) GetPeerProxyRoutes(ctx context.Context, peer *nbpeer.Peer, proxies map[string][]*reverseproxy.Service, resourcesMap map[string]*resourceTypes.NetworkResource, routers map[string]map[string]*routerTypes.NetworkRouter, proxyPeers []*nbpeer.Peer) ([]*route.Route, []*RouteFirewallRule, []*nbpeer.Peer) { sourceRanges := make([]string, 0, len(proxyPeers)) for _, proxyPeer := range proxyPeers { sourceRanges = append(sourceRanges, fmt.Sprintf(AllowedIPsFormat, proxyPeer.IP)) @@ -1924,7 +1924,7 @@ func (a *Account) GetResourcesMap() map[string]*resourceTypes.NetworkResource { } func (a *Account) InjectProxyPolicies(ctx context.Context) { - if len(a.ReverseProxies) == 0 { + if len(a.Services) == 0 { return } @@ -1933,7 +1933,7 @@ func (a *Account) InjectProxyPolicies(ctx context.Context) { return } - for _, service := range a.ReverseProxies { + for _, service := range a.Services { if !service.Enabled { continue } diff --git a/management/server/types/proxy_firewall_rules_test.go b/management/server/types/proxy_firewall_rules_test.go deleted file mode 100644 index 5bec34525..000000000 --- a/management/server/types/proxy_firewall_rules_test.go +++ /dev/null @@ -1,409 +0,0 @@ -package types - -import ( - "context" - "net" - "net/netip" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - "github.com/netbirdio/netbird/management/internals/modules/reverseproxy" - resourceTypes "github.com/netbirdio/netbird/management/server/networks/resources/types" - routerTypes "github.com/netbirdio/netbird/management/server/networks/routers/types" - nbpeer "github.com/netbirdio/netbird/management/server/peer" -) - -func TestGetProxyConnectionResources_PeerTarget(t *testing.T) { - account := &Account{ - Peers: map[string]*nbpeer.Peer{ - "target-peer": {ID: "target-peer", IP: net.ParseIP("100.64.0.1")}, - }, - } - - exposedServices := map[string][]*reverseproxy.ReverseProxy{ - "target-peer": { - { - ID: "proxy-1", - Enabled: true, - Targets: []reverseproxy.Target{ - { - TargetType: reverseproxy.TargetTypePeer, - TargetId: "target-peer", - Port: 8080, - Enabled: true, - }, - }, - }, - }, - } - - aclPeers := account.GetProxyConnectionResources(context.Background(), exposedServices) - - require.Len(t, aclPeers, 1) - assert.Equal(t, "target-peer", aclPeers[0].ID) -} - -func TestGetProxyConnectionResources_DisabledService(t *testing.T) { - account := &Account{ - Peers: map[string]*nbpeer.Peer{ - "target-peer": {ID: "target-peer", IP: net.ParseIP("100.64.0.1")}, - }, - } - - exposedServices := map[string][]*reverseproxy.ReverseProxy{ - "target-peer": { - { - ID: "proxy-1", - Enabled: false, - Targets: []reverseproxy.Target{ - { - TargetType: reverseproxy.TargetTypePeer, - TargetId: "target-peer", - Port: 8080, - Enabled: true, - }, - }, - }, - }, - } - - aclPeers := account.GetProxyConnectionResources(context.Background(), exposedServices) - assert.Empty(t, aclPeers) -} - -func TestGetProxyConnectionResources_ResourceTargetSkipped(t *testing.T) { - account := &Account{ - Peers: map[string]*nbpeer.Peer{ - "router-peer": {ID: "router-peer", IP: net.ParseIP("100.64.0.2")}, - }, - } - - exposedServices := map[string][]*reverseproxy.ReverseProxy{ - "router-peer": { - { - ID: "proxy-1", - Enabled: true, - Targets: []reverseproxy.Target{ - { - TargetType: reverseproxy.TargetTypeResource, - TargetId: "resource-1", - Port: 443, - Enabled: true, - }, - }, - }, - }, - } - - aclPeers := account.GetProxyConnectionResources(context.Background(), exposedServices) - assert.Empty(t, aclPeers, "resource targets should not add ACL peers via GetProxyConnectionResources") -} - -func TestGetPeerProxyResources_PeerTarget(t *testing.T) { - proxyPeers := []*nbpeer.Peer{ - {ID: "proxy-peer-1", IP: net.ParseIP("100.64.0.10")}, - {ID: "proxy-peer-2", IP: net.ParseIP("100.64.0.11")}, - } - - services := []*reverseproxy.ReverseProxy{ - { - ID: "proxy-1", - Enabled: true, - Targets: []reverseproxy.Target{ - { - TargetType: reverseproxy.TargetTypePeer, - TargetId: "target-peer", - Port: 8080, - Enabled: true, - }, - }, - }, - } - - account := &Account{} - aclPeers, fwRules := account.GetPeerProxyResources("target-peer", services, proxyPeers) - - require.Len(t, aclPeers, 2, "should include all proxy peers") - require.Len(t, fwRules, 2, "should have one IN rule per proxy peer") - - for i, rule := range fwRules { - assert.Equal(t, "proxy-proxy-1", rule.PolicyID) - assert.Equal(t, proxyPeers[i].IP.String(), rule.PeerIP) - assert.Equal(t, FirewallRuleDirectionIN, rule.Direction) - assert.Equal(t, "allow", rule.Action) - assert.Equal(t, string(PolicyRuleProtocolTCP), rule.Protocol) - assert.Equal(t, uint16(8080), rule.PortRange.Start) - assert.Equal(t, uint16(8080), rule.PortRange.End) - } -} - -func TestGetPeerProxyResources_PeerTargetMismatch(t *testing.T) { - proxyPeers := []*nbpeer.Peer{ - {ID: "proxy-peer-1", IP: net.ParseIP("100.64.0.10")}, - } - - services := []*reverseproxy.ReverseProxy{ - { - ID: "proxy-1", - Enabled: true, - Targets: []reverseproxy.Target{ - { - TargetType: reverseproxy.TargetTypePeer, - TargetId: "other-peer", - Port: 8080, - Enabled: true, - }, - }, - }, - } - - account := &Account{} - aclPeers, fwRules := account.GetPeerProxyResources("target-peer", services, proxyPeers) - - require.Len(t, aclPeers, 1, "should still add proxy peers to ACL") - assert.Empty(t, fwRules, "should not generate rules when target doesn't match this peer") -} - -func TestGetPeerProxyResources_ResourceAccessLocal(t *testing.T) { - proxyPeers := []*nbpeer.Peer{ - {ID: "proxy-peer-1", IP: net.ParseIP("100.64.0.10")}, - } - - services := []*reverseproxy.ReverseProxy{ - { - ID: "proxy-1", - Enabled: true, - Targets: []reverseproxy.Target{ - { - TargetType: reverseproxy.TargetTypeResource, - TargetId: "resource-1", - Port: 443, - Enabled: true, - AccessLocal: true, - }, - }, - }, - } - - account := &Account{} - aclPeers, fwRules := account.GetPeerProxyResources("router-peer", services, proxyPeers) - - require.Len(t, aclPeers, 1, "should include proxy peers in ACL") - require.Len(t, fwRules, 1, "should generate IN rule for AccessLocal resource") - - rule := fwRules[0] - assert.Equal(t, "proxy-proxy-1", rule.PolicyID) - assert.Equal(t, "100.64.0.10", rule.PeerIP) - assert.Equal(t, FirewallRuleDirectionIN, rule.Direction) - assert.Equal(t, uint16(443), rule.PortRange.Start) -} - -func TestGetPeerProxyResources_ResourceWithoutAccessLocal(t *testing.T) { - proxyPeers := []*nbpeer.Peer{ - {ID: "proxy-peer-1", IP: net.ParseIP("100.64.0.10")}, - } - - services := []*reverseproxy.ReverseProxy{ - { - ID: "proxy-1", - Enabled: true, - Targets: []reverseproxy.Target{ - { - TargetType: reverseproxy.TargetTypeResource, - TargetId: "resource-1", - Port: 443, - Enabled: true, - AccessLocal: false, - }, - }, - }, - } - - account := &Account{} - aclPeers, fwRules := account.GetPeerProxyResources("router-peer", services, proxyPeers) - - require.Len(t, aclPeers, 1, "should still include proxy peers in ACL") - assert.Empty(t, fwRules, "should not generate peer rules when AccessLocal is false") -} - -func TestGetPeerProxyResources_MixedTargets(t *testing.T) { - proxyPeers := []*nbpeer.Peer{ - {ID: "proxy-peer-1", IP: net.ParseIP("100.64.0.10")}, - } - - services := []*reverseproxy.ReverseProxy{ - { - ID: "proxy-1", - Enabled: true, - Targets: []reverseproxy.Target{ - { - TargetType: reverseproxy.TargetTypePeer, - TargetId: "target-peer", - Port: 8080, - Enabled: true, - }, - { - TargetType: reverseproxy.TargetTypeResource, - TargetId: "resource-1", - Port: 443, - Enabled: true, - AccessLocal: true, - }, - { - TargetType: reverseproxy.TargetTypeResource, - TargetId: "resource-2", - Port: 8443, - Enabled: true, - AccessLocal: false, - }, - }, - }, - } - - account := &Account{} - aclPeers, fwRules := account.GetPeerProxyResources("target-peer", services, proxyPeers) - - require.Len(t, aclPeers, 1) - require.Len(t, fwRules, 2, "should have rules for peer target + AccessLocal resource") - - ports := []uint16{fwRules[0].PortRange.Start, fwRules[1].PortRange.Start} - assert.Contains(t, ports, uint16(8080), "should include peer target port") - assert.Contains(t, ports, uint16(443), "should include AccessLocal resource port") -} - -func newProxyRoutesTestAccount() *Account { - return &Account{ - Peers: map[string]*nbpeer.Peer{ - "router-peer": {ID: "router-peer", Key: "router-key", IP: net.ParseIP("100.64.0.2")}, - "proxy-peer": {ID: "proxy-peer", Key: "proxy-key", IP: net.ParseIP("100.64.0.10")}, - }, - } -} - -func TestGetPeerProxyRoutes_ResourceWithoutAccessLocal(t *testing.T) { - account := newProxyRoutesTestAccount() - proxyPeers := []*nbpeer.Peer{account.Peers["proxy-peer"]} - - resourcesMap := map[string]*resourceTypes.NetworkResource{ - "resource-1": { - ID: "resource-1", - AccountID: "accountID", - NetworkID: "net-1", - Name: "web-service", - Type: resourceTypes.Host, - Prefix: netip.MustParsePrefix("192.168.1.100/32"), - Enabled: true, - }, - } - routers := map[string]map[string]*routerTypes.NetworkRouter{ - "net-1": { - "router-peer": {ID: "router-1", NetworkID: "net-1", Peer: "router-peer", Masquerade: true, Metric: 100}, - }, - } - - exposedServices := map[string][]*reverseproxy.ReverseProxy{ - "router-peer": { - { - ID: "proxy-1", - Enabled: true, - Targets: []reverseproxy.Target{ - { - TargetType: reverseproxy.TargetTypeResource, - TargetId: "resource-1", - Port: 443, - Enabled: true, - AccessLocal: false, - }, - }, - }, - }, - } - - routes, routeFwRules, aclPeers := account.GetPeerProxyRoutes(context.Background(), account.Peers["proxy-peer"], exposedServices, resourcesMap, routers, proxyPeers) - - require.NotEmpty(t, routes, "should generate routes for non-AccessLocal resource") - require.NotEmpty(t, routeFwRules, "should generate route firewall rules for non-AccessLocal resource") - require.NotEmpty(t, aclPeers, "should include router peer in ACL") - - assert.Equal(t, uint16(443), routeFwRules[0].PortRange.Start) - assert.Equal(t, "192.168.1.100/32", routeFwRules[0].Destination) -} - -func TestGetPeerProxyRoutes_ResourceWithAccessLocal(t *testing.T) { - account := newProxyRoutesTestAccount() - proxyPeers := []*nbpeer.Peer{account.Peers["proxy-peer"]} - - resourcesMap := map[string]*resourceTypes.NetworkResource{ - "resource-1": { - ID: "resource-1", - AccountID: "accountID", - NetworkID: "net-1", - Name: "local-service", - Type: resourceTypes.Host, - Prefix: netip.MustParsePrefix("192.168.1.100/32"), - Enabled: true, - }, - } - routers := map[string]map[string]*routerTypes.NetworkRouter{ - "net-1": { - "router-peer": {ID: "router-1", NetworkID: "net-1", Peer: "router-peer", Masquerade: true, Metric: 100}, - }, - } - - exposedServices := map[string][]*reverseproxy.ReverseProxy{ - "router-peer": { - { - ID: "proxy-1", - Enabled: true, - Targets: []reverseproxy.Target{ - { - TargetType: reverseproxy.TargetTypeResource, - TargetId: "resource-1", - Port: 443, - Enabled: true, - AccessLocal: true, - }, - }, - }, - }, - } - - routes, routeFwRules, aclPeers := account.GetPeerProxyRoutes(context.Background(), account.Peers["proxy-peer"], exposedServices, resourcesMap, routers, proxyPeers) - - require.NotEmpty(t, routes, "should generate routes for AccessLocal resource") - require.NotEmpty(t, routeFwRules, "should generate route firewall rules for AccessLocal resource") - require.NotEmpty(t, aclPeers, "should include router peer in ACL for AccessLocal resource") - - assert.Equal(t, uint16(443), routeFwRules[0].PortRange.Start) - assert.Equal(t, "192.168.1.100/32", routeFwRules[0].Destination) -} - -func TestGetPeerProxyRoutes_PeerTargetSkipped(t *testing.T) { - account := newProxyRoutesTestAccount() - proxyPeers := []*nbpeer.Peer{account.Peers["proxy-peer"]} - - exposedServices := map[string][]*reverseproxy.ReverseProxy{ - "router-peer": { - { - ID: "proxy-1", - Enabled: true, - Targets: []reverseproxy.Target{ - { - TargetType: reverseproxy.TargetTypePeer, - TargetId: "target-peer", - Port: 8080, - Enabled: true, - }, - }, - }, - }, - } - - routes, routeFwRules, aclPeers := account.GetPeerProxyRoutes(context.Background(), account.Peers["proxy-peer"], exposedServices, nil, nil, proxyPeers) - - assert.Empty(t, routes, "should NOT generate routes for peer targets") - assert.Empty(t, routeFwRules, "should NOT generate route firewall rules for peer targets") - assert.Empty(t, aclPeers) -} diff --git a/proxy/internal/acme/manager.go b/proxy/internal/acme/manager.go index 586084aed..a663b8138 100644 --- a/proxy/internal/acme/manager.go +++ b/proxy/internal/acme/manager.go @@ -23,7 +23,7 @@ import ( var oidSCTList = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 11129, 2, 4, 2} type certificateNotifier interface { - NotifyCertificateIssued(ctx context.Context, accountID, reverseProxyID, domain string) error + NotifyCertificateIssued(ctx context.Context, accountID, serviceID, domain string) error } type domainState int @@ -35,10 +35,10 @@ const ( ) type domainInfo struct { - accountID string - reverseProxyID string - state domainState - err string + accountID string + serviceID string + state domainState + err string } // Manager wraps autocert.Manager with domain tracking and cross-replica @@ -95,12 +95,12 @@ func (mgr *Manager) hostPolicy(_ context.Context, host string) error { } // AddDomain registers a domain for ACME certificate prefetching. -func (mgr *Manager) AddDomain(d domain.Domain, accountID, reverseProxyID string) { +func (mgr *Manager) AddDomain(d domain.Domain, accountID, serviceID string) { mgr.mu.Lock() mgr.domains[d] = &domainInfo{ - accountID: accountID, - reverseProxyID: reverseProxyID, - state: domainPending, + accountID: accountID, + serviceID: serviceID, + state: domainPending, } mgr.mu.Unlock() @@ -164,7 +164,7 @@ func (mgr *Manager) prefetchCertificate(d domain.Domain) { mgr.mu.RUnlock() if info != nil && mgr.certNotifier != nil { - if err := mgr.certNotifier.NotifyCertificateIssued(ctx, info.accountID, info.reverseProxyID, name); err != nil { + if err := mgr.certNotifier.NotifyCertificateIssued(ctx, info.accountID, info.serviceID, name); err != nil { mgr.logger.Warnf("notify certificate ready for domain %q: %v", name, err) } } diff --git a/proxy/internal/roundtrip/netbird.go b/proxy/internal/roundtrip/netbird.go index 76f3cc8a7..d2fcbcc6d 100644 --- a/proxy/internal/roundtrip/netbird.go +++ b/proxy/internal/roundtrip/netbird.go @@ -35,7 +35,7 @@ var ( // domainInfo holds metadata about a registered domain. type domainInfo struct { - reverseProxyID string + serviceID string } // clientEntry holds an embedded NetBird client and tracks which domains use it. @@ -48,7 +48,7 @@ type clientEntry struct { } type statusNotifier interface { - NotifyStatus(ctx context.Context, accountID, reverseProxyID, domain string, connected bool) error + NotifyStatus(ctx context.Context, accountID, serviceID, domain string, connected bool) error } type managementClient interface { @@ -91,13 +91,13 @@ type accountIDContextKey struct{} // AddPeer registers a domain for an account. If the account doesn't have a client yet, // one is created by authenticating with the management server using the provided token. // Multiple domains can share the same client. -func (n *NetBird) AddPeer(ctx context.Context, accountID types.AccountID, d domain.Domain, authToken, reverseProxyID string) error { +func (n *NetBird) AddPeer(ctx context.Context, accountID types.AccountID, d domain.Domain, authToken, serviceID string) error { n.clientsMux.Lock() entry, exists := n.clients[accountID] if exists { // Client already exists for this account, just register the domain - entry.domains[d] = domainInfo{reverseProxyID: reverseProxyID} + entry.domains[d] = domainInfo{serviceID: serviceID} started := entry.started n.clientsMux.Unlock() @@ -108,7 +108,7 @@ func (n *NetBird) AddPeer(ctx context.Context, accountID types.AccountID, d doma // If client is already started, notify this domain as connected immediately if started && n.statusNotifier != nil { - if err := n.statusNotifier.NotifyStatus(ctx, string(accountID), reverseProxyID, string(d), true); err != nil { + if err := n.statusNotifier.NotifyStatus(ctx, string(accountID), serviceID, string(d), true); err != nil { n.logger.WithFields(log.Fields{ "account_id": accountID, "domain": d, @@ -119,8 +119,8 @@ func (n *NetBird) AddPeer(ctx context.Context, accountID types.AccountID, d doma } n.logger.WithFields(log.Fields{ - "account_id": accountID, - "reverse_proxy_id": reverseProxyID, + "account_id": accountID, + "service_id": serviceID, }).Debug("generating WireGuard keypair for new peer") privateKey, err := wgtypes.GeneratePrivateKey() @@ -131,14 +131,14 @@ func (n *NetBird) AddPeer(ctx context.Context, accountID types.AccountID, d doma publicKey := privateKey.PublicKey() n.logger.WithFields(log.Fields{ - "account_id": accountID, - "reverse_proxy_id": reverseProxyID, - "public_key": publicKey.String(), + "account_id": accountID, + "service_id": serviceID, + "public_key": publicKey.String(), }).Debug("authenticating new proxy peer with management") // Authenticate with management using the one-time token and send public key resp, err := n.mgmtClient.CreateProxyPeer(ctx, &proto.CreateProxyPeerRequest{ - ReverseProxyId: reverseProxyID, + ServiceId: serviceID, AccountId: string(accountID), Token: authToken, WireguardPublicKey: publicKey.String(), @@ -158,9 +158,9 @@ func (n *NetBird) AddPeer(ctx context.Context, accountID types.AccountID, d doma } n.logger.WithFields(log.Fields{ - "account_id": accountID, - "reverse_proxy_id": reverseProxyID, - "public_key": publicKey.String(), + "account_id": accountID, + "service_id": serviceID, + "public_key": publicKey.String(), }).Info("proxy peer authenticated successfully with management") n.initLogOnce.Do(func() { @@ -189,7 +189,7 @@ func (n *NetBird) AddPeer(ctx context.Context, accountID types.AccountID, d doma // not work with reverse proxied requests. entry = &clientEntry{ client: client, - domains: map[domain.Domain]domainInfo{d: {reverseProxyID: reverseProxyID}}, + domains: map[domain.Domain]domainInfo{d: {serviceID: serviceID}}, transport: &http.Transport{ DialContext: client.DialContext, ForceAttemptHTTP2: true, @@ -237,15 +237,15 @@ func (n *NetBird) AddPeer(ctx context.Context, accountID types.AccountID, d doma } // Copy domain info while holding lock var domainsToNotify []struct { - domain domain.Domain - reverseProxyID string + domain domain.Domain + serviceID string } if exists { for dom, info := range entry.domains { domainsToNotify = append(domainsToNotify, struct { - domain domain.Domain - reverseProxyID string - }{domain: dom, reverseProxyID: info.reverseProxyID}) + domain domain.Domain + serviceID string + }{domain: dom, serviceID: info.serviceID}) } } n.clientsMux.Unlock() @@ -253,7 +253,7 @@ func (n *NetBird) AddPeer(ctx context.Context, accountID types.AccountID, d doma // Notify all domains that they're connected if n.statusNotifier != nil { for _, domInfo := range domainsToNotify { - if err := n.statusNotifier.NotifyStatus(ctx, string(accountID), domInfo.reverseProxyID, string(domInfo.domain), true); err != nil { + if err := n.statusNotifier.NotifyStatus(ctx, string(accountID), domInfo.serviceID, string(domInfo.domain), true); err != nil { n.logger.WithFields(log.Fields{ "account_id": accountID, "domain": domInfo.domain, @@ -303,7 +303,7 @@ func (n *NetBird) RemovePeer(ctx context.Context, accountID types.AccountID, d d // Notify this domain as disconnected if n.statusNotifier != nil { - if err := n.statusNotifier.NotifyStatus(ctx, string(accountID), domInfo.reverseProxyID, string(d), false); err != nil { + if err := n.statusNotifier.NotifyStatus(ctx, string(accountID), domInfo.serviceID, string(d), false); err != nil { n.logger.WithFields(log.Fields{ "account_id": accountID, "domain": d, @@ -325,7 +325,7 @@ func (n *NetBird) RemovePeer(ctx context.Context, accountID types.AccountID, d d // Notify disconnection before stopping if n.statusNotifier != nil { - if err := n.statusNotifier.NotifyStatus(ctx, string(accountID), domInfo.reverseProxyID, string(d), false); err != nil { + if err := n.statusNotifier.NotifyStatus(ctx, string(accountID), domInfo.serviceID, string(d), false); err != nil { n.logger.WithFields(log.Fields{ "account_id": accountID, "domain": d, diff --git a/proxy/internal/roundtrip/netbird_bench_test.go b/proxy/internal/roundtrip/netbird_bench_test.go index 070638f1c..e89213c33 100644 --- a/proxy/internal/roundtrip/netbird_bench_test.go +++ b/proxy/internal/roundtrip/netbird_bench_test.go @@ -31,7 +31,7 @@ func BenchmarkHasClient(b *testing.B) { nb.clients[id] = &clientEntry{ domains: map[domain.Domain]domainInfo{ domain.Domain(rand.Text()): { - reverseProxyID: rand.Text(), + serviceID: rand.Text(), }, }, createdAt: time.Now(), @@ -72,7 +72,7 @@ func BenchmarkHasClientDuringAddPeer(b *testing.B) { nb.clients[id] = &clientEntry{ domains: map[domain.Domain]domainInfo{ domain.Domain(rand.Text()): { - reverseProxyID: rand.Text(), + serviceID: rand.Text(), }, }, createdAt: time.Now(), diff --git a/proxy/server.go b/proxy/server.go index a817b729e..656d9f874 100644 --- a/proxy/server.go +++ b/proxy/server.go @@ -106,14 +106,14 @@ type Server struct { } // NotifyStatus sends a status update to management about tunnel connectivity -func (s *Server) NotifyStatus(ctx context.Context, accountID, reverseProxyID, domain string, connected bool) error { +func (s *Server) NotifyStatus(ctx context.Context, accountID, serviceID, domain string, connected bool) error { status := proto.ProxyStatus_PROXY_STATUS_TUNNEL_NOT_CREATED if connected { status = proto.ProxyStatus_PROXY_STATUS_ACTIVE } _, err := s.mgmtClient.SendStatusUpdate(ctx, &proto.SendStatusUpdateRequest{ - ReverseProxyId: reverseProxyID, + ServiceId: serviceID, AccountId: accountID, Status: status, CertificateIssued: false, @@ -122,9 +122,9 @@ func (s *Server) NotifyStatus(ctx context.Context, accountID, reverseProxyID, do } // NotifyCertificateIssued sends a notification to management that a certificate was issued -func (s *Server) NotifyCertificateIssued(ctx context.Context, accountID, reverseProxyID, domain string) error { +func (s *Server) NotifyCertificateIssued(ctx context.Context, accountID, serviceID, domain string) error { _, err := s.mgmtClient.SendStatusUpdate(ctx, &proto.SendStatusUpdateRequest{ - ReverseProxyId: reverseProxyID, + ServiceId: serviceID, AccountId: accountID, Status: proto.ProxyStatus_PROXY_STATUS_ACTIVE, CertificateIssued: true, @@ -523,14 +523,14 @@ func (s *Server) handleMappingStream(ctx context.Context, mappingClient proto.Pr func (s *Server) addMapping(ctx context.Context, mapping *proto.ProxyMapping) error { d := domain.Domain(mapping.GetDomain()) accountID := types.AccountID(mapping.GetAccountId()) - reverseProxyID := mapping.GetId() + serviceID := mapping.GetId() authToken := mapping.GetAuthToken() - if err := s.netbird.AddPeer(ctx, accountID, d, authToken, reverseProxyID); err != nil { + if err := s.netbird.AddPeer(ctx, accountID, d, authToken, serviceID); err != nil { return fmt.Errorf("create peer for domain %q: %w", d, err) } if s.acme != nil { - s.acme.AddDomain(d, string(accountID), reverseProxyID) + s.acme.AddDomain(d, string(accountID), serviceID) } // Pass the mapping through to the update function to avoid duplicating the diff --git a/shared/management/http/api/openapi.yml b/shared/management/http/api/openapi.yml index 978e7e084..aa51e72b2 100644 --- a/shared/management/http/api/openapi.yml +++ b/shared/management/http/api/openapi.yml @@ -36,8 +36,8 @@ tags: x-cloud-only: true - name: Identity Providers description: Interact with and view information about identity providers. - - name: Reverse Proxy - description: Interact with and view information about reverse proxies. + - name: Services + description: Interact with and view information about reverse proxy services. - name: Instance description: Instance setup and status endpoints for initial configuration. - name: Jobs @@ -2711,9 +2711,9 @@ components: type: string description: "Unique identifier for the access log entry" example: "ch8i4ug6lnn4g9hqv7m0" - proxy_id: + service_id: type: string - description: "ID of the reverse proxy that handled the request" + description: "ID of the service that handled the request" example: "ch8i4ug6lnn4g9hqv7m0" timestamp: type: string @@ -2766,7 +2766,7 @@ components: example: "San Francisco" required: - id - - proxy_id + - service_id - timestamp - method - host @@ -2868,30 +2868,30 @@ components: - issuer - client_id - client_secret - ReverseProxy: + Service: type: object properties: id: type: string - description: Reverse proxy ID + description: Service ID name: type: string - description: Reverse proxy name + description: Service name domain: type: string - description: Domain for the reverse proxy + description: Domain for the service proxy_cluster: type: string - description: The proxy cluster handling this reverse proxy (derived from domain) + description: The proxy cluster handling this service (derived from domain) example: "eu.proxy.netbird.io" targets: type: array items: - $ref: '#/components/schemas/ReverseProxyTarget' - description: List of target backends for this reverse proxy + $ref: '#/components/schemas/ServiceTarget' + description: List of target backends for this service enabled: type: boolean - description: Whether the reverse proxy is enabled + description: Whether the service is enabled pass_host_header: type: boolean description: When true, the original client Host header is passed through to the backend instead of being rewritten to the backend's address @@ -2899,9 +2899,9 @@ components: type: boolean description: When true, Location headers in backend responses are rewritten to replace the backend address with the public-facing domain auth: - $ref: '#/components/schemas/ReverseProxyAuthConfig' + $ref: '#/components/schemas/ServiceAuthConfig' meta: - $ref: '#/components/schemas/ReverseProxyMeta' + $ref: '#/components/schemas/ServiceMeta' required: - id - name @@ -2910,13 +2910,13 @@ components: - enabled - auth - meta - ReverseProxyMeta: + ServiceMeta: type: object properties: created_at: type: string format: date-time - description: Timestamp when the reverse proxy was created + description: Timestamp when the service was created example: "2024-02-03T10:30:00Z" certificate_issued_at: type: string @@ -2932,28 +2932,28 @@ components: - certificate_pending - certificate_failed - error - description: Current status of the reverse proxy + description: Current status of the service example: "active" required: - created_at - status - ReverseProxyRequest: + ServiceRequest: type: object properties: name: type: string - description: Reverse proxy name + description: Service name domain: type: string - description: Domain for the reverse proxy + description: Domain for the service targets: type: array items: - $ref: '#/components/schemas/ReverseProxyTarget' - description: List of target backends for this reverse proxy + $ref: '#/components/schemas/ServiceTarget' + description: List of target backends for this service enabled: type: boolean - description: Whether the reverse proxy is enabled + description: Whether the service is enabled default: true pass_host_header: type: boolean @@ -2962,14 +2962,14 @@ components: type: boolean description: When true, Location headers in backend responses are rewritten to replace the backend address with the public-facing domain auth: - $ref: '#/components/schemas/ReverseProxyAuthConfig' + $ref: '#/components/schemas/ServiceAuthConfig' required: - name - domain - targets - auth - enabled - ReverseProxyTarget: + ServiceTarget: type: object properties: target_id: @@ -3001,7 +3001,7 @@ components: - protocol - port - enabled - ReverseProxyAuthConfig: + ServiceAuthConfig: type: object properties: password_auth: @@ -6803,23 +6803,23 @@ paths: "$ref": "#/components/responses/forbidden" '500': "$ref": "#/components/responses/internal_error" - /api/reverse-proxies: + /api/reverse-proxies/services: get: - summary: List all Reverse Proxies - description: Returns a list of all reverse proxies - tags: [ Reverse Proxy ] + summary: List all Services + description: Returns a list of all reverse proxy services + tags: [ Services ] security: - BearerAuth: [ ] - TokenAuth: [ ] responses: '200': - description: A JSON Array of reverse proxies + description: A JSON Array of services content: application/json: schema: type: array items: - $ref: '#/components/schemas/ReverseProxy' + $ref: '#/components/schemas/Service' '401': "$ref": "#/components/responses/requires_authentication" '403': @@ -6827,25 +6827,25 @@ paths: '500': "$ref": "#/components/responses/internal_error" post: - summary: Create a Reverse Proxy - description: Creates a new reverse proxy - tags: [ Reverse Proxy ] + summary: Create a Service + description: Creates a new reverse proxy service + tags: [ Services ] security: - BearerAuth: [ ] - TokenAuth: [ ] requestBody: - description: New reverse proxy request + description: New service request content: application/json: schema: - $ref: '#/components/schemas/ReverseProxyRequest' + $ref: '#/components/schemas/ServiceRequest' responses: '200': - description: Reverse proxy created + description: Service created content: application/json: schema: - $ref: '#/components/schemas/ReverseProxy' + $ref: '#/components/schemas/Service' '400': "$ref": "#/components/responses/bad_request" '401': @@ -6858,7 +6858,7 @@ paths: get: summary: List available proxy clusters description: Returns a list of available proxy clusters with their connection status - tags: [ Reverse Proxy ] + tags: [ Services ] security: - BearerAuth: [ ] - TokenAuth: [ ] @@ -6877,28 +6877,28 @@ paths: "$ref": "#/components/responses/forbidden" '500': "$ref": "#/components/responses/internal_error" - /api/reverse-proxies/{proxyId}: + /api/reverse-proxies/services/{serviceId}: get: - summary: Retrieve a Reverse Proxy - description: Get information about a specific reverse proxy - tags: [ Reverse Proxy ] + summary: Retrieve a Service + description: Get information about a specific reverse proxy service + tags: [ Services ] security: - BearerAuth: [ ] - TokenAuth: [ ] parameters: - in: path - name: proxyId + name: serviceId required: true schema: type: string - description: The unique identifier of a reverse proxy + description: The unique identifier of a service responses: '200': - description: A reverse proxy object + description: A service object content: application/json: schema: - $ref: '#/components/schemas/ReverseProxy' + $ref: '#/components/schemas/Service' '400': "$ref": "#/components/responses/bad_request" '401': @@ -6910,32 +6910,32 @@ paths: '500': "$ref": "#/components/responses/internal_error" put: - summary: Update a Reverse Proxy - description: Update an existing reverse proxy - tags: [ Reverse Proxy ] + summary: Update a Service + description: Update an existing service + tags: [ Services ] security: - BearerAuth: [ ] - TokenAuth: [ ] parameters: - in: path - name: proxyId + name: serviceId required: true schema: type: string - description: The unique identifier of a reverse proxy + description: The unique identifier of a service requestBody: - description: Reverse proxy update request + description: Service update request content: application/json: schema: - $ref: '#/components/schemas/ReverseProxyRequest' + $ref: '#/components/schemas/ServiceRequest' responses: '200': - description: Reverse proxy updated + description: Service updated content: application/json: schema: - $ref: '#/components/schemas/ReverseProxy' + $ref: '#/components/schemas/Service' '400': "$ref": "#/components/responses/bad_request" '401': @@ -6947,22 +6947,22 @@ paths: '500': "$ref": "#/components/responses/internal_error" delete: - summary: Delete a Reverse Proxy - description: Delete an existing reverse proxy - tags: [ Reverse Proxy ] + summary: Delete a Service + description: Delete an existing service + tags: [ Services ] security: - BearerAuth: [ ] - TokenAuth: [ ] parameters: - in: path - name: proxyId + name: serviceId required: true schema: type: string - description: The unique identifier of a reverse proxy + description: The unique identifier of a service responses: '200': - description: Reverse proxy deleted + description: Service deleted '400': "$ref": "#/components/responses/bad_request" '401': @@ -6975,9 +6975,9 @@ paths: "$ref": "#/components/responses/internal_error" /api/reverse-proxies/domains: get: - summary: Retrieve Reverse Proxy Domains - description: Get information about domains that can be used for Reverse Proxy endpoints. - tags: [ Reverse Proxy ] + summary: Retrieve Service Domains + description: Get information about domains that can be used for service endpoints. + tags: [ Services ] security: - BearerAuth: [ ] - TokenAuth: [ ] @@ -7002,8 +7002,8 @@ paths: "$ref": "#/components/responses/internal_error" post: summary: Create a Custom domain - description: Create a new Custom domain for use with Reverse Proxy endpoints, this will trigger an initial validation check - tags: [ Reverse Proxy ] + description: Create a new Custom domain for use with service endpoints, this will trigger an initial validation check + tags: [ Services ] security: - BearerAuth: [ ] - TokenAuth: [ ] @@ -7015,11 +7015,11 @@ paths: $ref: '#/components/schemas/ReverseProxyDomainRequest' responses: '200': - description: Reverse proxy created + description: Service created content: application/json: schema: - $ref: '#/components/schemas/ReverseProxy' + $ref: '#/components/schemas/Service' '400': "$ref": "#/components/responses/bad_request" '401': @@ -7030,11 +7030,11 @@ paths: "$ref": "#/components/responses/not_found" '500': "$ref": "#/components/responses/internal_error" - /api/reverse-proxies/domains/{domainId}: + /api/services/domains/{domainId}: delete: summary: Delete a Custom domain - description: Delete an existing reverse proxy custom domain - tags: [ Reverse Proxy ] + description: Delete an existing service custom domain + tags: [ Services ] security: - BearerAuth: [ ] - TokenAuth: [ ] @@ -7047,7 +7047,7 @@ paths: description: The custom domain ID responses: '204': - description: Reverse proxy custom domain deleted + description: Service custom domain deleted '400': "$ref": "#/components/responses/bad_request" '401': @@ -7058,11 +7058,11 @@ paths: "$ref": "#/components/responses/not_found" '500': "$ref": "#/components/responses/internal_error" - /api/reverse-proxies/domains/{domainId}/validate: + /api/services/domains/{domainId}/validate: get: summary: Validate a custom domain description: Trigger domain ownership validation for a custom domain - tags: [ Reverse Proxy ] + tags: [ Services ] security: - BearerAuth: [ ] - TokenAuth: [ ] diff --git a/shared/management/http/api/types.gen.go b/shared/management/http/api/types.gen.go index df59b129a..a9fd67a53 100644 --- a/shared/management/http/api/types.gen.go +++ b/shared/management/http/api/types.gen.go @@ -275,26 +275,26 @@ const ( ReverseProxyDomainTypeFree ReverseProxyDomainType = "free" ) -// Defines values for ReverseProxyMetaStatus. +// Defines values for ServiceMetaStatus. const ( - ReverseProxyMetaStatusActive ReverseProxyMetaStatus = "active" - ReverseProxyMetaStatusCertificateFailed ReverseProxyMetaStatus = "certificate_failed" - ReverseProxyMetaStatusCertificatePending ReverseProxyMetaStatus = "certificate_pending" - ReverseProxyMetaStatusError ReverseProxyMetaStatus = "error" - ReverseProxyMetaStatusPending ReverseProxyMetaStatus = "pending" - ReverseProxyMetaStatusTunnelNotCreated ReverseProxyMetaStatus = "tunnel_not_created" + ServiceMetaStatusActive ServiceMetaStatus = "active" + ServiceMetaStatusCertificateFailed ServiceMetaStatus = "certificate_failed" + ServiceMetaStatusCertificatePending ServiceMetaStatus = "certificate_pending" + ServiceMetaStatusError ServiceMetaStatus = "error" + ServiceMetaStatusPending ServiceMetaStatus = "pending" + ServiceMetaStatusTunnelNotCreated ServiceMetaStatus = "tunnel_not_created" ) -// Defines values for ReverseProxyTargetProtocol. +// Defines values for ServiceTargetProtocol. const ( - ReverseProxyTargetProtocolHttp ReverseProxyTargetProtocol = "http" - ReverseProxyTargetProtocolHttps ReverseProxyTargetProtocol = "https" + ServiceTargetProtocolHttp ServiceTargetProtocol = "http" + ServiceTargetProtocolHttps ServiceTargetProtocol = "https" ) -// Defines values for ReverseProxyTargetTargetType. +// Defines values for ServiceTargetTargetType. const ( - ReverseProxyTargetTargetTypePeer ReverseProxyTargetTargetType = "peer" - ReverseProxyTargetTargetTypeResource ReverseProxyTargetTargetType = "resource" + ServiceTargetTargetTypePeer ServiceTargetTargetType = "peer" + ServiceTargetTargetTypeResource ServiceTargetTargetType = "resource" ) // Defines values for UserStatus. @@ -330,6 +330,23 @@ const ( GetApiEventsNetworkTrafficParamsDirectionINGRESS GetApiEventsNetworkTrafficParamsDirection = "INGRESS" ) +// Defines values for GetApiEventsProxyParamsMethod. +const ( + GetApiEventsProxyParamsMethodDELETE GetApiEventsProxyParamsMethod = "DELETE" + GetApiEventsProxyParamsMethodGET GetApiEventsProxyParamsMethod = "GET" + GetApiEventsProxyParamsMethodHEAD GetApiEventsProxyParamsMethod = "HEAD" + GetApiEventsProxyParamsMethodOPTIONS GetApiEventsProxyParamsMethod = "OPTIONS" + GetApiEventsProxyParamsMethodPATCH GetApiEventsProxyParamsMethod = "PATCH" + GetApiEventsProxyParamsMethodPOST GetApiEventsProxyParamsMethod = "POST" + GetApiEventsProxyParamsMethodPUT GetApiEventsProxyParamsMethod = "PUT" +) + +// Defines values for GetApiEventsProxyParamsStatus. +const ( + GetApiEventsProxyParamsStatusFailed GetApiEventsProxyParamsStatus = "failed" + GetApiEventsProxyParamsStatusSuccess GetApiEventsProxyParamsStatus = "success" +) + // AccessiblePeer defines model for AccessiblePeer. type AccessiblePeer struct { // CityName Commonly used English name of the city @@ -1931,12 +1948,12 @@ type ProxyAccessLog struct { // Path Path of the request Path string `json:"path"` - // ProxyId ID of the reverse proxy that handled the request - ProxyId string `json:"proxy_id"` - // Reason Reason for the request result (e.g., authentication failure) Reason *string `json:"reason,omitempty"` + // ServiceId ID of the service that handled the request + ServiceId string `json:"service_id"` + // SourceIp Source IP address of the request SourceIp *string `json:"source_ip,omitempty"` @@ -1987,44 +2004,6 @@ type Resource struct { // ResourceType defines model for ResourceType. type ResourceType string -// ReverseProxy defines model for ReverseProxy. -type ReverseProxy struct { - Auth ReverseProxyAuthConfig `json:"auth"` - - // Domain Domain for the reverse proxy - Domain string `json:"domain"` - - // Enabled Whether the reverse proxy is enabled - Enabled bool `json:"enabled"` - - // Id Reverse proxy ID - Id string `json:"id"` - Meta ReverseProxyMeta `json:"meta"` - - // Name Reverse proxy name - Name string `json:"name"` - - // PassHostHeader When true, the original client Host header is passed through to the backend instead of being rewritten to the backend's address - PassHostHeader *bool `json:"pass_host_header,omitempty"` - - // ProxyCluster The proxy cluster handling this reverse proxy (derived from domain) - ProxyCluster *string `json:"proxy_cluster,omitempty"` - - // RewriteRedirects When true, Location headers in backend responses are rewritten to replace the backend address with the public-facing domain - RewriteRedirects *bool `json:"rewrite_redirects,omitempty"` - - // Targets List of target backends for this reverse proxy - Targets []ReverseProxyTarget `json:"targets"` -} - -// ReverseProxyAuthConfig defines model for ReverseProxyAuthConfig. -type ReverseProxyAuthConfig struct { - BearerAuth *BearerAuthConfig `json:"bearer_auth,omitempty"` - LinkAuth *LinkAuthConfig `json:"link_auth,omitempty"` - PasswordAuth *PasswordAuthConfig `json:"password_auth,omitempty"` - PinAuth *PINAuthConfig `json:"pin_auth,omitempty"` -} - // ReverseProxyDomain defines model for ReverseProxyDomain. type ReverseProxyDomain struct { // Domain Domain name @@ -2055,74 +2034,6 @@ type ReverseProxyDomainRequest struct { // ReverseProxyDomainType Type of Reverse Proxy Domain type ReverseProxyDomainType string -// ReverseProxyMeta defines model for ReverseProxyMeta. -type ReverseProxyMeta struct { - // CertificateIssuedAt Timestamp when the certificate was issued (empty if not yet issued) - CertificateIssuedAt *time.Time `json:"certificate_issued_at,omitempty"` - - // CreatedAt Timestamp when the reverse proxy was created - CreatedAt time.Time `json:"created_at"` - - // Status Current status of the reverse proxy - Status ReverseProxyMetaStatus `json:"status"` -} - -// ReverseProxyMetaStatus Current status of the reverse proxy -type ReverseProxyMetaStatus string - -// ReverseProxyRequest defines model for ReverseProxyRequest. -type ReverseProxyRequest struct { - Auth ReverseProxyAuthConfig `json:"auth"` - - // Domain Domain for the reverse proxy - Domain string `json:"domain"` - - // Enabled Whether the reverse proxy is enabled - Enabled bool `json:"enabled"` - - // Name Reverse proxy name - Name string `json:"name"` - - // PassHostHeader When true, the original client Host header is passed through to the backend instead of being rewritten to the backend's address - PassHostHeader *bool `json:"pass_host_header,omitempty"` - - // RewriteRedirects When true, Location headers in backend responses are rewritten to replace the backend address with the public-facing domain - RewriteRedirects *bool `json:"rewrite_redirects,omitempty"` - - // Targets List of target backends for this reverse proxy - Targets []ReverseProxyTarget `json:"targets"` -} - -// ReverseProxyTarget defines model for ReverseProxyTarget. -type ReverseProxyTarget struct { - // Enabled Whether this target is enabled - Enabled bool `json:"enabled"` - - // Host Backend ip or domain for this target - Host *string `json:"host,omitempty"` - - // Path URL path prefix for this target - Path *string `json:"path,omitempty"` - - // Port Backend port for this target. Use 0 or omit to use the scheme default (80 for http, 443 for https). - Port int `json:"port"` - - // Protocol Protocol to use when connecting to the backend - Protocol ReverseProxyTargetProtocol `json:"protocol"` - - // TargetId Target ID - TargetId string `json:"target_id"` - - // TargetType Target type (e.g., "peer", "resource") - TargetType ReverseProxyTargetTargetType `json:"target_type"` -} - -// ReverseProxyTargetProtocol Protocol to use when connecting to the backend -type ReverseProxyTargetProtocol string - -// ReverseProxyTargetTargetType Target type (e.g., "peer", "resource") -type ReverseProxyTargetTargetType string - // Route defines model for Route. type Route struct { // AccessControlGroups Access control group identifier associated with route. @@ -2222,6 +2133,112 @@ type RulePortRange struct { Start int `json:"start"` } +// Service defines model for Service. +type Service struct { + Auth ServiceAuthConfig `json:"auth"` + + // Domain Domain for the service + Domain string `json:"domain"` + + // Enabled Whether the service is enabled + Enabled bool `json:"enabled"` + + // Id Service ID + Id string `json:"id"` + Meta ServiceMeta `json:"meta"` + + // Name Service name + Name string `json:"name"` + + // PassHostHeader When true, the original client Host header is passed through to the backend instead of being rewritten to the backend's address + PassHostHeader *bool `json:"pass_host_header,omitempty"` + + // ProxyCluster The proxy cluster handling this service (derived from domain) + ProxyCluster *string `json:"proxy_cluster,omitempty"` + + // RewriteRedirects When true, Location headers in backend responses are rewritten to replace the backend address with the public-facing domain + RewriteRedirects *bool `json:"rewrite_redirects,omitempty"` + + // Targets List of target backends for this service + Targets []ServiceTarget `json:"targets"` +} + +// ServiceAuthConfig defines model for ServiceAuthConfig. +type ServiceAuthConfig struct { + BearerAuth *BearerAuthConfig `json:"bearer_auth,omitempty"` + LinkAuth *LinkAuthConfig `json:"link_auth,omitempty"` + PasswordAuth *PasswordAuthConfig `json:"password_auth,omitempty"` + PinAuth *PINAuthConfig `json:"pin_auth,omitempty"` +} + +// ServiceMeta defines model for ServiceMeta. +type ServiceMeta struct { + // CertificateIssuedAt Timestamp when the certificate was issued (empty if not yet issued) + CertificateIssuedAt *time.Time `json:"certificate_issued_at,omitempty"` + + // CreatedAt Timestamp when the service was created + CreatedAt time.Time `json:"created_at"` + + // Status Current status of the service + Status ServiceMetaStatus `json:"status"` +} + +// ServiceMetaStatus Current status of the service +type ServiceMetaStatus string + +// ServiceRequest defines model for ServiceRequest. +type ServiceRequest struct { + Auth ServiceAuthConfig `json:"auth"` + + // Domain Domain for the service + Domain string `json:"domain"` + + // Enabled Whether the service is enabled + Enabled bool `json:"enabled"` + + // Name Service name + Name string `json:"name"` + + // PassHostHeader When true, the original client Host header is passed through to the backend instead of being rewritten to the backend's address + PassHostHeader *bool `json:"pass_host_header,omitempty"` + + // RewriteRedirects When true, Location headers in backend responses are rewritten to replace the backend address with the public-facing domain + RewriteRedirects *bool `json:"rewrite_redirects,omitempty"` + + // Targets List of target backends for this service + Targets []ServiceTarget `json:"targets"` +} + +// ServiceTarget defines model for ServiceTarget. +type ServiceTarget struct { + // Enabled Whether this target is enabled + Enabled bool `json:"enabled"` + + // Host Backend ip or domain for this target + Host *string `json:"host,omitempty"` + + // Path URL path prefix for this target + Path *string `json:"path,omitempty"` + + // Port Backend port for this target. Use 0 or omit to use the scheme default (80 for http, 443 for https). + Port int `json:"port"` + + // Protocol Protocol to use when connecting to the backend + Protocol ServiceTargetProtocol `json:"protocol"` + + // TargetId Target ID + TargetId string `json:"target_id"` + + // TargetType Target type (e.g., "peer", "resource") + TargetType ServiceTargetTargetType `json:"target_type"` +} + +// ServiceTargetProtocol Protocol to use when connecting to the backend +type ServiceTargetProtocol string + +// ServiceTargetTargetType Target type (e.g., "peer", "resource") +type ServiceTargetTargetType string + // SetupKey defines model for SetupKey. type SetupKey struct { // AllowExtraDnsLabels Allow extra DNS labels to be added to the peer @@ -2680,8 +2697,50 @@ type GetApiEventsProxyParams struct { // PageSize Number of items per page (max 100) PageSize *int `form:"page_size,omitempty" json:"page_size,omitempty"` + + // Search General search across request ID, host, path, source IP, user email, and user name + Search *string `form:"search,omitempty" json:"search,omitempty"` + + // SourceIp Filter by source IP address + SourceIp *string `form:"source_ip,omitempty" json:"source_ip,omitempty"` + + // Host Filter by host header + Host *string `form:"host,omitempty" json:"host,omitempty"` + + // Path Filter by request path (supports partial matching) + Path *string `form:"path,omitempty" json:"path,omitempty"` + + // UserId Filter by authenticated user ID + UserId *string `form:"user_id,omitempty" json:"user_id,omitempty"` + + // UserEmail Filter by user email (partial matching) + UserEmail *string `form:"user_email,omitempty" json:"user_email,omitempty"` + + // UserName Filter by user name (partial matching) + UserName *string `form:"user_name,omitempty" json:"user_name,omitempty"` + + // Method Filter by HTTP method + Method *GetApiEventsProxyParamsMethod `form:"method,omitempty" json:"method,omitempty"` + + // Status Filter by status (success = 2xx/3xx, failed = 1xx/4xx/5xx) + Status *GetApiEventsProxyParamsStatus `form:"status,omitempty" json:"status,omitempty"` + + // StatusCode Filter by HTTP status code + StatusCode *int `form:"status_code,omitempty" json:"status_code,omitempty"` + + // StartDate Filter by timestamp >= start_date (RFC3339 format) + StartDate *time.Time `form:"start_date,omitempty" json:"start_date,omitempty"` + + // EndDate Filter by timestamp <= end_date (RFC3339 format) + EndDate *time.Time `form:"end_date,omitempty" json:"end_date,omitempty"` } +// GetApiEventsProxyParamsMethod defines parameters for GetApiEventsProxy. +type GetApiEventsProxyParamsMethod string + +// GetApiEventsProxyParamsStatus defines parameters for GetApiEventsProxy. +type GetApiEventsProxyParamsStatus string + // GetApiGroupsParams defines parameters for GetApiGroups. type GetApiGroupsParams struct { // Name Filter groups by name (exact match) @@ -2796,14 +2855,14 @@ type PostApiPostureChecksJSONRequestBody = PostureCheckUpdate // PutApiPostureChecksPostureCheckIdJSONRequestBody defines body for PutApiPostureChecksPostureCheckId for application/json ContentType. type PutApiPostureChecksPostureCheckIdJSONRequestBody = PostureCheckUpdate -// PostApiReverseProxiesJSONRequestBody defines body for PostApiReverseProxies for application/json ContentType. -type PostApiReverseProxiesJSONRequestBody = ReverseProxyRequest - // PostApiReverseProxiesDomainsJSONRequestBody defines body for PostApiReverseProxiesDomains for application/json ContentType. type PostApiReverseProxiesDomainsJSONRequestBody = ReverseProxyDomainRequest -// PutApiReverseProxiesProxyIdJSONRequestBody defines body for PutApiReverseProxiesProxyId for application/json ContentType. -type PutApiReverseProxiesProxyIdJSONRequestBody = ReverseProxyRequest +// PostApiReverseProxiesServicesJSONRequestBody defines body for PostApiReverseProxiesServices for application/json ContentType. +type PostApiReverseProxiesServicesJSONRequestBody = ServiceRequest + +// PutApiReverseProxiesServicesServiceIdJSONRequestBody defines body for PutApiReverseProxiesServicesServiceId for application/json ContentType. +type PutApiReverseProxiesServicesServiceIdJSONRequestBody = ServiceRequest // PostApiRoutesJSONRequestBody defines body for PostApiRoutes for application/json ContentType. type PostApiRoutesJSONRequestBody = RouteRequest diff --git a/shared/management/proto/management.pb.go b/shared/management/proto/management.pb.go index 5f45d3fdd..44838fc16 100644 --- a/shared/management/proto/management.pb.go +++ b/shared/management/proto/management.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.26.0 -// protoc v6.33.3 +// protoc v6.33.0 // source: management.proto package proto diff --git a/shared/management/proto/proxy_service.pb.go b/shared/management/proto/proxy_service.pb.go index 95de71d1a..f4c0917dc 100644 --- a/shared/management/proto/proxy_service.pb.go +++ b/shared/management/proto/proxy_service.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.26.0 -// protoc v6.33.3 +// protoc v6.33.0 // source: proxy_service.proto package proto @@ -981,7 +981,7 @@ type SendStatusUpdateRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - ReverseProxyId string `protobuf:"bytes,1,opt,name=reverse_proxy_id,json=reverseProxyId,proto3" json:"reverse_proxy_id,omitempty"` + ServiceId string `protobuf:"bytes,1,opt,name=service_id,json=serviceId,proto3" json:"service_id,omitempty"` AccountId string `protobuf:"bytes,2,opt,name=account_id,json=accountId,proto3" json:"account_id,omitempty"` Status ProxyStatus `protobuf:"varint,3,opt,name=status,proto3,enum=management.ProxyStatus" json:"status,omitempty"` CertificateIssued bool `protobuf:"varint,4,opt,name=certificate_issued,json=certificateIssued,proto3" json:"certificate_issued,omitempty"` @@ -1020,9 +1020,9 @@ func (*SendStatusUpdateRequest) Descriptor() ([]byte, []int) { return file_proxy_service_proto_rawDescGZIP(), []int{12} } -func (x *SendStatusUpdateRequest) GetReverseProxyId() string { +func (x *SendStatusUpdateRequest) GetServiceId() string { if x != nil { - return x.ReverseProxyId + return x.ServiceId } return "" } @@ -1101,7 +1101,7 @@ type CreateProxyPeerRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - ReverseProxyId string `protobuf:"bytes,1,opt,name=reverse_proxy_id,json=reverseProxyId,proto3" json:"reverse_proxy_id,omitempty"` + ServiceId string `protobuf:"bytes,1,opt,name=service_id,json=serviceId,proto3" json:"service_id,omitempty"` AccountId string `protobuf:"bytes,2,opt,name=account_id,json=accountId,proto3" json:"account_id,omitempty"` Token string `protobuf:"bytes,3,opt,name=token,proto3" json:"token,omitempty"` WireguardPublicKey string `protobuf:"bytes,4,opt,name=wireguard_public_key,json=wireguardPublicKey,proto3" json:"wireguard_public_key,omitempty"` @@ -1140,9 +1140,9 @@ func (*CreateProxyPeerRequest) Descriptor() ([]byte, []int) { return file_proxy_service_proto_rawDescGZIP(), []int{14} } -func (x *CreateProxyPeerRequest) GetReverseProxyId() string { +func (x *CreateProxyPeerRequest) GetServiceId() string { if x != nil { - return x.ReverseProxyId + return x.ServiceId } return "" } @@ -1580,127 +1580,126 @@ var file_proxy_service_proto_rawDesc = []byte{ 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, - 0xfe, 0x01, 0x0a, 0x17, 0x53, 0x65, 0x6e, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x72, - 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x5f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x50, 0x72, - 0x6f, 0x78, 0x79, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x63, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x49, 0x64, 0x12, 0x2f, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, - 0x74, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2d, 0x0a, 0x12, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, - 0x63, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x73, 0x73, 0x75, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x11, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x49, 0x73, - 0x73, 0x75, 0x65, 0x64, 0x12, 0x28, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0c, 0x65, - 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x88, 0x01, 0x01, 0x42, 0x10, - 0x0a, 0x0e, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x22, 0x1a, 0x0a, 0x18, 0x53, 0x65, 0x6e, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xc3, 0x01, 0x0a, - 0x16, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x50, 0x65, 0x65, 0x72, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x72, 0x65, 0x76, 0x65, 0x72, - 0x73, 0x65, 0x5f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0e, 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x49, - 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x64, - 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x30, 0x0a, 0x14, 0x77, 0x69, 0x72, 0x65, 0x67, 0x75, - 0x61, 0x72, 0x64, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x77, 0x69, 0x72, 0x65, 0x67, 0x75, 0x61, 0x72, 0x64, 0x50, - 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6c, 0x75, 0x73, - 0x74, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6c, 0x75, 0x73, 0x74, - 0x65, 0x72, 0x22, 0x6f, 0x0a, 0x17, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x78, - 0x79, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, - 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, - 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x28, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, - 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, - 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x88, 0x01, - 0x01, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x22, 0x65, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x4f, 0x49, 0x44, 0x43, 0x55, 0x52, - 0x4c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x63, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x63, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x64, 0x69, 0x72, - 0x65, 0x63, 0x74, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, - 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x55, 0x72, 0x6c, 0x22, 0x26, 0x0a, 0x12, 0x47, 0x65, - 0x74, 0x4f, 0x49, 0x44, 0x43, 0x55, 0x52, 0x4c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, - 0x72, 0x6c, 0x22, 0x55, 0x0a, 0x16, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x65, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, - 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x6f, - 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, - 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x73, 0x65, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x8c, 0x01, 0x0a, 0x17, 0x56, 0x61, - 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x75, - 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, - 0x65, 0x72, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x65, 0x6d, 0x61, - 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x75, 0x73, 0x65, 0x72, 0x45, 0x6d, - 0x61, 0x69, 0x6c, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x65, 0x6e, 0x69, 0x65, 0x64, 0x5f, 0x72, 0x65, - 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x64, 0x65, 0x6e, 0x69, - 0x65, 0x64, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x2a, 0x64, 0x0a, 0x16, 0x50, 0x72, 0x6f, 0x78, - 0x79, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x79, - 0x70, 0x65, 0x12, 0x17, 0x0a, 0x13, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x54, 0x59, 0x50, - 0x45, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x44, 0x10, 0x00, 0x12, 0x18, 0x0a, 0x14, 0x55, - 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x4f, 0x44, 0x49, 0x46, - 0x49, 0x45, 0x44, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, - 0x54, 0x59, 0x50, 0x45, 0x5f, 0x52, 0x45, 0x4d, 0x4f, 0x56, 0x45, 0x44, 0x10, 0x02, 0x2a, 0xc8, - 0x01, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, - 0x0a, 0x14, 0x50, 0x52, 0x4f, 0x58, 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x50, - 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x50, 0x52, 0x4f, 0x58, - 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x10, - 0x01, 0x12, 0x23, 0x0a, 0x1f, 0x50, 0x52, 0x4f, 0x58, 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, - 0x53, 0x5f, 0x54, 0x55, 0x4e, 0x4e, 0x45, 0x4c, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x43, 0x52, 0x45, - 0x41, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x24, 0x0a, 0x20, 0x50, 0x52, 0x4f, 0x58, 0x59, 0x5f, + 0xf3, 0x01, 0x0a, 0x17, 0x53, 0x65, 0x6e, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x63, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x2f, 0x0a, 0x06, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x6d, 0x61, 0x6e, 0x61, + 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2d, 0x0a, 0x12, 0x63, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x73, 0x73, 0x75, 0x65, 0x64, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x65, 0x49, 0x73, 0x73, 0x75, 0x65, 0x64, 0x12, 0x28, 0x0a, 0x0d, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, + 0x48, 0x00, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x88, 0x01, 0x01, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x1a, 0x0a, 0x18, 0x53, 0x65, 0x6e, 0x64, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0xb8, 0x01, 0x0a, 0x16, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x78, + 0x79, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x61, + 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, + 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x12, 0x30, 0x0a, 0x14, 0x77, 0x69, 0x72, 0x65, 0x67, 0x75, 0x61, 0x72, 0x64, 0x5f, 0x70, 0x75, + 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, + 0x77, 0x69, 0x72, 0x65, 0x67, 0x75, 0x61, 0x72, 0x64, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, + 0x65, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x22, 0x6f, 0x0a, 0x17, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x50, 0x65, 0x65, 0x72, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x12, 0x28, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x88, 0x01, 0x01, 0x42, 0x10, 0x0a, 0x0e, 0x5f, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x65, 0x0a, + 0x11, 0x47, 0x65, 0x74, 0x4f, 0x49, 0x44, 0x43, 0x55, 0x52, 0x4c, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, + 0x69, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, + 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x5f, 0x75, 0x72, + 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, + 0x74, 0x55, 0x72, 0x6c, 0x22, 0x26, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x4f, 0x49, 0x44, 0x43, 0x55, + 0x52, 0x4c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, + 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x22, 0x55, 0x0a, 0x16, + 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x23, + 0x0a, 0x0d, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x6f, + 0x6b, 0x65, 0x6e, 0x22, 0x8c, 0x01, 0x0a, 0x17, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, + 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x69, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1d, + 0x0a, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x75, 0x73, 0x65, 0x72, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x23, 0x0a, + 0x0d, 0x64, 0x65, 0x6e, 0x69, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x64, 0x65, 0x6e, 0x69, 0x65, 0x64, 0x52, 0x65, 0x61, 0x73, + 0x6f, 0x6e, 0x2a, 0x64, 0x0a, 0x16, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x4d, 0x61, 0x70, 0x70, 0x69, + 0x6e, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x17, 0x0a, 0x13, + 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x43, 0x52, 0x45, 0x41, + 0x54, 0x45, 0x44, 0x10, 0x00, 0x12, 0x18, 0x0a, 0x14, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x4f, 0x44, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x01, 0x12, + 0x17, 0x0a, 0x13, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x52, + 0x45, 0x4d, 0x4f, 0x56, 0x45, 0x44, 0x10, 0x02, 0x2a, 0xc8, 0x01, 0x0a, 0x0b, 0x50, 0x72, 0x6f, + 0x78, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, 0x0a, 0x14, 0x50, 0x52, 0x4f, 0x58, + 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, + 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x50, 0x52, 0x4f, 0x58, 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, + 0x55, 0x53, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x10, 0x01, 0x12, 0x23, 0x0a, 0x1f, 0x50, + 0x52, 0x4f, 0x58, 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x54, 0x55, 0x4e, 0x4e, + 0x45, 0x4c, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x44, 0x10, 0x02, + 0x12, 0x24, 0x0a, 0x20, 0x50, 0x52, 0x4f, 0x58, 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, + 0x5f, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x5f, 0x50, 0x45, 0x4e, + 0x44, 0x49, 0x4e, 0x47, 0x10, 0x03, 0x12, 0x23, 0x0a, 0x1f, 0x50, 0x52, 0x4f, 0x58, 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, - 0x54, 0x45, 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x03, 0x12, 0x23, 0x0a, 0x1f, - 0x50, 0x52, 0x4f, 0x58, 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x45, 0x52, - 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, - 0x04, 0x12, 0x16, 0x0a, 0x12, 0x50, 0x52, 0x4f, 0x58, 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, - 0x53, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x05, 0x32, 0xfc, 0x04, 0x0a, 0x0c, 0x50, 0x72, - 0x6f, 0x78, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5f, 0x0a, 0x10, 0x47, 0x65, - 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x23, - 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x47, 0x65, 0x74, 0x4d, - 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, - 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x54, 0x0a, 0x0d, 0x53, - 0x65, 0x6e, 0x64, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x67, 0x12, 0x20, 0x2e, 0x6d, - 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x41, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, - 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x65, 0x6e, 0x64, - 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x51, 0x0a, 0x0c, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, - 0x65, 0x12, 0x1f, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x41, - 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, - 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5d, 0x0a, 0x10, 0x53, 0x65, 0x6e, 0x64, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x23, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, - 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x54, 0x45, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x04, 0x12, 0x16, 0x0a, 0x12, 0x50, + 0x52, 0x4f, 0x58, 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x45, 0x52, 0x52, 0x4f, + 0x52, 0x10, 0x05, 0x32, 0xfc, 0x04, 0x0a, 0x0c, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x12, 0x5f, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, + 0x6e, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x23, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, - 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x5a, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, - 0x78, 0x79, 0x50, 0x65, 0x65, 0x72, 0x12, 0x22, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, - 0x65, 0x6e, 0x74, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x50, - 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x6d, 0x61, 0x6e, - 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, - 0x6f, 0x78, 0x79, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x4b, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x4f, 0x49, 0x44, 0x43, 0x55, 0x52, 0x4c, 0x12, 0x1d, 0x2e, - 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x49, - 0x44, 0x43, 0x55, 0x52, 0x4c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x6d, - 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x49, 0x44, - 0x43, 0x55, 0x52, 0x4c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5a, 0x0a, 0x0f, - 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, - 0x22, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x56, 0x61, 0x6c, - 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, - 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x08, 0x5a, 0x06, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x61, + 0x70, 0x70, 0x69, 0x6e, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x54, 0x0a, 0x0d, 0x53, 0x65, 0x6e, 0x64, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x67, 0x12, 0x20, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x6f, + 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x51, 0x0a, 0x0c, 0x41, + 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x1f, 0x2e, 0x6d, 0x61, + 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, + 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6d, + 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, + 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5d, + 0x0a, 0x10, 0x53, 0x65, 0x6e, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x12, 0x23, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, + 0x53, 0x65, 0x6e, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, + 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5a, 0x0a, + 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x50, 0x65, 0x65, 0x72, + 0x12, 0x22, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x50, 0x65, 0x65, + 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x0a, 0x47, 0x65, 0x74, + 0x4f, 0x49, 0x44, 0x43, 0x55, 0x52, 0x4c, 0x12, 0x1d, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, + 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x49, 0x44, 0x43, 0x55, 0x52, 0x4c, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x49, 0x44, 0x43, 0x55, 0x52, 0x4c, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5a, 0x0a, 0x0f, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, + 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x2e, 0x6d, 0x61, 0x6e, 0x61, + 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, + 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, + 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, + 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x42, 0x08, 0x5a, 0x06, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/shared/management/proto/proxy_service.proto b/shared/management/proto/proxy_service.proto index 617f2b2e4..8b65efeb2 100644 --- a/shared/management/proto/proxy_service.proto +++ b/shared/management/proto/proxy_service.proto @@ -133,7 +133,7 @@ enum ProxyStatus { // SendStatusUpdateRequest is sent by the proxy to update its status message SendStatusUpdateRequest { - string reverse_proxy_id = 1; + string service_id = 1; string account_id = 2; ProxyStatus status = 3; bool certificate_issued = 4; @@ -146,7 +146,7 @@ message SendStatusUpdateResponse {} // CreateProxyPeerRequest is sent by the proxy to create a peer connection // The token is a one-time authentication token sent via ProxyMapping message CreateProxyPeerRequest { - string reverse_proxy_id = 1; + string service_id = 1; string account_id = 2; string token = 3; string wireguard_public_key = 4;