Skip to content

Commit

Permalink
Separate Item and ItemState; fill BelongsToCollectsion with all ances…
Browse files Browse the repository at this point in the history
…tors and for uninstalled items too
  • Loading branch information
mmetc committed Nov 20, 2023
1 parent 7b1074f commit 3cdcb80
Show file tree
Hide file tree
Showing 18 changed files with 237 additions and 195 deletions.
16 changes: 8 additions & 8 deletions cmd/crowdsec-cli/config_backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,30 +40,30 @@ func backupHub(dirPath string) error {
clog = clog.WithFields(log.Fields{
"file": v.Name,
})
if !v.Installed { //only backup installed ones
if !v.State.Installed { //only backup installed ones
clog.Debugf("[%s] : not installed", k)
continue
}

//for the local/tainted ones, we back up the full file
if v.Tainted || v.IsLocal() || !v.UpToDate {
if v.State.Tainted || v.IsLocal() || !v.State.UpToDate {
//we need to backup stages for parsers
if itemType == cwhub.PARSERS || itemType == cwhub.POSTOVERFLOWS {
fstagedir := fmt.Sprintf("%s%s", itemDirectory, v.Stage)
if err = os.MkdirAll(fstagedir, os.ModePerm); err != nil {
return fmt.Errorf("error while creating stage dir %s : %s", fstagedir, err)
}
}
clog.Debugf("[%s]: backing up file (tainted:%t local:%t up-to-date:%t)", k, v.Tainted, v.IsLocal(), v.UpToDate)
clog.Debugf("[%s]: backing up file (tainted:%t local:%t up-to-date:%t)", k, v.State.Tainted, v.IsLocal(), v.State.UpToDate)
tfile := fmt.Sprintf("%s%s/%s", itemDirectory, v.Stage, v.FileName)
if err = CopyFile(v.LocalPath, tfile); err != nil {
return fmt.Errorf("failed copy %s %s to %s : %s", itemType, v.LocalPath, tfile, err)
if err = CopyFile(v.State.LocalPath, tfile); err != nil {
return fmt.Errorf("failed copy %s %s to %s : %s", itemType, v.State.LocalPath, tfile, err)
}
clog.Infof("local/tainted saved %s to %s", v.LocalPath, tfile)
clog.Infof("local/tainted saved %s to %s", v.State.LocalPath, tfile)
continue
}
clog.Debugf("[%s] : from hub, just backup name (up-to-date:%t)", k, v.UpToDate)
clog.Infof("saving, version:%s, up-to-date:%t", v.Version, v.UpToDate)
clog.Debugf("[%s] : from hub, just backup name (up-to-date:%t)", k, v.State.UpToDate)
clog.Infof("saving, version:%s, up-to-date:%t", v.Version, v.State.UpToDate)
upstreamParsers = append(upstreamParsers, v.Name)
}
//write the upstream items
Expand Down
4 changes: 2 additions & 2 deletions cmd/crowdsec-cli/itemcommands.go
Original file line number Diff line number Diff line change
Expand Up @@ -331,8 +331,8 @@ func itemsRemoveRunner(it hubItemType) func(cmd *cobra.Command, args []string) e
return fmt.Errorf("can't find '%s' in %s", itemName, it.name)
}

if !force && len(item.BelongsToCollections) > 0 {
log.Warningf("%s belongs to collections: %s", item.Name, item.BelongsToCollections)
if !force && len(item.State.BelongsToCollections) > 0 {
log.Warningf("%s belongs to collections: %s", item.Name, item.State.BelongsToCollections)
log.Warningf("Run 'sudo cscli %s remove %s --force' if you want to force remove this %s", item.Type, item.Name, it.singular)

continue
Expand Down
8 changes: 4 additions & 4 deletions cmd/crowdsec-cli/items.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func selectItems(hub *cwhub.Hub, itemType string, args []string, installedOnly b

for _, itemName := range itemNames {
item := hub.GetItem(itemType, itemName)
if installedOnly && !item.Installed {
if installedOnly && !item.State.Installed {
continue
}

Expand Down Expand Up @@ -78,8 +78,8 @@ func listItems(out io.Writer, itemTypes []string, items map[string][]*cwhub.Item
status, emo := item.Status()
hubStatus[itemType][i] = itemHubStatus{
Name: item.Name,
LocalVersion: item.LocalVersion,
LocalPath: item.LocalPath,
LocalVersion: item.State.LocalVersion,
LocalPath: item.State.LocalPath,
Description: item.Description,
Status: status,
UTF8Status: fmt.Sprintf("%v %s", emo, status),
Expand Down Expand Up @@ -111,7 +111,7 @@ func listItems(out io.Writer, itemTypes []string, items map[string][]*cwhub.Item
row := []string{
item.Name,
status,
item.LocalVersion,
item.State.LocalVersion,
item.Description,
}
if len(itemTypes) > 1 {
Expand Down
2 changes: 1 addition & 1 deletion cmd/crowdsec-cli/simulation.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ func NewSimulationEnableCmd() *cobra.Command {
log.Errorf("'%s' doesn't exist or is not a scenario", scenario)
continue
}
if !item.Installed {
if !item.State.Installed {
log.Warningf("'%s' isn't enabled", scenario)
}
isExcluded := slices.Contains(csConfig.Cscli.SimulationConfig.Exclusions, scenario)
Expand Down
2 changes: 1 addition & 1 deletion cmd/crowdsec-cli/utils_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func listHubItemTable(out io.Writer, title string, items []*cwhub.Item) {

for _, item := range items {
status, emo := item.Status()
t.AddRow(item.Name, fmt.Sprintf("%v %s", emo, status), item.LocalVersion, item.LocalPath)
t.AddRow(item.Name, fmt.Sprintf("%v %s", emo, status), item.State.LocalVersion, item.State.LocalPath)
}
renderTableTitle(out, title)
t.Render()
Expand Down
4 changes: 2 additions & 2 deletions cmd/crowdsec/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ func LoadBuckets(cConfig *csconfig.Config, hub *cwhub.Hub) error {
files []string
)
for _, hubScenarioItem := range hub.GetItemMap(cwhub.SCENARIOS) {
if hubScenarioItem.Installed {
files = append(files, hubScenarioItem.LocalPath)
if hubScenarioItem.State.Installed {
files = append(files, hubScenarioItem.State.LocalPath)
}
}
buckets = leakybucket.NewBuckets()
Expand Down
14 changes: 7 additions & 7 deletions pkg/cwhub/enable.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ func (i *Item) createInstallLink() error {

// enable enables the item by creating a symlink to the downloaded content, and also enables sub-items
func (i *Item) enable() error {
if i.Installed {
if i.Tainted {
if i.State.Installed {
if i.State.Tainted {
return fmt.Errorf("%s is tainted, won't enable unless --force", i.Name)
}

Expand All @@ -75,7 +75,7 @@ func (i *Item) enable() error {
}

// if it's a collection, check sub-items even if the collection file itself is up-to-date
if i.UpToDate && !i.HasSubItems() {
if i.State.UpToDate && !i.HasSubItems() {
log.Tracef("%s is installed and up-to-date, skip.", i.Name)
return nil
}
Expand All @@ -92,14 +92,14 @@ func (i *Item) enable() error {
}

log.Infof("Enabled %s: %s", i.Type, i.Name)
i.Installed = true
i.State.Installed = true

return nil
}

// purge removes the actual config file that was downloaded
func (i *Item) purge() error {
if !i.Downloaded {
if !i.State.Downloaded {
log.Infof("removing %s: not downloaded -- no need to remove", i.Name)
return nil
}
Expand All @@ -118,7 +118,7 @@ func (i *Item) purge() error {
return fmt.Errorf("while removing file: %w", err)
}

i.Downloaded = false
i.State.Downloaded = false
log.Infof("Removed source file [%s]: %s", i.Name, src)

return nil
Expand Down Expand Up @@ -179,7 +179,7 @@ func (i *Item) disable(purge bool, force bool) error {
return err
}

i.Installed = false
i.State.Installed = false

if purge {
if err := i.purge(); err != nil {
Expand Down
32 changes: 16 additions & 16 deletions pkg/cwhub/enable_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,36 +16,36 @@ func testInstall(hub *Hub, t *testing.T, item *Item) {
err = hub.localSync()
require.NoError(t, err, "failed to run localSync")

assert.True(t, hub.Items[item.Type][item.Name].UpToDate, "%s should be up-to-date", item.Name)
assert.False(t, hub.Items[item.Type][item.Name].Installed, "%s should not be installed", item.Name)
assert.False(t, hub.Items[item.Type][item.Name].Tainted, "%s should not be tainted", item.Name)
assert.True(t, hub.Items[item.Type][item.Name].State.UpToDate, "%s should be up-to-date", item.Name)
assert.False(t, hub.Items[item.Type][item.Name].State.Installed, "%s should not be installed", item.Name)
assert.False(t, hub.Items[item.Type][item.Name].State.Tainted, "%s should not be tainted", item.Name)

err = item.enable()
require.NoError(t, err, "failed to enable %s", item.Name)

err = hub.localSync()
require.NoError(t, err, "failed to run localSync")

assert.True(t, hub.Items[item.Type][item.Name].Installed, "%s should be installed", item.Name)
assert.True(t, hub.Items[item.Type][item.Name].State.Installed, "%s should be installed", item.Name)
}

func testTaint(hub *Hub, t *testing.T, item *Item) {
assert.False(t, hub.Items[item.Type][item.Name].Tainted, "%s should not be tainted", item.Name)
assert.False(t, hub.Items[item.Type][item.Name].State.Tainted, "%s should not be tainted", item.Name)

// truncate the file
f, err := os.Create(item.LocalPath)
f, err := os.Create(item.State.LocalPath)
require.NoError(t, err)
f.Close()

// Local sync and check status
err = hub.localSync()
require.NoError(t, err, "failed to run localSync")

assert.True(t, hub.Items[item.Type][item.Name].Tainted, "%s should be tainted", item.Name)
assert.True(t, hub.Items[item.Type][item.Name].State.Tainted, "%s should be tainted", item.Name)
}

func testUpdate(hub *Hub, t *testing.T, item *Item) {
assert.False(t, hub.Items[item.Type][item.Name].UpToDate, "%s should not be up-to-date", item.Name)
assert.False(t, hub.Items[item.Type][item.Name].State.UpToDate, "%s should not be up-to-date", item.Name)

// Update it + check status
_, err := item.downloadLatest(true, true)
Expand All @@ -55,12 +55,12 @@ func testUpdate(hub *Hub, t *testing.T, item *Item) {
err = hub.localSync()
require.NoError(t, err, "failed to run localSync")

assert.True(t, hub.Items[item.Type][item.Name].UpToDate, "%s should be up-to-date", item.Name)
assert.False(t, hub.Items[item.Type][item.Name].Tainted, "%s should not be tainted anymore", item.Name)
assert.True(t, hub.Items[item.Type][item.Name].State.UpToDate, "%s should be up-to-date", item.Name)
assert.False(t, hub.Items[item.Type][item.Name].State.Tainted, "%s should not be tainted anymore", item.Name)
}

func testDisable(hub *Hub, t *testing.T, item *Item) {
assert.True(t, hub.Items[item.Type][item.Name].Installed, "%s should be installed", item.Name)
assert.True(t, hub.Items[item.Type][item.Name].State.Installed, "%s should be installed", item.Name)

// Remove
err := item.disable(false, false)
Expand All @@ -71,9 +71,9 @@ func testDisable(hub *Hub, t *testing.T, item *Item) {
require.NoError(t, err, "failed to run localSync")
require.Empty(t, hub.Warnings)

assert.False(t, hub.Items[item.Type][item.Name].Tainted, "%s should not be tainted anymore", item.Name)
assert.False(t, hub.Items[item.Type][item.Name].Installed, "%s should not be installed anymore", item.Name)
assert.True(t, hub.Items[item.Type][item.Name].Downloaded, "%s should still be downloaded", item.Name)
assert.False(t, hub.Items[item.Type][item.Name].State.Tainted, "%s should not be tainted anymore", item.Name)
assert.False(t, hub.Items[item.Type][item.Name].State.Installed, "%s should not be installed anymore", item.Name)
assert.True(t, hub.Items[item.Type][item.Name].State.Downloaded, "%s should still be downloaded", item.Name)

// Purge
err = item.disable(true, false)
Expand All @@ -84,8 +84,8 @@ func testDisable(hub *Hub, t *testing.T, item *Item) {
require.NoError(t, err, "failed to run localSync")
require.Empty(t, hub.Warnings)

assert.False(t, hub.Items[item.Type][item.Name].Installed, "%s should not be installed anymore", item.Name)
assert.False(t, hub.Items[item.Type][item.Name].Downloaded, "%s should not be downloaded", item.Name)
assert.False(t, hub.Items[item.Type][item.Name].State.Installed, "%s should not be installed anymore", item.Name)
assert.False(t, hub.Items[item.Type][item.Name].State.Downloaded, "%s should not be downloaded", item.Name)
}

func TestInstallParser(t *testing.T) {
Expand Down
38 changes: 19 additions & 19 deletions pkg/cwhub/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import (

// Install installs the item from the hub, downloading it if needed
func (i *Item) Install(force bool, downloadOnly bool) error {
if downloadOnly && i.Downloaded && i.UpToDate {
if downloadOnly && i.State.Downloaded && i.State.UpToDate {
log.Infof("%s is already downloaded and up-to-date", i.Name)

if !force {
Expand Down Expand Up @@ -100,11 +100,11 @@ func (i *Item) Remove(purge bool, force bool) (bool, error) {
return false, fmt.Errorf("%s isn't managed by hub. Please delete manually", i.Name)
}

if i.Tainted && !force {
if i.State.Tainted && !force {
return false, fmt.Errorf("%s is tainted, use '--force' to remove", i.Name)
}

if !i.Installed && !purge {
if !i.State.Installed && !purge {
log.Infof("removing %s: not installed -- no need to remove", i.Name)
return false, nil
}
Expand All @@ -117,7 +117,7 @@ func (i *Item) Remove(purge bool, force bool) (bool, error) {
}

for _, sub := range i.SubItems() {
if !sub.Installed {
if !sub.State.Installed {
continue
}

Expand Down Expand Up @@ -156,15 +156,15 @@ func (i *Item) Remove(purge bool, force bool) (bool, error) {
func (i *Item) Upgrade(force bool) (bool, error) {
updated := false

if !i.Downloaded {
if !i.State.Downloaded {
return false, fmt.Errorf("can't upgrade %s: not installed", i.Name)
}

if !i.Installed {
if !i.State.Installed {
return false, fmt.Errorf("can't upgrade %s: downloaded but not installed", i.Name)
}

if i.UpToDate {
if i.State.UpToDate {
log.Infof("%s: up-to-date", i.Name)

if err := i.DownloadDataIfNeeded(force); err != nil {
Expand All @@ -181,8 +181,8 @@ func (i *Item) Upgrade(force bool) (bool, error) {
return false, fmt.Errorf("%s: download failed: %w", i.Name, err)
}

if !i.UpToDate {
if i.Tainted {
if !i.State.UpToDate {
if i.State.Tainted {
log.Infof("%v %s is tainted, --force to overwrite", emoji.Warning, i.Name)
} else if i.IsLocal() {
log.Infof("%v %s is local", emoji.Prohibited, i.Name)
Expand All @@ -205,12 +205,12 @@ func (i *Item) downloadLatest(overwrite bool, updateOnly bool) (string, error) {
log.Debugf("Downloading %s %s", i.Type, i.Name)

for _, sub := range i.SubItems() {
if !sub.Installed && updateOnly && sub.Downloaded {
if !sub.State.Installed && updateOnly && sub.State.Downloaded {
log.Debugf("skipping upgrade of %s: not installed", i.Name)
continue
}

log.Debugf("Download %s sub-item: %s %s (%t -> %t)", i.Name, sub.Type, sub.Name, i.Installed, updateOnly)
log.Debugf("Download %s sub-item: %s %s (%t -> %t)", i.Name, sub.Type, sub.Name, i.State.Installed, updateOnly)

// recurse as it's a collection
if sub.HasSubItems() {
Expand All @@ -221,22 +221,22 @@ func (i *Item) downloadLatest(overwrite bool, updateOnly bool) (string, error) {
}
}

downloaded := sub.Downloaded
downloaded := sub.State.Downloaded

if _, err := sub.download(overwrite); err != nil {
return "", fmt.Errorf("while downloading %s: %w", sub.Name, err)
}

// We need to enable an item when it has been added to a collection since latest release of the collection.
// We check if sub.Downloaded is false because maybe the item has been disabled by the user.
if !sub.Installed && !downloaded {
if !sub.State.Installed && !downloaded {
if err := sub.enable(); err != nil {
return "", fmt.Errorf("enabling '%s': %w", sub.Name, err)
}
}
}

if !i.Installed && updateOnly && i.Downloaded {
if !i.State.Installed && updateOnly && i.State.Downloaded {
log.Debugf("skipping upgrade of %s: not installed", i.Name)
return "", nil
}
Expand Down Expand Up @@ -291,12 +291,12 @@ func (i *Item) fetch() ([]byte, error) {
func (i *Item) download(overwrite bool) (string, error) {
// if user didn't --force, don't overwrite local, tainted, up-to-date files
if !overwrite {
if i.Tainted {
if i.State.Tainted {
log.Debugf("%s: tainted, not updated", i.Name)
return "", nil
}

if i.UpToDate {
if i.State.UpToDate {
// We still have to check if data files are present
log.Debugf("%s: up-to-date, not updated", i.Name)
}
Expand Down Expand Up @@ -333,9 +333,9 @@ func (i *Item) download(overwrite bool) (string, error) {
return "", fmt.Errorf("while writing %s: %w", finalPath, err)
}

i.Downloaded = true
i.Tainted = false
i.UpToDate = true
i.State.Downloaded = true
i.State.Tainted = false
i.State.UpToDate = true

if err = downloadDataSet(i.hub.local.InstallDataDir, overwrite, bytes.NewReader(body)); err != nil {
return "", fmt.Errorf("while downloading data for %s: %w", i.FileName, err)
Expand Down
Loading

0 comments on commit 3cdcb80

Please sign in to comment.