package services import ( "context" "database/sql" "encoding/json" sqlerr "edge-infra.dev/pkg/edge/api/apierror/sql" "edge-infra.dev/pkg/edge/api/graph/model" sqlquery "edge-infra.dev/pkg/edge/api/sql" "edge-infra.dev/pkg/edge/api/utils" chariotClientApi "edge-infra.dev/pkg/edge/chariot/client" ) type CapabilityService interface { // only used by edge platform components / infra CreateCapability(ctx context.Context, capability model.CapabilityInput) (*model.Capability, error) UpdateCapability(ctx context.Context, capability *model.CapabilityUpdateInput) error // used by users AddCapability(ctx context.Context, capMapping *model.CapabilityBannerMappingInput) error RemoveCapability(ctx context.Context, capMapping *model.CapabilityBannerMappingInput) error ListCapabilities(ctx context.Context) ([]*model.Capability, error) // todo switch to return list of capabilities ListCapabilitiesByBanner(ctx context.Context, bannerID *string) ([]*model.Capability, error) } type capabilityService struct { SQLDB *sql.DB BannerService BannerService ChariotService ChariotService ForemanID string } func (s *capabilityService) CreateCapability(ctx context.Context, capability model.CapabilityInput) (*model.Capability, error) { if _, err := s.SQLDB.ExecContext(ctx, sqlquery.CapabilityInsertQuery, capability.Name, capability.Description); err != nil { return nil, err } var capa model.Capability row := s.SQLDB.QueryRowContext(ctx, sqlquery.CapabilitytGetByNameQuery, capability.Name) if err := row.Scan(&capa.UUID, &capa.Name, &capa.Description); err != nil { return nil, err } return &capa, nil } func (s *capabilityService) UpdateCapability(ctx context.Context, capability *model.CapabilityUpdateInput) error { _, err := s.SQLDB.ExecContext(ctx, sqlquery.CapabilityUpdateQuery, capability.Name, capability.Description) if err != nil { return err } return nil } // TODO return capability to get uuid func (s *capabilityService) AddCapability(ctx context.Context, mapping *model.CapabilityBannerMappingInput) error { // add sql entry for mapping if _, err := s.SQLDB.ExecContext(ctx, sqlquery.AddCapabilityMappyingQuery, mapping.Capabilityid, mapping.BannerEdgeID); err != nil { return err } // update banner cr // should probably do this from a common place so that other updates don't accidentally remove the capabilities banner, err := s.BannerService.GetBannerCRByID(ctx, mapping.BannerEdgeID) if err != nil { return err } path, err := s.BannerService.GetBannerInfraBucketPath(ctx) if err != nil { return err } // todo - code taken from s.BannerService.CreateBannerCr, need to do some refactoring bannerRequestByte, errs := json.Marshal(banner) if errs != nil { return errs } bannerRequestBase64 := utils.ToBase64(bannerRequestByte) msg := chariotClientApi. NewChariotMessage(). SetOperation(chariotClientApi.Create). SetOwner(ComponentOwner). SetBanner(s.ForemanID). SetCluster(path). AddObject(bannerRequestBase64) attrs := make(map[string]string) return s.ChariotService.InvokeChariotPubsub(ctx, msg, attrs) } func (s *capabilityService) RemoveCapability(ctx context.Context, mapping *model.CapabilityBannerMappingInput) error { if _, err := s.SQLDB.ExecContext(ctx, sqlquery.RemoveCapabilityMappingQuery, mapping.Capabilityid, mapping.BannerEdgeID); err != nil { return err } return nil } func (s *capabilityService) ListCapabilities(ctx context.Context) ([]*model.Capability, error) { rows, err := s.SQLDB.QueryContext(ctx, sqlquery.ListCapabilitiesQuery) if err != nil { return nil, err } capabilities := []*model.Capability{} defer rows.Close() for rows.Next() { var capability model.Capability if err = rows.Scan(&capability.UUID, &capability.Name, &capability.Description); err != nil { return nil, err } capabilities = append(capabilities, &capability) } if err := rows.Err(); err != nil { return nil, sqlerr.Wrap(err) } return capabilities, nil } func (s *capabilityService) ListCapabilitiesByBanner(ctx context.Context, bannerID *string) ([]*model.Capability, error) { rows, err := s.SQLDB.QueryContext(ctx, sqlquery.ListCapabilitiesByBannerQuery, bannerID) if err != nil { return nil, err } capabilities := []*model.Capability{} defer rows.Close() for rows.Next() { var capability model.Capability if err = rows.Scan(&capability.UUID, &capability.Name, &capability.Description); err != nil { return nil, err } capabilities = append(capabilities, &capability) } if err := rows.Err(); err != nil { return nil, sqlerr.Wrap(err) } return capabilities, nil } func NewCapabilityService(sqlDB *sql.DB, bannerService BannerService, chariotService ChariotService, foremanID string) CapabilityService { return &capabilityService{ SQLDB: sqlDB, BannerService: bannerService, ChariotService: chariotService, ForemanID: foremanID, } }