diff --git a/controllers/network.go b/controllers/network.go
index f340e836..d822b539 100644
--- a/controllers/network.go
+++ b/controllers/network.go
@@ -24,6 +24,8 @@ import (
func networkHandlers(r *mux.Router) {
r.HandleFunc("/api/networks", logic.SecurityCheck(true, http.HandlerFunc(getNetworks))).
Methods(http.MethodGet)
+ r.HandleFunc("/api/v1/networks/stats", logic.SecurityCheck(true, http.HandlerFunc(getNetworksStats))).
+ Methods(http.MethodGet)
r.HandleFunc("/api/networks", logic.SecurityCheck(true, checkFreeTierLimits(limitChoiceNetworks, http.HandlerFunc(createNetwork)))).
Methods(http.MethodPost)
r.HandleFunc("/api/networks/{networkname}", logic.SecurityCheck(true, http.HandlerFunc(getNetwork))).
@@ -74,6 +76,48 @@ func getNetworks(w http.ResponseWriter, r *http.Request) {
json.NewEncoder(w).Encode(allnetworks)
}
+// @Summary Lists all networks with stats
+// @Router /api/v1/networks/stats [get]
+// @Tags Networks
+// @Security oauth
+// @Produce json
+// @Success 200 {object} models.SuccessResponse
+// @Failure 500 {object} models.ErrorResponse
+func getNetworksStats(w http.ResponseWriter, r *http.Request) {
+
+ var err error
+ allnetworks, err := logic.GetNetworks()
+ if err != nil && !database.IsEmptyRecord(err) {
+ slog.Error("failed to fetch networks", "error", err.Error())
+ logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
+ return
+ }
+ if r.Header.Get("ismaster") != "yes" {
+ username := r.Header.Get("user")
+ user, err := logic.GetUser(username)
+ if err != nil {
+ logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
+ return
+ }
+ allnetworks = logic.FilterNetworksByRole(allnetworks, *user)
+ }
+ allNodes, err := logic.GetAllNodes()
+ if err != nil {
+ logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
+ return
+ }
+ netstats := []models.NetworkStatResp{}
+ logic.SortNetworks(allnetworks[:])
+ for _, network := range allnetworks {
+ netstats = append(netstats, models.NetworkStatResp{
+ Network: network,
+ Hosts: len(logic.GetNetworkNodesMemory(allNodes, network.NetID)),
+ })
+ }
+ logger.Log(2, r.Header.Get("user"), "fetched networks.")
+ logic.ReturnSuccessResponseWithJson(w, r, netstats, "fetched networks with stats")
+}
+
// @Summary Get a network
// @Router /api/networks/{networkname} [get]
// @Tags Networks
diff --git a/migrate/migrate.go b/migrate/migrate.go
index 1675f4ee..a2d9b65d 100644
--- a/migrate/migrate.go
+++ b/migrate/migrate.go
@@ -319,6 +319,7 @@ func syncUsers() {
nodes, err := logic.GetAllNodes()
if err == nil {
for _, netI := range networks {
+ logic.CreateDefaultNetworkRolesAndGroups(models.NetworkID(netI.NetID))
networkNodes := logic.GetNetworkNodesMemory(nodes, netI.NetID)
for _, networkNodeI := range networkNodes {
if networkNodeI.IsIngressGateway {
diff --git a/models/network.go b/models/network.go
index c29b45d7..32d95f86 100644
--- a/models/network.go
+++ b/models/network.go
@@ -97,3 +97,8 @@ func (network *Network) GetNetworkNetworkCIDR6() *net.IPNet {
_, netCidr, _ := net.ParseCIDR(network.AddressRange6)
return netCidr
}
+
+type NetworkStatResp struct {
+ Network
+ Hosts int `json:"hosts"`
+}
diff --git a/pro/email/invite.go b/pro/email/invite.go
index c2b39bd2..86018462 100644
--- a/pro/email/invite.go
+++ b/pro/email/invite.go
@@ -2,6 +2,7 @@ package email
import (
"fmt"
+ "github.com/gravitl/netmaker/servercfg"
)
// UserInvitedMail - mail for users that are invited to a tenant
@@ -12,16 +13,54 @@ type UserInvitedMail struct {
// GetSubject - gets the subject of the email
func (UserInvitedMail) GetSubject(info Notification) string {
- return "Netmaker: Pending Invitation"
+ return "You're invited to join Netmaker"
}
// GetBody - gets the body of the email
func (invite UserInvitedMail) GetBody(info Notification) string {
+ if servercfg.DeployedByOperator() {
+ return invite.BodyBuilder.
+ WithParagraph("Hi there,").
+ WithParagraph("
").
+ WithParagraph("Great news! Your colleague has invited you to join their Netmaker SaaS Tenant.").
+ WithParagraph("Click the button to accept your invitation:").
+ WithParagraph("
").
+ WithParagraph(fmt.Sprintf("Accept Invitation", invite.InviteURL)).
+ WithParagraph("
").
+ WithParagraph("Why you'll love Netmaker:").
+ WithParagraph("