Skip to content

Commit

Permalink
✨ Launch Discovery task when Apps are created/updated (#671)
Browse files Browse the repository at this point in the history
Signed-off-by: Sam Lucidi <slucidi@redhat.com>
  • Loading branch information
mansam authored Jun 21, 2024
1 parent c355d3d commit c9ff4b8
Show file tree
Hide file tree
Showing 8 changed files with 182 additions and 20 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ jobs:
make vet
DISCONNECTED=1 make run &
sleep 15 # probably a dirty solution
HUB_BASE_URL=http://localhost:8080 make test-api
HUB_BASE_URL=http://localhost:8080 make test-api # Intentionaly run 2x to catch data left in Hub DB.
DISCONNECTED=1 HUB_BASE_URL=http://localhost:8080 make test-api
DISCONNECTED=1 HUB_BASE_URL=http://localhost:8080 make test-api # Intentionaly run 2x to catch data left in Hub DB.
test-e2e:
runs-on: ubuntu-latest
Expand Down
38 changes: 38 additions & 0 deletions api/application.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package api

import (
"encoding/json"
"fmt"
"net/http"
"sort"
"strings"
Expand All @@ -10,6 +11,7 @@ import (
"github.com/konveyor/tackle2-hub/assessment"
"github.com/konveyor/tackle2-hub/metrics"
"github.com/konveyor/tackle2-hub/model"
tasking "github.com/konveyor/tackle2-hub/task"
"gorm.io/gorm/clause"
)

Expand Down Expand Up @@ -247,6 +249,12 @@ func (h ApplicationHandler) Create(ctx *gin.Context) {
_ = ctx.Error(err)
return
}

err = h.discover(ctx, m)
if err != nil {
_ = ctx.Error(err)
return
}
h.Respond(ctx, http.StatusCreated, r)
}

Expand Down Expand Up @@ -372,6 +380,11 @@ func (h ApplicationHandler) Update(ctx *gin.Context) {
}
}

err = h.discover(ctx, m)
if err != nil {
_ = ctx.Error(err)
return
}
h.Status(ctx, http.StatusNoContent)
}

Expand Down Expand Up @@ -1061,6 +1074,31 @@ func (h ApplicationHandler) AssessmentCreate(ctx *gin.Context) {
h.Respond(ctx, http.StatusCreated, r)
}

// discover an application's language and frameworks by launching discovery tasks.
func (h ApplicationHandler) discover(ctx *gin.Context, application *model.Application) (err error) {
rtx := WithContext(ctx)
db := h.DB(ctx)
for _, kind := range Settings.Hub.Discovery.Tasks {
t := Task{}
t.Kind = kind
t.Name = fmt.Sprintf("%s-%s", application.Name, kind)
ref := Ref{ID: application.ID}
t.Application = &ref
t.State = tasking.Ready
taskHandler := TaskHandler{}
err = taskHandler.FindRefs(rtx.Client, &t)
if err != nil {
return
}
task := tasking.Task{Task: t.Model()}
err = rtx.TaskManager.Create(db, &task)
if err != nil {
return
}
}
return
}

// Application REST resource.
type Application struct {
Resource `yaml:",inline"`
Expand Down
14 changes: 12 additions & 2 deletions api/identity.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (

"github.com/gin-gonic/gin"
"github.com/konveyor/tackle2-hub/model"
"gorm.io/gorm/clause"
)

// Routes
Expand All @@ -32,7 +33,7 @@ func (h IdentityHandler) AddRoutes(e *gin.Engine) {
routeGroup.GET(IdentitiesRoot+"/", h.setDecrypted, h.List)
routeGroup.POST(IdentitiesRoot, h.Create)
routeGroup.GET(IdentityRoot, h.setDecrypted, h.Get)
routeGroup.PUT(IdentityRoot, h.Update)
routeGroup.PUT(IdentityRoot, h.Update, Transaction)
routeGroup.DELETE(IdentityRoot, h.Delete)
}

Expand Down Expand Up @@ -186,7 +187,7 @@ func (h IdentityHandler) Update(ctx *gin.Context) {
return
}
ref := &model.Identity{}
err = h.DB(ctx).First(ref, id).Error
err = h.DB(ctx).Preload(clause.Associations).First(ref, id).Error
if err != nil {
_ = ctx.Error(err)
return
Expand All @@ -206,6 +207,15 @@ func (h IdentityHandler) Update(ctx *gin.Context) {
return
}

appHandler := ApplicationHandler{}
for i := range m.Applications {
err = appHandler.discover(ctx, &m.Applications[i])
if err != nil {
_ = ctx.Error(err)
return
}
}

h.Status(ctx, http.StatusNoContent)
}

Expand Down
9 changes: 4 additions & 5 deletions api/task.go
Original file line number Diff line number Diff line change
Expand Up @@ -292,15 +292,15 @@ func (h TaskHandler) Create(ctx *gin.Context) {
_ = ctx.Error(err)
return
}
err = h.findRefs(ctx, r)
rtx := WithContext(ctx)
err = h.FindRefs(rtx.Client, r)
if err != nil {
_ = ctx.Error(err)
return
}
task := &tasking.Task{}
task.With(r.Model())
task.CreateUser = h.BaseHandler.CurrentUser(ctx)
rtx := WithContext(ctx)
err = rtx.TaskManager.Create(h.DB(ctx), task)
if err != nil {
_ = ctx.Error(err)
Expand Down Expand Up @@ -617,14 +617,13 @@ func (h TaskHandler) GetAttached(ctx *gin.Context) {
}
}

// findRefs find referenced resources.
// FindRefs find referenced resources.
// - addon
// - extensions
// - kind
// - priority
// The priority is defaulted to the kind as needed.
func (h *TaskHandler) findRefs(ctx *gin.Context, r *Task) (err error) {
client := h.Client(ctx)
func (h *TaskHandler) FindRefs(client k8sclient.Client, r *Task) (err error) {
if r.Addon != "" {
addon := &crd.Addon{}
name := r.Addon
Expand Down
14 changes: 12 additions & 2 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@ var Settings = &settings.Settings
var log = logr.WithName("hub")

func init() {
_ = Settings.Load()
err := Settings.Load()
if err != nil {
panic(err)
}
}

// Setup the DB and models.
Expand Down Expand Up @@ -121,6 +124,10 @@ func main() {
return
}
}()
err = Settings.FindDiscoveryTasks()
if err != nil {
return
}
}
//
// k8s client.
Expand All @@ -129,6 +136,7 @@ func main() {
err = liberr.Wrap(err)
return
}

//
// Auth
if settings.Settings.Auth.Required {
Expand Down Expand Up @@ -168,7 +176,9 @@ func main() {
//
// Application import.
importManager := importer.Manager{
DB: db,
DB: db,
TaskManager: &taskManager,
Client: client,
}
importManager.Run(context.Background())
//
Expand Down
39 changes: 38 additions & 1 deletion importer/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,22 @@ import (
liberr "github.com/jortel/go-utils/error"
"github.com/konveyor/tackle2-hub/api"
"github.com/konveyor/tackle2-hub/model"
"github.com/konveyor/tackle2-hub/settings"
tasking "github.com/konveyor/tackle2-hub/task"
"gorm.io/gorm"
k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
)

var (
Settings = &settings.Settings
)

// Manager for processing application imports.
type Manager struct {
// DB
DB *gorm.DB
DB *gorm.DB
TaskManager *tasking.Manager
Client k8sclient.Client
}

// Run the manager.
Expand Down Expand Up @@ -334,11 +343,39 @@ func (m *Manager) createApplication(imp *model.Import) (ok bool) {
imp.ErrorMessage = result.Error.Error()
return
}
// best effort
err := m.discover(app)
if err != nil {
imp.ErrorMessage = fmt.Sprintf("Failed to launch discovery tasks for Application '%s'", app.Name)
return
}

ok = true
return
}

func (m *Manager) discover(application *model.Application) (err error) {
for _, kind := range Settings.Hub.Discovery.Tasks {
t := api.Task{}
t.Kind = kind
t.Name = fmt.Sprintf("%s-%s", application.Name, kind)
ref := api.Ref{ID: application.ID}
t.Application = &ref
t.State = tasking.Ready
taskHandler := api.TaskHandler{}
err = taskHandler.FindRefs(m.Client, &t)
if err != nil {
return
}
task := tasking.Task{Task: t.Model()}
err = m.TaskManager.Create(m.DB, &task)
if err != nil {
return
}
}
return
}

func (m *Manager) createStakeholder(name string, email string) (stakeholder model.Stakeholder, err error) {
stakeholder.Name = name
stakeholder.Email = email
Expand Down
17 changes: 9 additions & 8 deletions migration/v14/model/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,14 +244,15 @@ type Proxy struct {
// Identity represents and identity with a set of credentials.
type Identity struct {
Model
Kind string `gorm:"not null"`
Name string `gorm:"index;unique;not null"`
Description string
User string
Password string
Key string
Settings string
Proxies []Proxy `gorm:"constraint:OnDelete:SET NULL"`
Kind string `gorm:"not null"`
Name string `gorm:"index;unique;not null"`
Description string
User string
Password string
Key string
Settings string
Proxies []Proxy `gorm:"constraint:OnDelete:SET NULL"`
Applications []Application `gorm:"many2many:ApplicationIdentity;constraint:OnDelete:CASCADE"`
}

// Encrypt sensitive fields.
Expand Down
67 changes: 67 additions & 0 deletions settings/hub.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,22 @@
package settings

import (
"context"
"os"
"strconv"
"time"

liberr "github.com/jortel/go-utils/error"
crd "github.com/konveyor/tackle2-hub/k8s/api/tackle/v1alpha2"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/selection"
"k8s.io/client-go/kubernetes/scheme"
k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/config"
)

const (
DiscoveryLabel = "konveyor.io/discovery"
)

const (
Expand Down Expand Up @@ -34,6 +47,7 @@ const (
EnvDisconnected = "DISCONNECTED"
EnvAnalysisReportPath = "ANALYSIS_REPORT_PATH"
EnvAnalysisArchiverEnabled = "ANALYSIS_ARCHIVER_ENABLED"
EnvDiscoveryEnabled = "DISCOVERY_ENABLED"
)

type Hub struct {
Expand Down Expand Up @@ -100,6 +114,10 @@ type Hub struct {
ReportPath string
ArchiverEnabled bool
}
Discovery struct {
Enabled bool
Tasks []string
}
}

func (r *Hub) Load() (err error) {
Expand Down Expand Up @@ -258,6 +276,55 @@ func (r *Hub) Load() (err error) {
} else {
r.Analysis.ArchiverEnabled = true
}

if !r.Disconnected {
s, found = os.LookupEnv(EnvDiscoveryEnabled)
if found {
b, _ := strconv.ParseBool(s)
r.Discovery.Enabled = b
} else {
r.Discovery.Enabled = true
}
}

return
}

// FindDiscoveryTasks by their label.
func (r *Hub) FindDiscoveryTasks() (err error) {
if !r.Discovery.Enabled {
return
}
cfg, _ := config.GetConfig()
client, err := k8sclient.New(
cfg,
k8sclient.Options{
Scheme: scheme.Scheme,
})
if err != nil {
err = liberr.Wrap(err)
return
}
selector := labels.NewSelector()
req, _ := labels.NewRequirement(DiscoveryLabel, selection.Exists, []string{})
selector = selector.Add(*req)
options := &k8sclient.ListOptions{
Namespace: Settings.Namespace,
LabelSelector: selector,
}
list := crd.TaskList{}
err = client.List(
context.TODO(),
&list,
options)
if err != nil {
err = liberr.Wrap(err)
return
}
for i := range list.Items {
t := &list.Items[i]
r.Discovery.Tasks = append(r.Discovery.Tasks, t.Name)
}
return
}

Expand Down

0 comments on commit c9ff4b8

Please sign in to comment.