Skip to content

Commit

Permalink
Merge branch 'develop' into issue-6322
Browse files Browse the repository at this point in the history
  • Loading branch information
srikanthccv authored Nov 12, 2024
2 parents 2e36fb8 + fd9e9f0 commit 73f198c
Show file tree
Hide file tree
Showing 39 changed files with 3,667 additions and 553 deletions.
17 changes: 17 additions & 0 deletions ee/query-service/app/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ type APIHandlerOptions struct {
// Querier Influx Interval
FluxInterval time.Duration
UseLogsNewSchema bool
UseLicensesV3 bool
}

type APIHandler struct {
Expand All @@ -65,6 +66,7 @@ func NewAPIHandler(opts APIHandlerOptions) (*APIHandler, error) {
Cache: opts.Cache,
FluxInterval: opts.FluxInterval,
UseLogsNewSchema: opts.UseLogsNewSchema,
UseLicensesV3: opts.UseLicensesV3,
})

if err != nil {
Expand Down Expand Up @@ -173,10 +175,25 @@ func (ah *APIHandler) RegisterRoutes(router *mux.Router, am *baseapp.AuthMiddlew
router.HandleFunc("/api/v1/dashboards/{uuid}/lock", am.EditAccess(ah.lockDashboard)).Methods(http.MethodPut)
router.HandleFunc("/api/v1/dashboards/{uuid}/unlock", am.EditAccess(ah.unlockDashboard)).Methods(http.MethodPut)

// v2
router.HandleFunc("/api/v2/licenses",
am.ViewAccess(ah.listLicensesV2)).
Methods(http.MethodGet)

// v3
router.HandleFunc("/api/v3/licenses",
am.ViewAccess(ah.listLicensesV3)).
Methods(http.MethodGet)

router.HandleFunc("/api/v3/licenses",
am.AdminAccess(ah.applyLicenseV3)).
Methods(http.MethodPost)

router.HandleFunc("/api/v3/licenses",
am.AdminAccess(ah.refreshLicensesV3)).
Methods(http.MethodPut)

// v4
router.HandleFunc("/api/v4/query_range", am.ViewAccess(ah.queryRangeV4)).Methods(http.MethodPost)

// Gateway
Expand Down
101 changes: 98 additions & 3 deletions ee/query-service/app/api/license.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"go.signoz.io/signoz/ee/query-service/constants"
"go.signoz.io/signoz/ee/query-service/model"
"go.signoz.io/signoz/pkg/http/render"
"go.uber.org/zap"
)

Expand Down Expand Up @@ -59,6 +60,21 @@ type billingDetails struct {
} `json:"data"`
}

type ApplyLicenseRequest struct {
LicenseKey string `json:"key"`
}

type ListLicenseResponse map[string]interface{}

func convertLicenseV3ToListLicenseResponse(licensesV3 []*model.LicenseV3) []ListLicenseResponse {
listLicenses := []ListLicenseResponse{}

for _, license := range licensesV3 {
listLicenses = append(listLicenses, license.Data)
}
return listLicenses
}

func (ah *APIHandler) listLicenses(w http.ResponseWriter, r *http.Request) {
licenses, apiError := ah.LM().GetLicenses(context.Background())
if apiError != nil {
Expand Down Expand Up @@ -88,6 +104,51 @@ func (ah *APIHandler) applyLicense(w http.ResponseWriter, r *http.Request) {
ah.Respond(w, license)
}

func (ah *APIHandler) listLicensesV3(w http.ResponseWriter, r *http.Request) {
licenses, apiError := ah.LM().GetLicensesV3(r.Context())

if apiError != nil {
RespondError(w, apiError, nil)
return
}

ah.Respond(w, convertLicenseV3ToListLicenseResponse(licenses))
}

// this function is called by zeus when inserting licenses in the query-service
func (ah *APIHandler) applyLicenseV3(w http.ResponseWriter, r *http.Request) {
var licenseKey ApplyLicenseRequest

if err := json.NewDecoder(r.Body).Decode(&licenseKey); err != nil {
RespondError(w, model.BadRequest(err), nil)
return
}

if licenseKey.LicenseKey == "" {
RespondError(w, model.BadRequest(fmt.Errorf("license key is required")), nil)
return
}

_, apiError := ah.LM().ActivateV3(r.Context(), licenseKey.LicenseKey)
if apiError != nil {
RespondError(w, apiError, nil)
return
}

render.Success(w, http.StatusAccepted, nil)
}

func (ah *APIHandler) refreshLicensesV3(w http.ResponseWriter, r *http.Request) {

apiError := ah.LM().RefreshLicense(r.Context())
if apiError != nil {
RespondError(w, apiError, nil)
return
}

render.Success(w, http.StatusNoContent, nil)
}

func (ah *APIHandler) checkout(w http.ResponseWriter, r *http.Request) {

type checkoutResponse struct {
Expand Down Expand Up @@ -154,11 +215,45 @@ func (ah *APIHandler) getBilling(w http.ResponseWriter, r *http.Request) {
ah.Respond(w, billingResponse.Data)
}

func convertLicenseV3ToLicenseV2(licenses []*model.LicenseV3) []model.License {
licensesV2 := []model.License{}
for _, l := range licenses {
licenseV2 := model.License{
Key: l.Key,
ActivationId: "",
PlanDetails: "",
FeatureSet: l.Features,
ValidationMessage: "",
IsCurrent: l.IsCurrent,
LicensePlan: model.LicensePlan{
PlanKey: l.PlanName,
ValidFrom: l.ValidFrom,
ValidUntil: l.ValidUntil,
Status: l.Status},
}
licensesV2 = append(licensesV2, licenseV2)
}
return licensesV2
}

func (ah *APIHandler) listLicensesV2(w http.ResponseWriter, r *http.Request) {

licenses, apiError := ah.LM().GetLicenses(context.Background())
if apiError != nil {
RespondError(w, apiError, nil)
var licenses []model.License

if ah.UseLicensesV3 {
licensesV3, err := ah.LM().GetLicensesV3(r.Context())
if err != nil {
RespondError(w, err, nil)
return
}
licenses = convertLicenseV3ToLicenseV2(licensesV3)
} else {
_licenses, apiError := ah.LM().GetLicenses(r.Context())
if apiError != nil {
RespondError(w, apiError, nil)
return
}
licenses = _licenses
}

resp := model.Licenses{
Expand Down
4 changes: 3 additions & 1 deletion ee/query-service/app/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ type ServerOptions struct {
Cluster string
GatewayUrl string
UseLogsNewSchema bool
UseLicensesV3 bool
}

// Server runs HTTP api service
Expand Down Expand Up @@ -133,7 +134,7 @@ func NewServer(serverOptions *ServerOptions) (*Server, error) {
}

// initiate license manager
lm, err := licensepkg.StartManager("sqlite", localDB)
lm, err := licensepkg.StartManager("sqlite", localDB, serverOptions.UseLicensesV3)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -269,6 +270,7 @@ func NewServer(serverOptions *ServerOptions) (*Server, error) {
FluxInterval: fluxInterval,
Gateway: gatewayProxy,
UseLogsNewSchema: serverOptions.UseLogsNewSchema,
UseLicensesV3: serverOptions.UseLicensesV3,
}

apiHandler, err := api.NewAPIHandler(apiOpts)
Expand Down
1 change: 1 addition & 0 deletions ee/query-service/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ var LicenseAPIKey = GetOrDefaultEnv("SIGNOZ_LICENSE_API_KEY", "")
var SaasSegmentKey = GetOrDefaultEnv("SIGNOZ_SAAS_SEGMENT_KEY", "")
var FetchFeatures = GetOrDefaultEnv("FETCH_FEATURES", "false")
var ZeusFeaturesURL = GetOrDefaultEnv("ZEUS_FEATURES_URL", "ZeusFeaturesURL")
var ZeusURL = GetOrDefaultEnv("ZEUS_URL", "ZeusURL")

func GetOrDefaultEnv(key string, fallback string) string {
v := os.Getenv(key)
Expand Down
5 changes: 5 additions & 0 deletions ee/query-service/integrations/signozio/response.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,8 @@ type ActivationResponse struct {
ActivationId string `json:"ActivationId"`
PlanDetails string `json:"PlanDetails"`
}

type ValidateLicenseResponse struct {
Status status `json:"status"`
Data map[string]interface{} `json:"data"`
}
61 changes: 59 additions & 2 deletions ee/query-service/integrations/signozio/signozio.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"fmt"
"io"
"net/http"
"time"

"github.com/pkg/errors"
"go.uber.org/zap"
Expand All @@ -23,12 +24,14 @@ const (
)

type Client struct {
Prefix string
Prefix string
GatewayUrl string
}

func New() *Client {
return &Client{
Prefix: constants.LicenseSignozIo,
Prefix: constants.LicenseSignozIo,
GatewayUrl: constants.ZeusURL,
}
}

Expand Down Expand Up @@ -116,6 +119,60 @@ func ValidateLicense(activationId string) (*ActivationResponse, *model.ApiError)

}

func ValidateLicenseV3(licenseKey string) (*model.LicenseV3, *model.ApiError) {

// Creating an HTTP client with a timeout for better control
client := &http.Client{
Timeout: 10 * time.Second,
}

req, err := http.NewRequest("GET", C.GatewayUrl+"/v2/licenses/me", nil)
if err != nil {
return nil, model.BadRequest(errors.Wrap(err, fmt.Sprintf("failed to create request: %w", err)))
}

// Setting the custom header
req.Header.Set("X-Signoz-Cloud-Api-Key", licenseKey)

response, err := client.Do(req)
if err != nil {
return nil, model.BadRequest(errors.Wrap(err, fmt.Sprintf("failed to make post request: %w", err)))
}

body, err := io.ReadAll(response.Body)
if err != nil {
return nil, model.BadRequest(errors.Wrap(err, fmt.Sprintf("failed to read validation response from %v", C.GatewayUrl)))
}

defer response.Body.Close()

switch response.StatusCode {
case 200:
a := ValidateLicenseResponse{}
err = json.Unmarshal(body, &a)
if err != nil {
return nil, model.BadRequest(errors.Wrap(err, "failed to marshal license validation response"))
}

license, err := model.NewLicenseV3(a.Data)
if err != nil {
return nil, model.BadRequest(errors.Wrap(err, "failed to generate new license v3"))
}

return license, nil
case 400:
return nil, model.BadRequest(errors.Wrap(fmt.Errorf(string(body)),
fmt.Sprintf("bad request error received from %v", C.GatewayUrl)))
case 401:
return nil, model.Unauthorized(errors.Wrap(fmt.Errorf(string(body)),
fmt.Sprintf("unauthorized request error received from %v", C.GatewayUrl)))
default:
return nil, model.InternalError(errors.Wrap(fmt.Errorf(string(body)),
fmt.Sprintf("internal request error received from %v", C.GatewayUrl)))
}

}

func NewPostRequestWithCtx(ctx context.Context, url string, contentType string, body io.Reader) (*http.Request, error) {
req, err := http.NewRequestWithContext(ctx, POST, url, body)
if err != nil {
Expand Down
Loading

0 comments on commit 73f198c

Please sign in to comment.