diff --git a/api/application.go b/api/application.go index f0ba525fb..ca2abf65d 100644 --- a/api/application.go +++ b/api/application.go @@ -250,7 +250,7 @@ func (h ApplicationHandler) Create(ctx *gin.Context) { return } - err = discover(ctx, m) + err = h.discover(ctx, m) if err != nil { _ = ctx.Error(err) return @@ -380,7 +380,7 @@ func (h ApplicationHandler) Update(ctx *gin.Context) { } } - err = discover(ctx, m) + err = h.discover(ctx, m) if err != nil { _ = ctx.Error(err) return @@ -1074,6 +1074,25 @@ 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 := model.Task{} + task := tasking.Task{Task: &t} + task.Kind = kind + task.Name = fmt.Sprintf("%s-%s", application.Name, kind) + task.ApplicationID = &application.ID + task.State = tasking.Ready + err = rtx.TaskManager.Create(db, &task) + if err != nil { + return + } + } + return +} + // Application REST resource. type Application struct { Resource `yaml:",inline"` @@ -1346,22 +1365,3 @@ func (r *Stakeholders) contributors() (contributors []model.Stakeholder) { } return } - -func discover(ctx *gin.Context, application *model.Application) (err error) { - rtx := WithContext(ctx) - db := rtx.DB.Debug() - kinds := []string{Settings.Hub.Task.Kinds.Discovery.Language, Settings.Hub.Task.Kinds.Discovery.Technology} - for _, kind := range kinds { - t := model.Task{} - task := tasking.Task{Task: &t} - task.Kind = kind - task.Name = fmt.Sprintf("%s-%s", application.Name, kind) - task.ApplicationID = &application.ID - task.State = tasking.Ready - err = rtx.TaskManager.Create(db, &task) - if err != nil { - return - } - } - return -} diff --git a/api/identity.go b/api/identity.go index c9922cd32..5ffb006a9 100644 --- a/api/identity.go +++ b/api/identity.go @@ -207,8 +207,9 @@ func (h IdentityHandler) Update(ctx *gin.Context) { return } + appHandler := ApplicationHandler{} for i := range m.Applications { - err = discover(ctx, &m.Applications[i]) + err = appHandler.discover(ctx, &m.Applications[i]) if err != nil { _ = ctx.Error(err) return diff --git a/importer/manager.go b/importer/manager.go index fb35601b5..b2830d1bd 100644 --- a/importer/manager.go +++ b/importer/manager.go @@ -349,8 +349,7 @@ func (m *Manager) createApplication(imp *model.Import) (ok bool) { } func (m *Manager) discover(application *model.Application) (err error) { - kinds := []string{Settings.Hub.Task.Kinds.Discovery.Language, Settings.Hub.Task.Kinds.Discovery.Technology} - for _, kind := range kinds { + for _, kind := range Settings.Hub.Discovery.Tasks { t := model.Task{} task := tasking.Task{Task: &t} task.Kind = kind diff --git a/settings/hub.go b/settings/hub.go index c8d07e3d1..f20843764 100644 --- a/settings/hub.go +++ b/settings/hub.go @@ -1,41 +1,52 @@ package settings import ( + "context" "os" "strconv" "time" + + liberr "github.com/jortel/go-utils/error" + "github.com/konveyor/tackle2-hub/k8s" + crd "github.com/konveyor/tackle2-hub/k8s/api/tackle/v1alpha2" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/selection" + k8sclient "sigs.k8s.io/controller-runtime/pkg/client" ) const ( - EnvNamespace = "NAMESPACE" - EnvDbPath = "DB_PATH" - EnvDbSeedPath = "DB_SEED_PATH" - EnvBucketPath = "BUCKET_PATH" - EnvRwxSupported = "RWX_SUPPORTED" - EnvCachePath = "CACHE_PATH" - EnvCachePvc = "CACHE_PVC" - EnvSharedPath = "SHARED_PATH" - EnvPassphrase = "ENCRYPTION_PASSPHRASE" - EnvTaskReapCreated = "TASK_REAP_CREATED" - EnvTaskReapSucceeded = "TASK_REAP_SUCCEEDED" - EnvTaskReapFailed = "TASK_REAP_FAILED" - EnvTaskSA = "TASK_SA" - EnvTaskRetries = "TASK_RETRIES" - EnvTaskPreemptEnabled = "TASK_PREEMPT_ENABLED" - EnvTaskPreemptDelayed = "TASK_PREEMPT_DELAYED" - EnvTaskPreemptPostponed = "TASK_PREEMPT_POSTPONED" - EnvTaskPreemptRate = "TASK_PREEMPT_RATE" - EnvFrequencyTask = "FREQUENCY_TASK" - EnvFrequencyReaper = "FREQUENCY_REAPER" - EnvDevelopment = "DEVELOPMENT" - EnvBucketTTL = "BUCKET_TTL" - EnvFileTTL = "FILE_TTL" - EnvAppName = "APP_NAME" - EnvDisconnected = "DISCONNECTED" - EnvAnalysisReportPath = "ANALYSIS_REPORT_PATH" - EnvAnalysisArchiverEnabled = "ANALYSIS_ARCHIVER_ENABLED" - EnvTaskKindDiscoveryLanguage = "TASK_KIND_DISCOVERY_LANGUAGE" - EnvTaskKindDiscoveryTechnology = "TASK_KIND_DISCOVERY_TECHNOLOGY" + DiscoveryLabel = "konveyor.io/discovery" +) + +const ( + EnvNamespace = "NAMESPACE" + EnvDbPath = "DB_PATH" + EnvDbSeedPath = "DB_SEED_PATH" + EnvBucketPath = "BUCKET_PATH" + EnvRwxSupported = "RWX_SUPPORTED" + EnvCachePath = "CACHE_PATH" + EnvCachePvc = "CACHE_PVC" + EnvSharedPath = "SHARED_PATH" + EnvPassphrase = "ENCRYPTION_PASSPHRASE" + EnvTaskReapCreated = "TASK_REAP_CREATED" + EnvTaskReapSucceeded = "TASK_REAP_SUCCEEDED" + EnvTaskReapFailed = "TASK_REAP_FAILED" + EnvTaskSA = "TASK_SA" + EnvTaskRetries = "TASK_RETRIES" + EnvTaskPreemptEnabled = "TASK_PREEMPT_ENABLED" + EnvTaskPreemptDelayed = "TASK_PREEMPT_DELAYED" + EnvTaskPreemptPostponed = "TASK_PREEMPT_POSTPONED" + EnvTaskPreemptRate = "TASK_PREEMPT_RATE" + EnvFrequencyTask = "FREQUENCY_TASK" + EnvFrequencyReaper = "FREQUENCY_REAPER" + EnvDevelopment = "DEVELOPMENT" + EnvBucketTTL = "BUCKET_TTL" + EnvFileTTL = "FILE_TTL" + EnvAppName = "APP_NAME" + EnvDisconnected = "DISCONNECTED" + EnvAnalysisReportPath = "ANALYSIS_REPORT_PATH" + EnvAnalysisArchiverEnabled = "ANALYSIS_ARCHIVER_ENABLED" + EnvDiscoveryEnabled = "DISCOVERY_ENABLED" ) type Hub struct { @@ -108,6 +119,10 @@ type Hub struct { ReportPath string ArchiverEnabled bool } + Discovery struct { + Enabled bool + Tasks []string + } } func (r *Hub) Load() (err error) { @@ -267,13 +282,49 @@ func (r *Hub) Load() (err error) { r.Analysis.ArchiverEnabled = true } - r.Task.Kinds.Discovery.Language, found = os.LookupEnv(EnvTaskKindDiscoveryLanguage) - if !found { - r.Task.Kinds.Discovery.Language = "language-discovery" + if !r.Disconnected { + s, found = os.LookupEnv(EnvDiscoveryEnabled) + if found { + b, _ := strconv.ParseBool(s) + r.Discovery.Enabled = b + } else { + r.Discovery.Enabled = true + r.Discovery.Tasks, err = r.discoveryTasks() + if err != nil { + return err + } + } } - r.Task.Kinds.Discovery.Technology, found = os.LookupEnv(EnvTaskKindDiscoveryTechnology) - if !found { - r.Task.Kinds.Discovery.Technology = "tech-discovery" + + return +} + +// discoveryTasks finds discovery tasks by their label +func (r *Hub) discoveryTasks() (tasks []string, err error) { + client, err := k8s.NewClient() + 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] + tasks = append(tasks, t.Name) } return }