Merge branch 'develop' of https://github.com/gravitl/netmaker into NET-1615

This commit is contained in:
abhishek9686 2024-09-26 12:21:22 +04:00
commit 1d1c033988
5 changed files with 95 additions and 6 deletions

View file

@ -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

View file

@ -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 {

View file

@ -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"`
}

View file

@ -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("<br>").
WithParagraph("Great news! Your colleague has invited you to join their Netmaker SaaS Tenant.").
WithParagraph("Click the button to accept your invitation:").
WithParagraph("<br>").
WithParagraph(fmt.Sprintf("<a class=\"x-button\" href=\"%s\">Accept Invitation</a>", invite.InviteURL)).
WithParagraph("<br>").
WithParagraph("Why you'll love Netmaker:").
WithParagraph("<ul>").
WithParagraph("<li>Blazing-fast connections with our WireGuard®-powered mesh VPN</li>").
WithParagraph("<li>Seamless multi-cloud and hybrid-cloud networking</li>").
WithParagraph("<li>Automated Kubernetes networking across any infrastructure</li>").
WithParagraph("<li>Enterprise-grade security with simple management</li>").
WithParagraph("</ul>").
WithParagraph("Got questions? Our team is here to help you every step of the way.").
WithParagraph("<br>").
WithParagraph("Welcome aboard,").
WithParagraph("<h2>The Netmaker Team</h2>").
WithParagraph("P.S. Curious to learn more before accepting? Check out our quick start tutorial at <a href=\"https://netmaker.io/tutorials\">netmaker.io/tutorials</a>").
Build()
}
return invite.BodyBuilder.
WithHeadline("Join Netmaker from this invite!").
WithParagraph("Hello from Netmaker,").
WithParagraph("You have been invited to join Netmaker.").
WithParagraph(fmt.Sprintf("Join Using This Invite Link <a href=\"%s\">Netmaker</a>", invite.InviteURL)).
WithParagraph("Hi there,").
WithParagraph("<br>").
WithParagraph("Great news! Your colleague has invited you to join their Netmaker network.").
WithParagraph("Click the button to accept your invitation:").
WithParagraph("<br>").
WithParagraph(fmt.Sprintf("<a class=\"x-button\" href=\"%s\">Accept Invitation</a>", invite.InviteURL)).
WithParagraph("<br>").
WithParagraph("Why you'll love Netmaker:").
WithParagraph("<ul>").
WithParagraph("<li>Blazing-fast connections with our WireGuard®-powered mesh VPN</li>").
WithParagraph("<li>Seamless multi-cloud and hybrid-cloud networking</li>").
WithParagraph("<li>Automated Kubernetes networking across any infrastructure</li>").
WithParagraph("<li>Enterprise-grade security with simple management</li>").
WithParagraph("</ul>").
WithParagraph("Got questions? Our team is here to help you every step of the way.").
WithParagraph("<br>").
WithParagraph("Welcome aboard,").
WithParagraph("<h2>The Netmaker Team</h2>").
WithParagraph("P.S. Curious to learn more before accepting? Check out our quick start tutorial at <a href=\"https://netmaker.io/tutorials\">netmaker.io/tutorials</a>").
Build()
}

View file

@ -73,7 +73,7 @@ func (b *EmailBodyBuilderWithH1HeadlineAndImage) Build() string {
</xml>
<![endif]-->
<style>
*{box-sizing:border-box}body{margin:0;padding:0}a[x-apple-data-detectors]{color:inherit!important;text-decoration:inherit!important}#MessageViewBody a{color:inherit;text-decoration:none}p{line-height:inherit}.desktop_hide,.desktop_hide table{mso-hide:all;display:none;max-height:0;overflow:hidden}@media (max-width:720px){.desktop_hide table.icons-inner{display:inline-block!important}.icons-inner{text-align:center}.icons-inner td{margin:0 auto}.image_block img.big,.row-content{width:100%!important}.mobile_hide{display:none}.stack .column{width:100%;display:block}.mobile_hide{min-height:0;max-height:0;max-width:0;overflow:hidden;font-size:0}.desktop_hide,.desktop_hide table{display:table!important;max-height:none!important}}
*{box-sizing:border-box}body{margin:0;padding:0}a[x-apple-data-detectors]{color:inherit!important;text-decoration:inherit!important}#MessageViewBody a{color:inherit;text-decoration:none}p{line-height:inherit}.desktop_hide,.desktop_hide table{mso-hide:all;display:none;max-height:0;overflow:hidden}@media (max-width:720px){.desktop_hide table.icons-inner{display:inline-block!important}.icons-inner{text-align:center}.icons-inner td{margin:0 auto}.image_block img.big,.row-content{width:100%!important}.mobile_hide{display:none}.stack .column{width:100%;display:block}.mobile_hide{min-height:0;max-height:0;max-width:0;overflow:hidden;font-size:0}.desktop_hide,.desktop_hide table{display:table!important;max-height:none!important}} .x-button{background:#5E5DF0;border-radius:999px;box-shadow:#5E5DF0 0 10px 20px -10px;box-sizing:border-box;color:#FFFFFF !important;cursor:pointer;font-family:Inter,Helvetica,"Apple Color Emoji","Segoe UI Emoji",NotoColorEmoji,"Noto Color Emoji","Segoe UI Symbol","Android Emoji",EmojiSymbols,-apple-system,system-ui,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans",sans-serif;font-size:16px;font-weight:700;line-height:24px;opacity:1;outline:0 solid transparent;padding:8px 18px;user-select:none;-webkit-user-select:none;touch-action:manipulation;width:fit-content;word-break:break-word;border:0;margin:20px 20px 20px 0px;text-decoration:none;}
</style>
</head>
<body style="background-color:transparent;margin:0;padding:0;-webkit-text-size-adjust:none;text-size-adjust:none">