mirror of
https://github.com/paralus/paralus.git
synced 2026-08-21 04:16:20 +00:00
* updated main.go script to reinitialize the permissions when the are existing or there is any update Signed-off-by: swastik959 <Sswastik959@gmail.com> * added few corrections and added better error logging Signed-off-by: swastik959 <Sswastik959@gmail.com> * added the checks for checking the existence of different components Signed-off-by: swastik959 <Sswastik959@gmail.com> * started adding the Upsert function Signed-off-by: swastik959 <Sswastik959@gmail.com> * added upsert to role.go Signed-off-by: swastik959 <Sswastik959@gmail.com> * added tests and auditing Signed-off-by: swastik959 <Sswastik959@gmail.com> * updated packages Signed-off-by: swastik959 <Sswastik959@gmail.com> * updated go version Signed-off-by: swastik959 <Sswastik959@gmail.com> * added minor changes Signed-off-by: swastik959 <Sswastik959@gmail.com> * added correction to role_test.go Signed-off-by: swastik959 <Sswastik959@gmail.com> * corrected test cases Signed-off-by: swastik959 <Sswastik959@gmail.com> --------- Signed-off-by: swastik959 <Sswastik959@gmail.com>
391 lines
12 KiB
Go
391 lines
12 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/paralus/paralus/internal/dao"
|
|
"github.com/paralus/paralus/internal/models"
|
|
commonv3 "github.com/paralus/paralus/proto/types/commonpb/v3"
|
|
v3 "github.com/paralus/paralus/proto/types/commonpb/v3"
|
|
systemv3 "github.com/paralus/paralus/proto/types/systempb/v3"
|
|
bun "github.com/uptrace/bun"
|
|
"go.uber.org/zap"
|
|
"google.golang.org/protobuf/types/known/timestamppb"
|
|
)
|
|
|
|
// PartnerService is the interface for partner operations
|
|
type PartnerService interface {
|
|
// create partner
|
|
Create(ctx context.Context, partner *systemv3.Partner) (*systemv3.Partner, error)
|
|
// get partner by id
|
|
GetByID(ctx context.Context, partnerId string) (*systemv3.Partner, error)
|
|
// get partner by id
|
|
GetByName(ctx context.Context, name string) (*systemv3.Partner, error)
|
|
// create or update partner
|
|
Update(ctx context.Context, partner *systemv3.Partner) (*systemv3.Partner, error)
|
|
// delete partner
|
|
Delete(ctx context.Context, partner *systemv3.Partner) (*systemv3.Partner, error)
|
|
// list partner
|
|
GetOnlyPartner(ctx context.Context) (*systemv3.Partner, error)
|
|
// Upsert partner
|
|
Upsert(ctx context.Context, partner *systemv3.Partner) (*systemv3.Partner, error)
|
|
}
|
|
|
|
// partnerService implements PartnerService
|
|
type partnerService struct {
|
|
db *bun.DB
|
|
al *zap.Logger
|
|
}
|
|
|
|
// NewPartnerService return new partner service
|
|
func NewPartnerService(db *bun.DB, al *zap.Logger) PartnerService {
|
|
return &partnerService{db, al}
|
|
}
|
|
|
|
func (s *partnerService) Create(ctx context.Context, partner *systemv3.Partner) (*systemv3.Partner, error) {
|
|
|
|
var sb []byte
|
|
if partner.GetSpec().GetSettings() != nil {
|
|
sb = json.RawMessage(partner.GetSpec().GetSettings().String())
|
|
}
|
|
//convert v3 spec to internal models
|
|
part := models.Partner{
|
|
Name: partner.GetMetadata().GetName(),
|
|
Description: partner.GetMetadata().GetDescription(),
|
|
Trash: false,
|
|
Settings: sb,
|
|
Host: partner.GetSpec().GetHost(),
|
|
Domain: partner.GetSpec().GetDomain(),
|
|
TosLink: partner.GetSpec().GetTosLink(),
|
|
LogoLink: partner.GetSpec().GetLogoLink(),
|
|
NotificationEmail: partner.GetSpec().GetNotificationEmail(),
|
|
HelpdeskEmail: partner.GetSpec().GetHelpdeskEmail(),
|
|
ProductName: partner.GetSpec().GetProductName(),
|
|
SupportTeamName: partner.GetSpec().GetSupportTeamName(),
|
|
OpsHost: partner.GetSpec().GetOpsHost(),
|
|
FavIconLink: partner.GetSpec().GetFavIconLink(),
|
|
IsTOTPEnabled: partner.GetSpec().GetIsTOTPEnabled(),
|
|
IsSyntheticPartnerEnabled: false,
|
|
CreatedAt: time.Now(),
|
|
ModifiedAt: time.Now(),
|
|
}
|
|
entity, err := dao.Create(ctx, s.db, &part)
|
|
if err != nil {
|
|
return &systemv3.Partner{}, err
|
|
}
|
|
|
|
if createdPartner, ok := entity.(*models.Partner); ok {
|
|
//update v3 spec
|
|
partner.Metadata.Id = createdPartner.ID.String()
|
|
partner.Metadata.ModifiedAt = timestamppb.New(createdPartner.ModifiedAt)
|
|
|
|
CreatePartnerAuditEvent(ctx, s.al, AuditActionCreate, partner.GetMetadata().GetName(), createdPartner.ID)
|
|
}
|
|
|
|
return partner, nil
|
|
|
|
}
|
|
|
|
func (s *partnerService) GetByID(ctx context.Context, id string) (*systemv3.Partner, error) {
|
|
|
|
partner := &systemv3.Partner{
|
|
ApiVersion: apiVersion,
|
|
Kind: partnerKind,
|
|
Metadata: &v3.Metadata{
|
|
Id: id,
|
|
},
|
|
}
|
|
|
|
uid, err := uuid.Parse(id)
|
|
if err != nil {
|
|
return &systemv3.Partner{}, err
|
|
}
|
|
entity, err := dao.GetByID(ctx, s.db, uid, &models.Partner{})
|
|
if err != nil {
|
|
return &systemv3.Partner{}, err
|
|
}
|
|
|
|
if part, ok := entity.(*models.Partner); ok {
|
|
|
|
partner.Metadata = &v3.Metadata{
|
|
Name: part.Name,
|
|
Description: part.Description,
|
|
ModifiedAt: timestamppb.New(part.ModifiedAt),
|
|
}
|
|
partner.Spec = &systemv3.PartnerSpec{
|
|
Host: part.Host,
|
|
Domain: part.Domain,
|
|
TosLink: part.TosLink,
|
|
LogoLink: part.LogoLink,
|
|
NotificationEmail: part.NotificationEmail,
|
|
HelpdeskEmail: part.HelpdeskEmail,
|
|
ProductName: part.ProductName,
|
|
SupportTeamName: part.SupportTeamName,
|
|
OpsHost: part.OpsHost,
|
|
FavIconLink: part.FavIconLink,
|
|
IsTOTPEnabled: part.IsTOTPEnabled,
|
|
Settings: nil, //TODO
|
|
}
|
|
|
|
return partner, nil
|
|
|
|
} else {
|
|
partner := &systemv3.Partner{
|
|
ApiVersion: apiVersion,
|
|
Kind: partnerKind,
|
|
Metadata: &v3.Metadata{
|
|
Id: id,
|
|
},
|
|
Status: &v3.Status{
|
|
ConditionStatus: v3.ConditionStatus_StatusNotSet,
|
|
Reason: "Unable to fetch partner information",
|
|
LastUpdated: timestamppb.Now(),
|
|
},
|
|
}
|
|
|
|
return partner, nil
|
|
}
|
|
|
|
}
|
|
|
|
func (s *partnerService) GetByName(ctx context.Context, name string) (*systemv3.Partner, error) {
|
|
|
|
partner := &systemv3.Partner{
|
|
ApiVersion: apiVersion,
|
|
Kind: partnerKind,
|
|
Metadata: &v3.Metadata{
|
|
Name: name,
|
|
},
|
|
}
|
|
|
|
entity, err := dao.GetByName(ctx, s.db, name, &models.Partner{})
|
|
if err != nil {
|
|
return &systemv3.Partner{}, err
|
|
}
|
|
|
|
if part, ok := entity.(*models.Partner); ok {
|
|
|
|
partner.Metadata = &v3.Metadata{
|
|
Name: part.Name,
|
|
Id: part.ID.String(),
|
|
Description: part.Description,
|
|
ModifiedAt: timestamppb.New(part.ModifiedAt),
|
|
}
|
|
partner.Spec = &systemv3.PartnerSpec{
|
|
Host: part.Host,
|
|
Domain: part.Domain,
|
|
TosLink: part.TosLink,
|
|
LogoLink: part.LogoLink,
|
|
NotificationEmail: part.NotificationEmail,
|
|
HelpdeskEmail: part.HelpdeskEmail,
|
|
ProductName: part.ProductName,
|
|
SupportTeamName: part.SupportTeamName,
|
|
OpsHost: part.OpsHost,
|
|
FavIconLink: part.FavIconLink,
|
|
IsTOTPEnabled: part.IsTOTPEnabled,
|
|
Settings: nil, //TODO
|
|
}
|
|
|
|
return partner, nil
|
|
} else {
|
|
partner := &systemv3.Partner{
|
|
ApiVersion: apiVersion,
|
|
Kind: partnerKind,
|
|
Metadata: &v3.Metadata{
|
|
Name: name,
|
|
},
|
|
Status: &v3.Status{
|
|
ConditionType: "Describe",
|
|
ConditionStatus: v3.ConditionStatus_StatusNotSet,
|
|
Reason: "Unable to fetch partner information",
|
|
LastUpdated: timestamppb.Now(),
|
|
},
|
|
}
|
|
|
|
return partner, nil
|
|
}
|
|
|
|
}
|
|
|
|
func (s *partnerService) Update(ctx context.Context, partner *systemv3.Partner) (*systemv3.Partner, error) {
|
|
|
|
entity, err := dao.GetByName(ctx, s.db, partner.Metadata.Name, &models.Partner{})
|
|
if err != nil {
|
|
return &systemv3.Partner{}, err
|
|
}
|
|
|
|
var sb []byte
|
|
if partner.GetSpec().GetSettings() != nil {
|
|
sb = json.RawMessage(partner.GetSpec().GetSettings().String())
|
|
}
|
|
|
|
if part, ok := entity.(*models.Partner); ok {
|
|
//update partner details
|
|
part.Name = partner.GetMetadata().Name
|
|
part.Description = partner.GetMetadata().GetDescription()
|
|
part.Settings = sb
|
|
part.Host = partner.GetSpec().GetHost()
|
|
part.Domain = partner.GetSpec().GetDomain()
|
|
part.TosLink = partner.GetSpec().GetTosLink()
|
|
part.LogoLink = partner.GetSpec().GetLogoLink()
|
|
part.NotificationEmail = partner.GetSpec().GetNotificationEmail()
|
|
part.HelpdeskEmail = partner.GetSpec().GetHelpdeskEmail()
|
|
part.ProductName = partner.GetSpec().GetProductName()
|
|
part.SupportTeamName = partner.GetSpec().GetSupportTeamName()
|
|
part.OpsHost = partner.GetSpec().GetOpsHost()
|
|
part.FavIconLink = partner.GetSpec().GetFavIconLink()
|
|
part.IsTOTPEnabled = partner.GetSpec().GetIsTOTPEnabled()
|
|
part.ModifiedAt = time.Now()
|
|
|
|
//Update the partner details
|
|
_, err = dao.Update(ctx, s.db, part.ID, part)
|
|
if err != nil {
|
|
return &systemv3.Partner{}, err
|
|
}
|
|
|
|
//update metadata and status
|
|
partner.Metadata.ModifiedAt = timestamppb.New(part.ModifiedAt)
|
|
|
|
CreatePartnerAuditEvent(ctx, s.al, AuditActionUpdate, partner.GetMetadata().GetName(), part.ID)
|
|
|
|
}
|
|
|
|
return partner, nil
|
|
}
|
|
|
|
func (s *partnerService) Delete(ctx context.Context, partner *systemv3.Partner) (*systemv3.Partner, error) {
|
|
entity, err := dao.GetByName(ctx, s.db, partner.Metadata.Name, &models.Partner{})
|
|
if err != nil {
|
|
return &systemv3.Partner{}, err
|
|
}
|
|
|
|
if part, ok := entity.(*models.Partner); ok {
|
|
err := dao.Delete(ctx, s.db, part.ID, part)
|
|
if err != nil {
|
|
return &systemv3.Partner{}, err
|
|
}
|
|
|
|
CreatePartnerAuditEvent(ctx, s.al, AuditActionDelete, partner.GetMetadata().GetName(), part.ID)
|
|
return partner, nil
|
|
}
|
|
|
|
return partner, nil
|
|
|
|
}
|
|
|
|
func (s *partnerService) GetOnlyPartner(ctx context.Context) (partner *systemv3.Partner, err error) {
|
|
var partners []models.Partner
|
|
entities, err := dao.ListAll(ctx, s.db, &partners)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if pts, ok := entities.(*[]models.Partner); ok {
|
|
for _, part := range *pts {
|
|
partner = &systemv3.Partner{
|
|
Metadata: &v3.Metadata{
|
|
Name: part.Name,
|
|
Id: part.ID.String(),
|
|
Description: part.Description,
|
|
ModifiedAt: timestamppb.New(part.ModifiedAt),
|
|
},
|
|
Spec: &systemv3.PartnerSpec{
|
|
Host: part.Host,
|
|
Domain: part.Domain,
|
|
TosLink: part.TosLink,
|
|
LogoLink: part.LogoLink,
|
|
NotificationEmail: part.NotificationEmail,
|
|
HelpdeskEmail: part.HelpdeskEmail,
|
|
ProductName: part.ProductName,
|
|
SupportTeamName: part.SupportTeamName,
|
|
OpsHost: part.OpsHost,
|
|
FavIconLink: part.FavIconLink,
|
|
IsTOTPEnabled: part.IsTOTPEnabled,
|
|
Settings: nil,
|
|
},
|
|
Status: &v3.Status{
|
|
ConditionType: "Describe",
|
|
ConditionStatus: v3.ConditionStatus_StatusOK,
|
|
LastUpdated: timestamppb.New(part.ModifiedAt),
|
|
},
|
|
}
|
|
|
|
return partner, nil
|
|
}
|
|
}
|
|
return partner, err
|
|
}
|
|
|
|
func (s *partnerService) Upsert(ctx context.Context, partner *systemv3.Partner) (*systemv3.Partner, error) {
|
|
// Convert settings to JSON if needed
|
|
sb, err := json.Marshal(map[string]interface{}{})
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to marshal settings: %v", err)
|
|
}
|
|
|
|
p := models.Partner{
|
|
Name: partner.GetMetadata().GetName(),
|
|
Description: partner.GetMetadata().GetDescription(),
|
|
Trash: false,
|
|
Settings: sb,
|
|
Host: partner.GetSpec().GetHost(),
|
|
Domain: partner.GetSpec().GetDomain(),
|
|
TosLink: partner.GetSpec().GetTosLink(),
|
|
LogoLink: partner.GetSpec().GetLogoLink(),
|
|
NotificationEmail: partner.GetSpec().GetNotificationEmail(),
|
|
HelpdeskEmail: partner.GetSpec().GetHelpdeskEmail(),
|
|
ProductName: partner.GetSpec().GetProductName(),
|
|
SupportTeamName: partner.GetSpec().GetSupportTeamName(),
|
|
OpsHost: partner.GetSpec().GetOpsHost(),
|
|
FavIconLink: partner.GetSpec().GetFavIconLink(),
|
|
IsTOTPEnabled: partner.GetSpec().GetIsTOTPEnabled(),
|
|
IsSyntheticPartnerEnabled: false,
|
|
CreatedAt: time.Now(),
|
|
ModifiedAt: time.Now(),
|
|
}
|
|
|
|
_, err = s.db.NewInsert().
|
|
Model(&p).
|
|
On("CONFLICT (name) WHERE trash IS FALSE DO UPDATE").
|
|
Set("description = EXCLUDED.description").
|
|
Set("host = EXCLUDED.host").
|
|
Set("domain = EXCLUDED.domain").
|
|
Set("tos_link = EXCLUDED.tos_link").
|
|
Set("logo_link = EXCLUDED.logo_link").
|
|
Set("notification_email = EXCLUDED.notification_email").
|
|
Set("support_team_name = EXCLUDED.support_team_name").
|
|
Set("ops_host = EXCLUDED.ops_host").
|
|
Set("fav_icon_link = EXCLUDED.fav_icon_link").
|
|
Set("is_totp_enabled = EXCLUDED.is_totp_enabled").
|
|
Set("modified_at = EXCLUDED.modified_at").
|
|
Exec(ctx)
|
|
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to upsert partner: %v", err)
|
|
}
|
|
CreatePartnerAuditEvent(ctx, s.al, AuditActionUpsert, partner.GetMetadata().GetName(), p.ID)
|
|
|
|
return &systemv3.Partner{
|
|
Metadata: &commonv3.Metadata{
|
|
Name: p.Name,
|
|
Description: p.Description,
|
|
},
|
|
Spec: &systemv3.PartnerSpec{
|
|
Host: p.Host,
|
|
Domain: p.Domain,
|
|
TosLink: p.TosLink,
|
|
LogoLink: p.LogoLink,
|
|
NotificationEmail: p.NotificationEmail,
|
|
HelpdeskEmail: p.HelpdeskEmail,
|
|
ProductName: p.ProductName,
|
|
SupportTeamName: p.SupportTeamName,
|
|
OpsHost: p.OpsHost,
|
|
FavIconLink: p.FavIconLink,
|
|
IsTOTPEnabled: p.IsTOTPEnabled,
|
|
},
|
|
}, nil
|
|
}
|