Skip to content

Commit

Permalink
feat(license): implemented get status
Browse files Browse the repository at this point in the history
Signed-off-by: sahil <sahilraja242@gmail.com>
  • Loading branch information
rajaSahil committed Apr 11, 2023
1 parent bd01757 commit b467c68
Show file tree
Hide file tree
Showing 8 changed files with 452 additions and 95 deletions.
2 changes: 2 additions & 0 deletions src/cluster/k8sClientHandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,7 @@ func CreateLicenseSecret(k8sClient *kubernetes.Clientset, key string, userId str
}

if secret != nil {
log.Info().Msgf("secrets already exists for discovery-engine license for user-id: %s", userId)
return secret, nil
}
t := true
Expand All @@ -567,6 +568,7 @@ func CreateLicenseSecret(k8sClient *kubernetes.Clientset, key string, userId str
log.Error().Msgf("error while creating secret for license key, error: %s", err.Error())
return nil, err
}
log.Info().Msgf("secret created successfully for discovery-engine")
return secret, nil
}

Expand Down
105 changes: 87 additions & 18 deletions src/license/license.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,16 @@ import (
"github.com/rs/zerolog/log"
"k8s.io/client-go/kubernetes"
"strings"
"time"
)

// For testing purpose
var publicKey = "-----BEGIN PUBLIC KEY-----\nMIGeMA0GCSqGSIb3DQEBAQUAA4GMADCBiAKBgHUc95xoPHqsuC3zLfCSHHJ9F/Gx\nlJdyBkns1wDYCLY8yX1vvZndfDP9br3dbFKOaYOYmF9e0gKcDpGItdBQe+TVX9ol\nM3S23yD/xHNKw+f88KjI0dPnj3IRgqajd5eBMhNNugRFzRKWBBLCflukm7CfjzUP\nX1jQ/NCkoTwjScpJAgMBAAE=\n-----END PUBLIC KEY-----"

type ConfigLicense struct {
type LicenseConfig struct {
k8sClient *kubernetes.Clientset
Tkn *Token
Lcs *License
}

type License struct {
Expand All @@ -24,22 +27,25 @@ type License struct {
PlatformUUID string
}

var cfg *ConfigLicense
var Tkn *Token
var LCfg *LicenseConfig

func InitializeConfig(k8sClient *kubernetes.Clientset) {
cfg = &ConfigLicense{k8sClient: k8sClient}
LCfg = &LicenseConfig{
k8sClient: k8sClient,
Tkn: nil,
Lcs: nil,
}
}

func CheckLicenseSecret() error {
log.Info().Msgf("fetching license secrets to validate discovery-engine licensing")
secret, err := cluster.GetSecrets(cfg.k8sClient, "app=discovery-engine")
secret, err := cluster.GetSecrets(LCfg.k8sClient, "app=discovery-engine")
if err != nil {
log.Error().Msgf("error while fetching secrets for discovery engine licensing, error: %s", err.Error())
return err
}
if secret == nil {
return nil
return errors.New("license secret doesn't exist for discovery-engine")
}

l := &License{
Expand All @@ -52,14 +58,28 @@ func CheckLicenseSecret() error {
log.Error().Msgf("error while validating license retrieved through secrets, error: %s", err.Error())
return err
}
log.Info().Msgf("license validation successfully for user-id: %s with key: %s", l.UserId, l.Key)
// Initialize to global config only after validation is done.
LCfg.Lcs = l
log.Info().Msgf("license validation successfully for user-id: %s with key: %s", LCfg.Lcs.UserId, LCfg.Lcs.Key)
return nil
}

func (l *License) ValidateLicense() error {
var err error

l.PlatformUUID, err = cfg.getKubeSystemUUID()
if checkExistingLicense() {
if !LCfg.Tkn.checkExpiration() {
err = fmt.Errorf("valid license already exists with user-id: %s, key: %s and platform uuid: %s", LCfg.Lcs.UserId, LCfg.Lcs.Key, LCfg.Lcs.PlatformUUID)
log.Error().Msgf("%s", err)
return err
}
err = removeSecretsConfig()
if err != nil {
return err
}
}

l.PlatformUUID, err = LCfg.getKubeSystemUUID()
if err != nil {
log.Error().Msgf("error while fetching uuid of kube-system namespace, error: %s", err.Error())
return err
Expand All @@ -71,25 +91,27 @@ func (l *License) ValidateLicense() error {
return err
}

Tkn, err = validateToken(decryptedKey, l.UserId)
LCfg.Tkn, err = validateToken(decryptedKey, l.UserId)
if err != nil {
log.Error().Msgf("error while validating jwt token")
return err
}

log.Info().Msgf("license validation successfully for user: %s with license key: %s", l.UserId, l.Key)

secret, err := cluster.CreateLicenseSecret(cfg.k8sClient, l.Key, l.UserId)
secret, err := cluster.CreateLicenseSecret(LCfg.k8sClient, l.Key, l.UserId)
if err != nil {
log.Error().Msgf("error while creating secret for discovery engine license, error: %s", err.Error())
return err
}
// Initialize to global config only after validation is done.
LCfg.Lcs = l

log.Info().Msgf("secret created for discovery engine license with name: %s and uuid: %s", secret.GetName(), secret.GetUID())
log.Info().Msgf("secret for discovery engine license with name: %s and uuid: %s", secret.GetName(), secret.GetUID())
return nil
}

func (cfg *ConfigLicense) getKubeSystemUUID() (string, error) {
func (cfg *LicenseConfig) getKubeSystemUUID() (string, error) {
uuid, err := cluster.GetKubeSystemUUID(cfg.k8sClient)
if err != nil {
log.Error().Msgf("error while fetching uuid of kube-system namespace, error: %s", err.Error())
Expand All @@ -110,12 +132,17 @@ func decryptKey(key string, platformUUID string) (string, error) {

type Token struct {
jwt *jwt.Token
claims *jwt.MapClaims
claims *Claims
}

type Claims struct {
Features []string `json:"features"`
*jwt.RegisteredClaims
}

func validateToken(decryptedKey string, userId string) (*Token, error) {

claims := jwt.MapClaims{}
claims := &Claims{}

key, err := jwt.ParseRSAPublicKeyFromPEM([]byte(publicKey))
if err != nil {
Expand All @@ -135,7 +162,7 @@ func validateToken(decryptedKey string, userId string) (*Token, error) {

Tkn := &Token{
jwt: jwtToken,
claims: &claims,
claims: claims,
}

err = Tkn.validateClaims(userId)
Expand Down Expand Up @@ -170,10 +197,52 @@ func (t *Token) validateUserId(userId string) error {

}

func (t *Token) getFeatures() []string {
return nil
func (t *Token) getFeatures() ([]string, error) {
features := t.claims.Features
return features, nil
}

func WatchFeatures(features []string, expTime string) error {
func (cfg *LicenseConfig) WatchFeatures() bool {

for {
//time.Sleep(500 * time.Millisecond)
if cfg.Lcs == nil || cfg.Tkn == nil {
continue
}

if !cfg.Tkn.checkExpiration() {
log.Info().Msgf("valid license exists for discovery-engine")
return true
}
}

}

func (t *Token) checkExpiration() bool {
exp, err := LCfg.Tkn.claims.RegisteredClaims.GetExpirationTime()
if err != nil {
log.Error().Msgf("error while getting expiration time for license, error: %s", err.Error())
return true
}
if exp.Before(time.Now()) {
return true
}
return false
}

func checkExistingLicense() bool {
if LCfg.Lcs != nil && LCfg.Tkn != nil {
return true
}
return false
}

func removeSecretsConfig() error {
err := cluster.DeleteSecrets(LCfg.k8sClient, "app=discovery-engine")
if err != nil {
return err
}
LCfg.Lcs = nil
LCfg.Tkn = nil
return nil
}
51 changes: 47 additions & 4 deletions src/license/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,72 @@ package license

import (
"context"
"errors"
ipb "github.com/accuknox/auto-policy-discovery/src/protobuf/v1/license"
"github.com/rs/zerolog/log"
"time"
)

type Server struct {
ipb.UnimplementedLicenseServer
}

func (ls *Server) InstallLicense(ctx context.Context, lr *ipb.LicenseRequest) (*ipb.LicenseResponse, error) {
func (ls *Server) InstallLicense(ctx context.Context, lr *ipb.LicenseInstallRequest) (*ipb.LicenseInstallResponse, error) {
log.Info().Msgf("request received to install license for user-id: %s", lr.UserId)
l := License{
l := &License{
UserId: lr.UserId,
Key: lr.Key,
}
err := l.ValidateLicense()
if err != nil {
return &ipb.LicenseResponse{
return &ipb.LicenseInstallResponse{
Res: -1,
Message: "error while validating license",
}, err
}
return &ipb.LicenseResponse{
return &ipb.LicenseInstallResponse{
Res: 0,
Message: "license installed successfully",
}, nil
}

func (ls *Server) GetLicenseStatus(ctx context.Context, lr *ipb.LicenseStatusRequest) (*ipb.LicenseStatusResponse, error) {
log.Info().Msgf("request received to fetch the status of license")
if LCfg.Lcs == nil || LCfg.Tkn == nil {
return nil, errors.New("error while fetching status, no license secrets exists")
}

iAt, err := LCfg.Tkn.claims.RegisteredClaims.GetIssuedAt()
if err != nil {
log.Error().Msgf("error while getting issued time for license, error: %s", err.Error())
return nil, err
}

exp, err := LCfg.Tkn.claims.RegisteredClaims.GetExpirationTime()
if err != nil {
log.Error().Msgf("error while getting expiration time for license, error: %s", err.Error())
return nil, err
}

features, err := LCfg.Tkn.getFeatures()
if err != nil || features == nil {
log.Error().Msgf("error while getting features that are supported in license, error: %s", err.Error())
return nil, err

}

var status string
if exp.After(time.Now()) {
status = "Active"
}

return &ipb.LicenseStatusResponse{
Key: LCfg.Lcs.Key,
UserId: LCfg.Lcs.UserId,
PlatformUUID: LCfg.Lcs.PlatformUUID,
IssuedAt: iAt.String(),
Expiration: exp.String(),
Features: features,
Status: status,
}, nil
}
35 changes: 23 additions & 12 deletions src/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,18 @@ package main
import (
"github.com/accuknox/auto-policy-discovery/src/cluster"
"github.com/accuknox/auto-policy-discovery/src/config"
"github.com/accuknox/auto-policy-discovery/src/libs"
"github.com/accuknox/auto-policy-discovery/src/license"
logger "github.com/accuknox/auto-policy-discovery/src/logging"
grpcserver "github.com/accuknox/auto-policy-discovery/src/server"
"github.com/spf13/viper"
"google.golang.org/grpc"
"math/rand"
"net"
"os"
"time"

libs "github.com/accuknox/auto-policy-discovery/src/libs"
logger "github.com/accuknox/auto-policy-discovery/src/logging"
grpcserver "github.com/accuknox/auto-policy-discovery/src/server"

"github.com/rs/zerolog"
"github.com/spf13/viper"
)

var cfg cluster.Config
Expand Down Expand Up @@ -55,12 +55,26 @@ func init() {

func main() {

lis, server := CreateListenerAndGrpcServer()
// add license server
server = grpcserver.AddLicenseServer(server)

// check for license secret, if exist then validate
err := license.CheckLicenseSecret()

if err != nil {
log.Error().Msgf("error while validating license, error: %s", err.Error())
log.Error().Msgf("error while validating license secrets for discovery engine, error: %s", err.Error())
go serve(lis, server)
_ = license.LCfg.WatchFeatures()
os.Exit(1)
}

server = grpcserver.AddServers(server)
serve(lis, server)

}

func CreateListenerAndGrpcServer() (net.Listener, *grpc.Server) {
// create server
lis, err := net.Listen("tcp", ":"+grpcserver.PortNumber)
if err != nil {
Expand All @@ -70,15 +84,12 @@ func main() {

// starts grpc server
server := grpcserver.StartGrpcServer()
// add license server
server = grpcserver.AddLicenseServer(server)

server = grpcserver.AddServers(server)
return lis, server
}

// start autopolicy service
log.Info().Msgf("gRPC server on %s port started", grpcserver.PortNumber)
func serve(lis net.Listener, server *grpc.Server) {
if err := server.Serve(lis); err != nil {
log.Error().Msgf("Failed to serve: %v", err)
}

}

0 comments on commit b467c68

Please sign in to comment.