<commit_before>package device

import (
	"fmt"
	"strings"

	"github.com/logicmonitor/k8s-argus/pkg/config"
	"github.com/logicmonitor/k8s-argus/pkg/constants"
	"github.com/logicmonitor/k8s-argus/pkg/device/builder"
	"github.com/logicmonitor/k8s-argus/pkg/devicecache"
	"github.com/logicmonitor/k8s-argus/pkg/filters"
	"github.com/logicmonitor/k8s-argus/pkg/lmctx"
	lmlog "github.com/logicmonitor/k8s-argus/pkg/log"
	util "github.com/logicmonitor/k8s-argus/pkg/utilities"

	//"github.com/logicmonitor/k8s-argus/pkg/lmexec"
	"github.com/logicmonitor/k8s-argus/pkg/types"
	cscutils "github.com/logicmonitor/k8s-argus/pkg/utilities"
	"github.com/logicmonitor/lm-sdk-go/client/lm"
	"github.com/logicmonitor/lm-sdk-go/models"
)

// Manager implements types.DeviceManager
type Manager struct {
	ResourceType string
	*types.Base
	*builder.Builder
	types.LMExecutor
	types.LMFacade
	DC *devicecache.DeviceCache
}

func buildDevice(lctx *lmctx.LMContext, c *config.Config, d *models.Device, options ...types.DeviceOption) *models.Device {
	log := lmlog.Logger(lctx)
	if d == nil {
		hostGroupIds := "1"
		propertyName := constants.K8sClusterNamePropertyKey
		// use the copy value
		clusterName := c.ClusterName
		d = &models.Device{
			CustomProperties: []*models.NameAndValue{
				{
					Name:  &propertyName,
					Value: &clusterName,
				},
			},
			DisableAlerting: c.DisableAlerting,
			HostGroupIds:    &hostGroupIds,
			DeviceType:      constants.K8sDeviceType,
		}

		for _, option := range options {
			option(d)
		}

		collectorID := cscutils.GetCollectorID()
		log.Infof("Using collector ID %d for %q", collectorID, *d.DisplayName)
		d.PreferredCollectorID = &collectorID
	} else {
		for _, option := range options {
			option(d)
		}
	}

	return d
}

// checkAndUpdateExistingDevice tries to find and update the devices which needs to be changed
func (m *Manager) checkAndUpdateExistingDevice(lctx *lmctx.LMContext, resource string, device *models.Device) (*models.Device, error) {
	log := lmlog.Logger(lctx)
	currentCluster := m.Config().ClusterName
	existingDevices, err := m.FindByDisplayNames(lctx, resource, *device.DisplayName, util.GetFullDisplayName(device, resource, currentCluster))

	if err != nil {
		return nil, err
	}
	if len(existingDevices) == 0 {
		return nil, fmt.Errorf("cannot find devices with names: %s , %s", *device.DisplayName, util.GetFullDisplayName(device, resource, currentCluster))
	}
	for _, existingDevice := range existingDevices {
		clusterName := util.GetPropertyValue(existingDevice, constants.K8sClusterNamePropertyKey)
		if clusterName == currentCluster {
			// the device which is not changed will be ignored
			if util.GetDisplayNameWithNamespace(existingDevice, resource) == util.GetDisplayNameWithNamespace(device, resource) {
				log.Infof("No changes to device (%s). Ignoring update", *device.DisplayName)
				m.DC.Set(util.GetFullDisplayName(existingDevice, resource, currentCluster))
				return nil, nil
			}

			log.Infof("Updating and moving to conflicts group - existing device (%s)", *existingDevice.DisplayName)
			err2 := m.moveDeviceToConflictGroup(lctx, existingDevice, resource)
			if err2 != nil {
				log.Errorf("%v", err2)
				return nil, err2
			}

			m.DC.Set(util.GetFullDisplayName(existingDevice, resource, currentCluster))
			return existingDevice, nil
		}
	}
	return nil, nil
}

// renameAndAddDevice rename display name and then add the device
func (m *Manager) renameAndAddDevice(lctx *lmctx.LMContext, resource string, device *models.Device) (*models.Device, error) {
	restResponse, err := m.addDevice(lctx, resource, device)

	if err != nil {
		return nil, err
	}
	return restResponse.(*lm.AddDeviceOK).Payload, nil
}<commit_msg>fix(multicluster): conflicting device within multiple clusters wasn't adding (#156)<commit_after>package device

import (
	"fmt"
	"strings"

	"github.com/logicmonitor/k8s-argus/pkg/config"
	"github.com/logicmonitor/k8s-argus/pkg/constants"
	"github.com/logicmonitor/k8s-argus/pkg/device/builder"
	"github.com/logicmonitor/k8s-argus/pkg/devicecache"
	"github.com/logicmonitor/k8s-argus/pkg/filters"
	"github.com/logicmonitor/k8s-argus/pkg/lmctx"
	lmlog "github.com/logicmonitor/k8s-argus/pkg/log"
	util "github.com/logicmonitor/k8s-argus/pkg/utilities"

	//"github.com/logicmonitor/k8s-argus/pkg/lmexec"
	"github.com/logicmonitor/k8s-argus/pkg/types"
	cscutils "github.com/logicmonitor/k8s-argus/pkg/utilities"
	"github.com/logicmonitor/lm-sdk-go/client/lm"
	"github.com/logicmonitor/lm-sdk-go/models"
)

// Manager implements types.DeviceManager
type Manager struct {
	ResourceType string
	*types.Base
	*builder.Builder
	types.LMExecutor
	types.LMFacade
	DC *devicecache.DeviceCache
}

func buildDevice(lctx *lmctx.LMContext, c *config.Config, d *models.Device, options ...types.DeviceOption) *models.Device {
	log := lmlog.Logger(lctx)
	if d == nil {
		hostGroupIds := "1"
		propertyName := constants.K8sClusterNamePropertyKey
		// use the copy value
		clusterName := c.ClusterName
		d = &models.Device{
			CustomProperties: []*models.NameAndValue{
				{
					Name:  &propertyName,
					Value: &clusterName,
				},
			},
			DisableAlerting: c.DisableAlerting,
			HostGroupIds:    &hostGroupIds,
			DeviceType:      constants.K8sDeviceType,
		}

		for _, option := range options {
			option(d)
		}

		collectorID := cscutils.GetCollectorID()
		log.Infof("Using collector ID %d for %q", collectorID, *d.DisplayName)
		d.PreferredCollectorID = &collectorID
	} else {
		for _, option := range options {
			option(d)
		}
	}

	return d
}

// checkAndUpdateExistingDevice tries to find and update the devices which needs to be changed
func (m *Manager) checkAndUpdateExistingDevice(lctx *lmctx.LMContext, resource string, device *models.Device) (*models.Device, error) {
	log := lmlog.Logger(lctx)
	currentCluster := m.Config().ClusterName
	existingDevices, err := m.FindByDisplayNames(lctx, resource, *device.DisplayName, util.GetFullDisplayName(device, resource, currentCluster))

	if err != nil {
		return nil, err
	}
	if len(existingDevices) == 0 {
		return nil, fmt.Errorf("cannot find devices with names: %s , %s", *device.DisplayName, util.GetFullDisplayName(device, resource, currentCluster))
	}
	for _, existingDevice := range existingDevices {
		clusterName := util.GetPropertyValue(existingDevice, constants.K8sClusterNamePropertyKey)
		if clusterName == currentCluster {
			// the device which is not changed will be ignored
			if util.GetDisplayNameWithNamespace(existingDevice, resource) == util.GetDisplayNameWithNamespace(device, resource) {
				log.Infof("No changes to device (%s). Ignoring update", *device.DisplayName)
				m.DC.Set(util.GetFullDisplayName(existingDevice, resource, currentCluster))
				return nil, nil
			}

			log.Infof("Updating and moving to conflicts group - existing device (%s)", *existingDevice.DisplayName)
			err2 := m.moveDeviceToConflictGroup(lctx, existingDevice, resource)
			if err2 != nil {
				log.Errorf("%v", err2)
				return nil, err2
			}

			m.DC.Set(util.GetFullDisplayName(existingDevice, resource, currentCluster))
			return existingDevice, nil
		}
	}
	return device, nil
}

// renameAndAddDevice rename display name and then add the device
func (m *Manager) renameAndAddDevice(lctx *lmctx.LMContext, resource string, device *models.Device) (*models.Device, error) {
	restResponse, err := m.addDevice(lctx, resource, device)

	if err != nil {
		return nil, err
	}
	return restResponse.(*lm.AddDeviceOK).Payload, nil
}
{'fraction_non_alphanumeric': 0.12059965198768571, 'fraction_numerical': 0.0057555882746620265, 'mean_word_length': 4.547141796585004, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5246215', 'n_tokens_mistral': 2686, 'n_tokens_neox': 2465, 'n_words': 528}