mirror of
https://github.com/gravitl/netmaker.git
synced 2025-10-01 07:02:48 +08:00
[NET-494 / ACC-322] New free tier limits (#2495)
* Rename var * Rename consts and use iota * Use switch instead of repeated else if * Rename limits related vars * Introduce new free tier limits * Measure new limits and report on license validation * Separate usage and limits, have new ones * Don't check for hosts and clients limits, but for machines instead * Error on egress creation @ free tier w/ internet gateways * Remove clients and hosts limit from code * Rename var * Rename consts and use iota * Use switch instead of repeated else if * Rename limits related vars * Introduce new free tier limits * Measure new limits and report on license validation * Separate usage and limits, have new ones * Don't check for hosts and clients limits, but for machines instead * Error on egress creation @ free tier w/ internet gateways * Remove clients and hosts limit from code
This commit is contained in:

committed by
GitHub

parent
449f3f947b
commit
8ce7da2ce9
@@ -82,9 +82,10 @@ type ServerConfig struct {
|
|||||||
TurnPassword string `yaml:"turn_password"`
|
TurnPassword string `yaml:"turn_password"`
|
||||||
UseTurn bool `yaml:"use_turn"`
|
UseTurn bool `yaml:"use_turn"`
|
||||||
UsersLimit int `yaml:"user_limit"`
|
UsersLimit int `yaml:"user_limit"`
|
||||||
ClientsLimit int `yaml:"client_limit"`
|
|
||||||
NetworksLimit int `yaml:"network_limit"`
|
NetworksLimit int `yaml:"network_limit"`
|
||||||
HostsLimit int `yaml:"host_limit"`
|
MachinesLimit int `yaml:"machines_limit"`
|
||||||
|
IngressesLimit int `yaml:"ingresses_limit"`
|
||||||
|
EgressesLimit int `yaml:"egresses_limit"`
|
||||||
DeployedByOperator bool `yaml:"deployed_by_operator"`
|
DeployedByOperator bool `yaml:"deployed_by_operator"`
|
||||||
Environment string `yaml:"environment"`
|
Environment string `yaml:"environment"`
|
||||||
}
|
}
|
||||||
|
@@ -29,7 +29,7 @@ func extClientHandlers(r *mux.Router) {
|
|||||||
r.HandleFunc("/api/extclients/{network}/{clientid}/{type}", logic.NetUserSecurityCheck(false, true, http.HandlerFunc(getExtClientConf))).Methods(http.MethodGet)
|
r.HandleFunc("/api/extclients/{network}/{clientid}/{type}", logic.NetUserSecurityCheck(false, true, http.HandlerFunc(getExtClientConf))).Methods(http.MethodGet)
|
||||||
r.HandleFunc("/api/extclients/{network}/{clientid}", logic.NetUserSecurityCheck(false, true, http.HandlerFunc(updateExtClient))).Methods(http.MethodPut)
|
r.HandleFunc("/api/extclients/{network}/{clientid}", logic.NetUserSecurityCheck(false, true, http.HandlerFunc(updateExtClient))).Methods(http.MethodPut)
|
||||||
r.HandleFunc("/api/extclients/{network}/{clientid}", logic.NetUserSecurityCheck(false, true, http.HandlerFunc(deleteExtClient))).Methods(http.MethodDelete)
|
r.HandleFunc("/api/extclients/{network}/{clientid}", logic.NetUserSecurityCheck(false, true, http.HandlerFunc(deleteExtClient))).Methods(http.MethodDelete)
|
||||||
r.HandleFunc("/api/extclients/{network}/{nodeid}", logic.NetUserSecurityCheck(false, true, checkFreeTierLimits(clients_l, http.HandlerFunc(createExtClient)))).Methods(http.MethodPost)
|
r.HandleFunc("/api/extclients/{network}/{nodeid}", logic.NetUserSecurityCheck(false, true, checkFreeTierLimits(limitChoiceMachines, http.HandlerFunc(createExtClient)))).Methods(http.MethodPost)
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkIngressExists(nodeID string) bool {
|
func checkIngressExists(nodeID string) bool {
|
||||||
|
@@ -10,36 +10,60 @@ import (
|
|||||||
|
|
||||||
// limit consts
|
// limit consts
|
||||||
const (
|
const (
|
||||||
node_l = 0
|
limitChoiceNetworks = iota
|
||||||
networks_l = 1
|
limitChoiceUsers
|
||||||
users_l = 2
|
limitChoiceMachines
|
||||||
clients_l = 3
|
limitChoiceIngress
|
||||||
|
limitChoiceEgress
|
||||||
)
|
)
|
||||||
|
|
||||||
func checkFreeTierLimits(limit_choice int, next http.Handler) http.HandlerFunc {
|
func checkFreeTierLimits(limitChoice int, next http.Handler) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
var errorResponse = models.ErrorResponse{
|
var errorResponse = models.ErrorResponse{
|
||||||
Code: http.StatusForbidden, Message: "free tier limits exceeded on networks",
|
Code: http.StatusForbidden, Message: "free tier limits exceeded on ",
|
||||||
}
|
}
|
||||||
|
|
||||||
if logic.Free_Tier { // check that free tier limits not exceeded
|
if logic.FreeTier { // check that free tier limits not exceeded
|
||||||
if limit_choice == networks_l {
|
switch limitChoice {
|
||||||
|
case limitChoiceNetworks:
|
||||||
currentNetworks, err := logic.GetNetworks()
|
currentNetworks, err := logic.GetNetworks()
|
||||||
if (err != nil && !database.IsEmptyRecord(err)) || len(currentNetworks) >= logic.Networks_Limit {
|
if (err != nil && !database.IsEmptyRecord(err)) ||
|
||||||
|
len(currentNetworks) >= logic.NetworksLimit {
|
||||||
|
errorResponse.Message += "networks"
|
||||||
logic.ReturnErrorResponse(w, r, errorResponse)
|
logic.ReturnErrorResponse(w, r, errorResponse)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else if limit_choice == users_l {
|
case limitChoiceUsers:
|
||||||
users, err := logic.GetUsers()
|
users, err := logic.GetUsers()
|
||||||
if (err != nil && !database.IsEmptyRecord(err)) || len(users) >= logic.Users_Limit {
|
if (err != nil && !database.IsEmptyRecord(err)) ||
|
||||||
errorResponse.Message = "free tier limits exceeded on users"
|
len(users) >= logic.UsersLimit {
|
||||||
|
errorResponse.Message += "users"
|
||||||
logic.ReturnErrorResponse(w, r, errorResponse)
|
logic.ReturnErrorResponse(w, r, errorResponse)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else if limit_choice == clients_l {
|
case limitChoiceMachines:
|
||||||
clients, err := logic.GetAllExtClients()
|
hosts, hErr := logic.GetAllHosts()
|
||||||
if (err != nil && !database.IsEmptyRecord(err)) || len(clients) >= logic.Clients_Limit {
|
clients, cErr := logic.GetAllExtClients()
|
||||||
errorResponse.Message = "free tier limits exceeded on external clients"
|
if (hErr != nil && !database.IsEmptyRecord(hErr)) ||
|
||||||
|
(cErr != nil && !database.IsEmptyRecord(cErr)) ||
|
||||||
|
len(hosts)+len(clients) >= logic.MachinesLimit {
|
||||||
|
errorResponse.Message += "machines"
|
||||||
|
logic.ReturnErrorResponse(w, r, errorResponse)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
case limitChoiceIngress:
|
||||||
|
ingresses, err := logic.GetAllIngresses()
|
||||||
|
if (err != nil && !database.IsEmptyRecord(err)) ||
|
||||||
|
len(ingresses) >= logic.IngressesLimit {
|
||||||
|
errorResponse.Message += "ingresses"
|
||||||
|
logic.ReturnErrorResponse(w, r, errorResponse)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
case limitChoiceEgress:
|
||||||
|
egresses, err := logic.GetAllEgresses()
|
||||||
|
if (err != nil && !database.IsEmptyRecord(err)) ||
|
||||||
|
len(egresses) >= logic.EgressesLimit {
|
||||||
|
errorResponse.Message += "egresses"
|
||||||
logic.ReturnErrorResponse(w, r, errorResponse)
|
logic.ReturnErrorResponse(w, r, errorResponse)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@@ -21,7 +21,7 @@ import (
|
|||||||
|
|
||||||
func networkHandlers(r *mux.Router) {
|
func networkHandlers(r *mux.Router) {
|
||||||
r.HandleFunc("/api/networks", logic.SecurityCheck(false, http.HandlerFunc(getNetworks))).Methods(http.MethodGet)
|
r.HandleFunc("/api/networks", logic.SecurityCheck(false, http.HandlerFunc(getNetworks))).Methods(http.MethodGet)
|
||||||
r.HandleFunc("/api/networks", logic.SecurityCheck(true, checkFreeTierLimits(networks_l, http.HandlerFunc(createNetwork)))).Methods(http.MethodPost)
|
r.HandleFunc("/api/networks", logic.SecurityCheck(true, checkFreeTierLimits(limitChoiceNetworks, http.HandlerFunc(createNetwork)))).Methods(http.MethodPost)
|
||||||
r.HandleFunc("/api/networks/{networkname}", logic.SecurityCheck(false, http.HandlerFunc(getNetwork))).Methods(http.MethodGet)
|
r.HandleFunc("/api/networks/{networkname}", logic.SecurityCheck(false, http.HandlerFunc(getNetwork))).Methods(http.MethodGet)
|
||||||
r.HandleFunc("/api/networks/{networkname}", logic.SecurityCheck(true, http.HandlerFunc(deleteNetwork))).Methods(http.MethodDelete)
|
r.HandleFunc("/api/networks/{networkname}", logic.SecurityCheck(true, http.HandlerFunc(deleteNetwork))).Methods(http.MethodDelete)
|
||||||
r.HandleFunc("/api/networks/{networkname}", logic.SecurityCheck(true, http.HandlerFunc(updateNetwork))).Methods(http.MethodPut)
|
r.HandleFunc("/api/networks/{networkname}", logic.SecurityCheck(true, http.HandlerFunc(updateNetwork))).Methods(http.MethodPut)
|
||||||
|
@@ -28,9 +28,9 @@ func nodeHandlers(r *mux.Router) {
|
|||||||
r.HandleFunc("/api/nodes/{network}/{nodeid}", Authorize(true, true, "node", http.HandlerFunc(getNode))).Methods(http.MethodGet)
|
r.HandleFunc("/api/nodes/{network}/{nodeid}", Authorize(true, true, "node", http.HandlerFunc(getNode))).Methods(http.MethodGet)
|
||||||
r.HandleFunc("/api/nodes/{network}/{nodeid}", Authorize(false, true, "node", http.HandlerFunc(updateNode))).Methods(http.MethodPut)
|
r.HandleFunc("/api/nodes/{network}/{nodeid}", Authorize(false, true, "node", http.HandlerFunc(updateNode))).Methods(http.MethodPut)
|
||||||
r.HandleFunc("/api/nodes/{network}/{nodeid}", Authorize(true, true, "node", http.HandlerFunc(deleteNode))).Methods(http.MethodDelete)
|
r.HandleFunc("/api/nodes/{network}/{nodeid}", Authorize(true, true, "node", http.HandlerFunc(deleteNode))).Methods(http.MethodDelete)
|
||||||
r.HandleFunc("/api/nodes/{network}/{nodeid}/creategateway", Authorize(false, true, "user", http.HandlerFunc(createEgressGateway))).Methods(http.MethodPost)
|
r.HandleFunc("/api/nodes/{network}/{nodeid}/creategateway", Authorize(false, true, "user", checkFreeTierLimits(limitChoiceEgress, http.HandlerFunc(createEgressGateway)))).Methods(http.MethodPost)
|
||||||
r.HandleFunc("/api/nodes/{network}/{nodeid}/deletegateway", Authorize(false, true, "user", http.HandlerFunc(deleteEgressGateway))).Methods(http.MethodDelete)
|
r.HandleFunc("/api/nodes/{network}/{nodeid}/deletegateway", Authorize(false, true, "user", http.HandlerFunc(deleteEgressGateway))).Methods(http.MethodDelete)
|
||||||
r.HandleFunc("/api/nodes/{network}/{nodeid}/createingress", logic.SecurityCheck(false, http.HandlerFunc(createIngressGateway))).Methods(http.MethodPost)
|
r.HandleFunc("/api/nodes/{network}/{nodeid}/createingress", logic.SecurityCheck(false, checkFreeTierLimits(limitChoiceIngress, http.HandlerFunc(createIngressGateway)))).Methods(http.MethodPost)
|
||||||
r.HandleFunc("/api/nodes/{network}/{nodeid}/deleteingress", logic.SecurityCheck(false, http.HandlerFunc(deleteIngressGateway))).Methods(http.MethodDelete)
|
r.HandleFunc("/api/nodes/{network}/{nodeid}/deleteingress", logic.SecurityCheck(false, http.HandlerFunc(deleteIngressGateway))).Methods(http.MethodDelete)
|
||||||
r.HandleFunc("/api/nodes/{network}/{nodeid}", Authorize(true, true, "node", http.HandlerFunc(updateNode))).Methods(http.MethodPost)
|
r.HandleFunc("/api/nodes/{network}/{nodeid}", Authorize(true, true, "node", http.HandlerFunc(updateNode))).Methods(http.MethodPost)
|
||||||
r.HandleFunc("/api/nodes/adm/{network}/authenticate", authenticate).Methods(http.MethodPost)
|
r.HandleFunc("/api/nodes/adm/{network}/authenticate", authenticate).Methods(http.MethodPost)
|
||||||
|
@@ -24,12 +24,16 @@ func serverHandlers(r *mux.Router) {
|
|||||||
r.HandleFunc("/api/server/status", http.HandlerFunc(getStatus)).Methods(http.MethodGet)
|
r.HandleFunc("/api/server/status", http.HandlerFunc(getStatus)).Methods(http.MethodGet)
|
||||||
r.HandleFunc("/api/server/usage", Authorize(true, false, "user", http.HandlerFunc(getUsage))).Methods(http.MethodGet)
|
r.HandleFunc("/api/server/usage", Authorize(true, false, "user", http.HandlerFunc(getUsage))).Methods(http.MethodGet)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO move to EE package? there is a function and a type there for that already
|
||||||
func getUsage(w http.ResponseWriter, r *http.Request) {
|
func getUsage(w http.ResponseWriter, r *http.Request) {
|
||||||
type usage struct {
|
type usage struct {
|
||||||
Hosts int `json:"hosts"`
|
Hosts int `json:"hosts"`
|
||||||
Clients int `json:"clients"`
|
Clients int `json:"clients"`
|
||||||
Networks int `json:"networks"`
|
Networks int `json:"networks"`
|
||||||
Users int `json:"users"`
|
Users int `json:"users"`
|
||||||
|
Ingresses int `json:"ingresses"`
|
||||||
|
Egresses int `json:"egresses"`
|
||||||
}
|
}
|
||||||
var serverUsage usage
|
var serverUsage usage
|
||||||
hosts, err := logic.GetAllHosts()
|
hosts, err := logic.GetAllHosts()
|
||||||
@@ -48,6 +52,14 @@ func getUsage(w http.ResponseWriter, r *http.Request) {
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
serverUsage.Networks = len(networks)
|
serverUsage.Networks = len(networks)
|
||||||
}
|
}
|
||||||
|
ingresses, err := logic.GetAllIngresses()
|
||||||
|
if err == nil {
|
||||||
|
serverUsage.Ingresses = len(ingresses)
|
||||||
|
}
|
||||||
|
egresses, err := logic.GetAllEgresses()
|
||||||
|
if err == nil {
|
||||||
|
serverUsage.Egresses = len(egresses)
|
||||||
|
}
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
json.NewEncoder(w).Encode(models.SuccessResponse{
|
json.NewEncoder(w).Encode(models.SuccessResponse{
|
||||||
Code: http.StatusOK,
|
Code: http.StatusOK,
|
||||||
|
@@ -30,7 +30,7 @@ func userHandlers(r *mux.Router) {
|
|||||||
r.HandleFunc("/api/users/{username}", logic.SecurityCheck(false, logic.ContinueIfUserMatch(http.HandlerFunc(updateUser)))).Methods(http.MethodPut)
|
r.HandleFunc("/api/users/{username}", logic.SecurityCheck(false, logic.ContinueIfUserMatch(http.HandlerFunc(updateUser)))).Methods(http.MethodPut)
|
||||||
r.HandleFunc("/api/users/networks/{username}", logic.SecurityCheck(true, http.HandlerFunc(updateUserNetworks))).Methods(http.MethodPut)
|
r.HandleFunc("/api/users/networks/{username}", logic.SecurityCheck(true, http.HandlerFunc(updateUserNetworks))).Methods(http.MethodPut)
|
||||||
r.HandleFunc("/api/users/{username}/adm", logic.SecurityCheck(true, http.HandlerFunc(updateUserAdm))).Methods(http.MethodPut)
|
r.HandleFunc("/api/users/{username}/adm", logic.SecurityCheck(true, http.HandlerFunc(updateUserAdm))).Methods(http.MethodPut)
|
||||||
r.HandleFunc("/api/users/{username}", logic.SecurityCheck(true, checkFreeTierLimits(users_l, http.HandlerFunc(createUser)))).Methods(http.MethodPost)
|
r.HandleFunc("/api/users/{username}", logic.SecurityCheck(true, checkFreeTierLimits(limitChoiceUsers, http.HandlerFunc(createUser)))).Methods(http.MethodPost)
|
||||||
r.HandleFunc("/api/users/{username}", logic.SecurityCheck(true, http.HandlerFunc(deleteUser))).Methods(http.MethodDelete)
|
r.HandleFunc("/api/users/{username}", logic.SecurityCheck(true, http.HandlerFunc(deleteUser))).Methods(http.MethodDelete)
|
||||||
r.HandleFunc("/api/users/{username}", logic.SecurityCheck(false, logic.ContinueIfUserMatch(http.HandlerFunc(getUser)))).Methods(http.MethodGet)
|
r.HandleFunc("/api/users/{username}", logic.SecurityCheck(false, logic.ContinueIfUserMatch(http.HandlerFunc(getUser)))).Methods(http.MethodGet)
|
||||||
r.HandleFunc("/api/users", logic.SecurityCheck(true, http.HandlerFunc(getUsers))).Methods(http.MethodGet)
|
r.HandleFunc("/api/users", logic.SecurityCheck(true, http.HandlerFunc(getUsers))).Methods(http.MethodGet)
|
||||||
|
@@ -81,7 +81,7 @@ func ValidateLicense() (err error) {
|
|||||||
|
|
||||||
licenseSecret := LicenseSecret{
|
licenseSecret := LicenseSecret{
|
||||||
AssociatedID: netmakerTenantID,
|
AssociatedID: netmakerTenantID,
|
||||||
Limits: getCurrentServerLimit(),
|
Usage: getCurrentServerUsage(),
|
||||||
}
|
}
|
||||||
|
|
||||||
secretData, err := json.Marshal(&licenseSecret)
|
secretData, err := json.Marshal(&licenseSecret)
|
||||||
|
26
ee/types.go
26
ee/types.go
@@ -26,11 +26,13 @@ var errValidation = fmt.Errorf(license_validation_err_msg)
|
|||||||
type LicenseKey struct {
|
type LicenseKey struct {
|
||||||
LicenseValue string `json:"license_value"` // actual (public) key and the unique value for the key
|
LicenseValue string `json:"license_value"` // actual (public) key and the unique value for the key
|
||||||
Expiration int64 `json:"expiration"`
|
Expiration int64 `json:"expiration"`
|
||||||
LimitServers int `json:"limit_servers"`
|
UsageServers int `json:"usage_servers"`
|
||||||
LimitUsers int `json:"limit_users"`
|
UsageUsers int `json:"usage_users"`
|
||||||
LimitHosts int `json:"limit_hosts"`
|
UsageClients int `json:"usage_clients"`
|
||||||
LimitNetworks int `json:"limit_networks"`
|
UsageHosts int `json:"usage_hosts"`
|
||||||
LimitClients int `json:"limit_clients"`
|
UsageNetworks int `json:"usage_networks"`
|
||||||
|
UsageIngresses int `json:"usage_ingresses"`
|
||||||
|
UsageEgresses int `json:"usage_egresses"`
|
||||||
Metadata string `json:"metadata"`
|
Metadata string `json:"metadata"`
|
||||||
IsActive bool `json:"is_active"` // yes if active
|
IsActive bool `json:"is_active"` // yes if active
|
||||||
}
|
}
|
||||||
@@ -44,25 +46,29 @@ type ValidatedLicense struct {
|
|||||||
// LicenseSecret - the encrypted struct for sending user-id
|
// LicenseSecret - the encrypted struct for sending user-id
|
||||||
type LicenseSecret struct {
|
type LicenseSecret struct {
|
||||||
AssociatedID string `json:"associated_id" binding:"required"` // UUID for user foreign key to User table
|
AssociatedID string `json:"associated_id" binding:"required"` // UUID for user foreign key to User table
|
||||||
Limits LicenseLimits `json:"limits" binding:"required"`
|
Usage Usage `json:"usage" binding:"required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// LicenseLimits - struct license limits
|
// Usage - struct for license usage
|
||||||
type LicenseLimits struct {
|
type Usage struct {
|
||||||
Servers int `json:"servers"`
|
Servers int `json:"servers"`
|
||||||
Users int `json:"users"`
|
Users int `json:"users"`
|
||||||
Hosts int `json:"hosts"`
|
Hosts int `json:"hosts"`
|
||||||
Clients int `json:"clients"`
|
Clients int `json:"clients"`
|
||||||
Networks int `json:"networks"`
|
Networks int `json:"networks"`
|
||||||
|
Ingresses int `json:"ingresses"`
|
||||||
|
Egresses int `json:"egresses"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// LicenseLimits.SetDefaults - sets the default values for limits
|
// Usage.SetDefaults - sets the default values for usage
|
||||||
func (l *LicenseLimits) SetDefaults() {
|
func (l *Usage) SetDefaults() {
|
||||||
l.Clients = 0
|
l.Clients = 0
|
||||||
l.Servers = 1
|
l.Servers = 1
|
||||||
l.Hosts = 0
|
l.Hosts = 0
|
||||||
l.Users = 1
|
l.Users = 1
|
||||||
l.Networks = 0
|
l.Networks = 0
|
||||||
|
l.Ingresses = 0
|
||||||
|
l.Egresses = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValidateLicenseRequest - used for request to validate license endpoint
|
// ValidateLicenseRequest - used for request to validate license endpoint
|
||||||
|
19
ee/util.go
19
ee/util.go
@@ -30,14 +30,15 @@ func base64decode(input string) []byte {
|
|||||||
|
|
||||||
return bytes
|
return bytes
|
||||||
}
|
}
|
||||||
func getCurrentServerLimit() (limits LicenseLimits) {
|
|
||||||
|
func getCurrentServerUsage() (limits Usage) {
|
||||||
limits.SetDefaults()
|
limits.SetDefaults()
|
||||||
hosts, err := logic.GetAllHosts()
|
hosts, hErr := logic.GetAllHosts()
|
||||||
if err == nil {
|
if hErr == nil {
|
||||||
limits.Hosts = len(hosts)
|
limits.Hosts = len(hosts)
|
||||||
}
|
}
|
||||||
clients, err := logic.GetAllExtClients()
|
clients, cErr := logic.GetAllExtClients()
|
||||||
if err == nil {
|
if cErr == nil {
|
||||||
limits.Clients = len(clients)
|
limits.Clients = len(clients)
|
||||||
}
|
}
|
||||||
users, err := logic.GetUsers()
|
users, err := logic.GetUsers()
|
||||||
@@ -48,5 +49,13 @@ func getCurrentServerLimit() (limits LicenseLimits) {
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
limits.Networks = len(networks)
|
limits.Networks = len(networks)
|
||||||
}
|
}
|
||||||
|
ingresses, err := logic.GetAllIngresses()
|
||||||
|
if err == nil {
|
||||||
|
limits.Ingresses = len(ingresses)
|
||||||
|
}
|
||||||
|
egresses, err := logic.GetAllEgresses()
|
||||||
|
if err == nil {
|
||||||
|
limits.Egresses = len(egresses)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@@ -11,6 +11,36 @@ import (
|
|||||||
"github.com/gravitl/netmaker/servercfg"
|
"github.com/gravitl/netmaker/servercfg"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// GetAllIngresses - gets all the hosts that are ingresses
|
||||||
|
func GetAllIngresses() ([]models.Node, error) {
|
||||||
|
nodes, err := GetAllNodes()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
ingresses := make([]models.Node, 0)
|
||||||
|
for _, node := range nodes {
|
||||||
|
if node.IsIngressGateway {
|
||||||
|
ingresses = append(ingresses, node)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ingresses, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAllEgresses - gets all the hosts that are egresses
|
||||||
|
func GetAllEgresses() ([]models.Node, error) {
|
||||||
|
nodes, err := GetAllNodes()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
egresses := make([]models.Node, 0)
|
||||||
|
for _, node := range nodes {
|
||||||
|
if node.IsEgressGateway {
|
||||||
|
egresses = append(egresses, node)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return egresses, nil
|
||||||
|
}
|
||||||
|
|
||||||
// CreateEgressGateway - creates an egress gateway
|
// CreateEgressGateway - creates an egress gateway
|
||||||
func CreateEgressGateway(gateway models.EgressGatewayRequest) (models.Node, error) {
|
func CreateEgressGateway(gateway models.EgressGatewayRequest) (models.Node, error) {
|
||||||
node, err := GetNodeByID(gateway.NodeID)
|
node, err := GetNodeByID(gateway.NodeID)
|
||||||
@@ -28,10 +58,13 @@ func CreateEgressGateway(gateway models.EgressGatewayRequest) (models.Node, erro
|
|||||||
return models.Node{}, errors.New("firewall is not supported for egress gateways")
|
return models.Node{}, errors.New("firewall is not supported for egress gateways")
|
||||||
}
|
}
|
||||||
for i := len(gateway.Ranges) - 1; i >= 0; i-- {
|
for i := len(gateway.Ranges) - 1; i >= 0; i-- {
|
||||||
|
// check if internet gateway IPv4
|
||||||
|
if gateway.Ranges[i] == "0.0.0.0/0" && FreeTier {
|
||||||
|
return models.Node{}, fmt.Errorf("currently IPv4 internet gateways are not supported on the free tier: %s", gateway.Ranges[i])
|
||||||
|
}
|
||||||
|
// check if internet gateway IPv6
|
||||||
if gateway.Ranges[i] == "::/0" {
|
if gateway.Ranges[i] == "::/0" {
|
||||||
logger.Log(0, "currently IPv6 internet gateways are not supported", gateway.Ranges[i])
|
return models.Node{}, fmt.Errorf("currently IPv6 internet gateways are not supported: %s", gateway.Ranges[i])
|
||||||
gateway.Ranges = append(gateway.Ranges[:i], gateway.Ranges[i+1:]...)
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
normalized, err := NormalizeCIDR(gateway.Ranges[i])
|
normalized, err := NormalizeCIDR(gateway.Ranges[i])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -150,15 +183,6 @@ func DeleteIngressGateway(nodeid string) (models.Node, bool, []models.ExtClient,
|
|||||||
node.IsIngressGateway = false
|
node.IsIngressGateway = false
|
||||||
node.IngressGatewayRange = ""
|
node.IngressGatewayRange = ""
|
||||||
node.Failover = false
|
node.Failover = false
|
||||||
|
|
||||||
//logger.Log(3, "deleting ingress gateway firewall in use is '", host.FirewallInUse, "' and isEgressGateway is", node.IsEgressGateway)
|
|
||||||
if node.EgressGatewayRequest.NodeID != "" {
|
|
||||||
_, err := CreateEgressGateway(node.EgressGatewayRequest)
|
|
||||||
if err != nil {
|
|
||||||
logger.Log(0, fmt.Sprintf("failed to create egress gateway on node [%s] on network [%s]: %v",
|
|
||||||
node.EgressGatewayRequest.NodeID, node.EgressGatewayRequest.NetID, err))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err = UpsertNode(&node)
|
err = UpsertNode(&node)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return models.Node{}, wasFailover, removedClients, err
|
return models.Node{}, wasFailover, removedClients, err
|
||||||
|
@@ -158,14 +158,14 @@ func GetHost(hostid string) (*models.Host, error) {
|
|||||||
|
|
||||||
// CreateHost - creates a host if not exist
|
// CreateHost - creates a host if not exist
|
||||||
func CreateHost(h *models.Host) error {
|
func CreateHost(h *models.Host) error {
|
||||||
hosts, err := GetAllHosts()
|
hosts, hErr := GetAllHosts()
|
||||||
if err != nil && !database.IsEmptyRecord(err) {
|
clients, cErr := GetAllExtClients()
|
||||||
return err
|
if (hErr != nil && !database.IsEmptyRecord(hErr)) ||
|
||||||
|
(cErr != nil && !database.IsEmptyRecord(cErr)) ||
|
||||||
|
len(hosts)+len(clients) >= MachinesLimit {
|
||||||
|
return errors.New("free tier limits exceeded on machines")
|
||||||
}
|
}
|
||||||
if len(hosts) >= Hosts_Limit {
|
_, err := GetHost(h.ID.String())
|
||||||
return errors.New("free tier limits exceeded on hosts")
|
|
||||||
}
|
|
||||||
_, err = GetHost(h.ID.String())
|
|
||||||
if (err != nil && !database.IsEmptyRecord(err)) || (err == nil) {
|
if (err != nil && !database.IsEmptyRecord(err)) || (err == nil) {
|
||||||
return ErrHostExists
|
return ErrHostExists
|
||||||
}
|
}
|
||||||
|
@@ -2,22 +2,23 @@ package logic
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
||||||
"github.com/gravitl/netmaker/database"
|
"github.com/gravitl/netmaker/database"
|
||||||
"github.com/gravitl/netmaker/servercfg"
|
"github.com/gravitl/netmaker/servercfg"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// Networks_Limit - dummy var for community
|
// NetworksLimit - dummy var for community
|
||||||
Networks_Limit = 1000000000
|
NetworksLimit = 1000000000
|
||||||
// Users_Limit - dummy var for community
|
// UsersLimit - dummy var for community
|
||||||
Users_Limit = 1000000000
|
UsersLimit = 1000000000
|
||||||
// Clients_Limit - dummy var for community
|
// MachinesLimit - dummy var for community
|
||||||
Clients_Limit = 1000000000
|
MachinesLimit = 1000000000
|
||||||
// Hosts_Limit - dummy var for community
|
// IngressesLimit - dummy var for community
|
||||||
Hosts_Limit = 1000000000
|
IngressesLimit = 1000000000
|
||||||
// Free_Tier - specifies if free tier
|
// EgressesLimit - dummy var for community
|
||||||
Free_Tier = false
|
EgressesLimit = 1000000000
|
||||||
|
// FreeTier - specifies if free tier
|
||||||
|
FreeTier = false
|
||||||
)
|
)
|
||||||
|
|
||||||
type serverData struct {
|
type serverData struct {
|
||||||
@@ -87,10 +88,12 @@ func StoreJWTSecret(privateKey string) error {
|
|||||||
return database.Insert("nm-jwt-secret", string(data), database.SERVERCONF_TABLE_NAME)
|
return database.Insert("nm-jwt-secret", string(data), database.SERVERCONF_TABLE_NAME)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetFreeTierLimits - sets limits for free tier
|
||||||
func SetFreeTierLimits() {
|
func SetFreeTierLimits() {
|
||||||
Free_Tier = true
|
FreeTier = true
|
||||||
Users_Limit = servercfg.GetUserLimit()
|
UsersLimit = servercfg.GetUserLimit()
|
||||||
Clients_Limit = servercfg.GetClientLimit()
|
NetworksLimit = servercfg.GetNetworkLimit()
|
||||||
Networks_Limit = servercfg.GetNetworkLimit()
|
MachinesLimit = servercfg.GetMachinesLimit()
|
||||||
Hosts_Limit = servercfg.GetHostLimit()
|
IngressesLimit = servercfg.GetIngressLimit()
|
||||||
|
EgressesLimit = servercfg.GetEgressLimit()
|
||||||
}
|
}
|
||||||
|
@@ -753,26 +753,28 @@ func GetNetworkLimit() int {
|
|||||||
return networkslimit
|
return networkslimit
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetClientLimit - fetches free tier limits on ext. clients
|
// GetMachinesLimit - fetches free tier limits on machines (clients + hosts)
|
||||||
func GetClientLimit() int {
|
func GetMachinesLimit() int {
|
||||||
var clientsLimit int
|
if l, err := strconv.Atoi(os.Getenv("MACHINES_LIMIT")); err == nil {
|
||||||
if os.Getenv("CLIENTS_LIMIT") != "" {
|
return l
|
||||||
clientsLimit, _ = strconv.Atoi(os.Getenv("CLIENTS_LIMIT"))
|
|
||||||
} else {
|
|
||||||
clientsLimit = config.Config.Server.ClientsLimit
|
|
||||||
}
|
}
|
||||||
return clientsLimit
|
return config.Config.Server.MachinesLimit
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetHostLimit - fetches free tier limits on hosts
|
// GetIngressLimit - fetches free tier limits on ingresses
|
||||||
func GetHostLimit() int {
|
func GetIngressLimit() int {
|
||||||
var hostsLimit int
|
if l, err := strconv.Atoi(os.Getenv("INGRESSES_LIMIT")); err == nil {
|
||||||
if os.Getenv("HOSTS_LIMIT") != "" {
|
return l
|
||||||
hostsLimit, _ = strconv.Atoi(os.Getenv("HOSTS_LIMIT"))
|
|
||||||
} else {
|
|
||||||
hostsLimit = config.Config.Server.HostsLimit
|
|
||||||
}
|
}
|
||||||
return hostsLimit
|
return config.Config.Server.IngressesLimit
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetEgressLimit - fetches free tier limits on egresses
|
||||||
|
func GetEgressLimit() int {
|
||||||
|
if l, err := strconv.Atoi(os.Getenv("EGRESSES_LIMIT")); err == nil {
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
return config.Config.Server.EgressesLimit
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeployedByOperator - returns true if the instance is deployed by netmaker operator
|
// DeployedByOperator - returns true if the instance is deployed by netmaker operator
|
||||||
|
Reference in New Issue
Block a user