Skip to content
This repository was archived by the owner on Jan 16, 2023. It is now read-only.

Commit cedf4e8

Browse files
DzXiaoLMCDslopeinsb
authored andcommitted
Develop (#112)
* DEV-39965: Allow the user to specify a parent group during installation * DEV-39965: Allow the user to specify a parent group during installation * DEV-40505: Sync the k8s resource to santaba when argus launches * DEV-40434: The alert status of Pods and Services are disabled * DEV-40505: Sync the k8s resource to santaba when argus launches * DEV-40505: Sync the k8s resource to santaba when argus launches * DEV-40779: Enable the alert on service group when it is created by argus * DEV-41432: Use IP as hostname for argus related devices * DEV-41432: Use IP as hostname for argus related devices * DEV-41459: Add a new device type for k8s devices * DEV-41432: Use IP as hostname for argus related devices * DEV-40217: Support to set log levels and improve logs in argus related projects * DEV-40217: Support to set log levels and improve logs in argus related projects * DEV-41682: Improve the argus code for the CI failure in GitHub * Dev-40217 support to set log levels and improve Dev-40217 support to set log levels and improve * DEV-41947: Improve the initsync logic to prevent lost data after k8s device is updated * DEV-41947: Improve the initsync logic to prevent lost data after k8s device is updated * DEV-42060: Don't create collector device for Kubernetes Clusters * DEV-47062 Add distinguishing property to host network pods * DEV-49046 Fix the internal IP cannot found bug in argus * DEV-49046 Fix the internal IP cannot found bug in argus * Update node_test.go * DEV-48974 Upgrade Argus from golang 1.9 to 1.11 * DEV-48974 Upgrade Argus from golang 1.9 to 1.11 * DEV-49251 improve panic log process * DEV-50734 Support all service type, and add the logs * DEV-41301 Upgrade the go sdk to v2 * DEV-41301 Upgrade the go sdk to v2 * DEV-41301 Upgrade the go sdk to v2 * DEV-41301 Upgrade the go sdk to v2 * DEV-50734 Support all service type, modify the UpdateFunc * DEV-41301 Upgrade the go sdk to v2 * DEV-50929 Add k8s deployments monitoring by Argus * DEV-49251 Add the defer to initSync and improve log output * DEV-41301 Upgrade the go sdk to v2 * DEV-50929 Improve the code with comments * DEV-50734 Improve the log message * DEV-49251 Improve the log message * DEV-49251 Improve the comments * DEV-51405 Fix the argus log format * DEV-51567 Fixed the label value of k8s monitored * DEV-49675 Synchronous develop branch, add the recover panic logic for deployments * Modify the format by Travis CI check * DEV-51677 Improve the code according to github comments * Improve the variable naming * DEV-51932 fix uptime widget for k8s resources * DEV-49675 Restore the dockerfile * DEV-52508 Fixed the CI check * DEV-52508 Argus deployment rbac privilege improve * DEV-52508 Argus deployment rbac privilege improve * DEV-52508 Argus deployment rbac privilege compatibility improvement * DEV-52508 Argus deployment rbac privilege compatibility improvement * DEV-52508 Argus deployment rbac privilege compatibility improvement * DEV-52036 Allow for duplicate pod names in one LM account * DEV-52508 Improve by the comments * DEV-52508 Fix the comments * DEV-52508 Fix the comments * remove logo link * DEV-52036 Allow for duplicate pod names in one LM account * DEV-52036 Allow for duplicate pod names in one LM account * DEV-52036 Allow for duplicate pod names in one LM account * DEV-52036 Fix the comments * DEV-52036 Fix the comments * DEV-52991 Add UT
1 parent 654d92c commit cedf4e8

File tree

9 files changed

+181
-38
lines changed

9 files changed

+181
-38
lines changed

pkg/constants/constants.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ const (
8484
const (
8585
// K8sClusterNamePropertyKey is the key of the unique auto property kubernetes cluster name
8686
K8sClusterNamePropertyKey = "auto.clustername"
87+
// K8sResourceNamePropertyKey is the key of the custom property used to record resource name
88+
K8sResourceNamePropertyKey = "auto.resourcename"
8789
// K8sResourceCreatedOnPropertyKey is the key of the custom property used to record resource create timestamp
8890
K8sResourceCreatedOnPropertyKey = "kubernetes.resourceCreatedOn"
8991
// K8sDeviceType is the type value of the k8s device

pkg/device/device.go

Lines changed: 111 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package device
33
import (
44
"context"
55
"fmt"
6+
"strings"
67

78
"github.com/logicmonitor/k8s-argus/pkg/config"
89
"github.com/logicmonitor/k8s-argus/pkg/constants"
@@ -55,40 +56,92 @@ func buildDevice(c *config.Config, client api.CollectorSetControllerClient, opti
5556

5657
// checkAndUpdateExistingDevice tries to find and update the devices which needs to be changed
5758
func (m *Manager) checkAndUpdateExistingDevice(device *models.Device) (*models.Device, error) {
58-
oldDevice, err := m.FindByDisplayName(*device.DisplayName)
59+
displayNameWithClusterName := fmt.Sprintf("%s-%s", *device.DisplayName, m.Config().ClusterName)
60+
existingDevices, err := m.FindByDisplayNames(*device.DisplayName, displayNameWithClusterName)
5961
if err != nil {
6062
return nil, err
6163
}
62-
if oldDevice == nil {
63-
return nil, fmt.Errorf("can not find the device: %s", *device.DisplayName)
64+
if len(existingDevices) == 0 {
65+
return nil, fmt.Errorf("cannot find devices with name: %s", *device.DisplayName)
6466
}
65-
66-
// the device which is not changed will be ignored
67-
if *device.Name == *oldDevice.Name {
68-
log.Infof("No changes to device (%s). Ignoring update", *device.DisplayName)
69-
return device, nil
70-
}
71-
72-
// the device of the other cluster will be ignored
73-
oldClusterName := ""
74-
if oldDevice.CustomProperties != nil && len(oldDevice.CustomProperties) > 0 {
75-
for _, cp := range oldDevice.CustomProperties {
76-
if *cp.Name == constants.K8sClusterNamePropertyKey {
77-
oldClusterName = *cp.Value
67+
for _, existingDevice := range existingDevices {
68+
clusterName := m.GetPropertyValue(existingDevice, constants.K8sClusterNamePropertyKey)
69+
if clusterName == m.Config().ClusterName {
70+
// the device which is not changed will be ignored
71+
if *existingDevice.Name == *device.Name {
72+
log.Infof("No changes to device (%s). Ignoring update", *device.DisplayName)
73+
return device, nil
7874
}
75+
// the clusterName is the same and hostName is not the same, need update
76+
*device.DisplayName = *existingDevice.DisplayName
77+
newDevice, err2 := m.updateAndReplace(existingDevice.ID, device)
78+
if err2 != nil {
79+
return nil, err2
80+
}
81+
log.Infof("Updating existing device (%s)", *newDevice.DisplayName)
82+
return newDevice, nil
7983
}
8084
}
81-
if oldClusterName != m.Config().ClusterName {
82-
log.Infof("Device (%s) belongs to a different cluster (%s). Ignoring update", *device.DisplayName, oldClusterName)
83-
return device, nil
85+
// duplicate device exists. update displayName and re-add
86+
renamedDevice, err := m.renameAndAddDevice(device)
87+
if err != nil {
88+
log.Errorf("rename device failed: %v", err)
89+
return nil, fmt.Errorf("rename device failed")
8490
}
91+
return renamedDevice, nil
92+
}
8593

86-
newDevice, err := m.updateAndReplace(oldDevice.ID, device)
94+
// renameAndAddDevice rename display name and then add the device
95+
func (m *Manager) renameAndAddDevice(device *models.Device) (*models.Device, error) {
96+
resourceName := m.GetPropertyValue(device, constants.K8sResourceNamePropertyKey)
97+
if resourceName == "" {
98+
resourceName = *device.DisplayName
99+
}
100+
renameResourceName := fmt.Sprintf("%s-%s", resourceName, m.Config().ClusterName)
101+
existingDevice, err := m.FindByDisplayName(renameResourceName)
102+
if err != nil {
103+
log.Warnf("Get device(%s) failed, err: %v", resourceName, err)
104+
}
105+
if existingDevice != nil {
106+
if m.Config().ClusterName == m.GetPropertyValue(existingDevice, constants.K8sClusterNamePropertyKey) {
107+
device.DisplayName = existingDevice.DisplayName
108+
return m.updateAndReplace(existingDevice.ID, device)
109+
}
110+
return nil, fmt.Errorf("exist displayName: %s", renameResourceName)
111+
}
112+
log.Infof("Rename device: %s -> %s", *device.DisplayName, renameResourceName)
113+
device.DisplayName = &renameResourceName
114+
params := lm.NewAddDeviceParams()
115+
addFromWizard := false
116+
params.SetAddFromWizard(&addFromWizard)
117+
params.SetBody(device)
118+
restResponse, err := m.LMClient.LM.AddDevice(params)
87119
if err != nil {
88120
return nil, err
89121
}
90-
log.Infof("Finished updating the device: %s", *newDevice.DisplayName)
91-
return newDevice, nil
122+
return restResponse.Payload, nil
123+
}
124+
125+
// GetPropertyValue get device property value by property name
126+
func (m *Manager) GetPropertyValue(device *models.Device, propertyName string) string {
127+
if device == nil {
128+
return ""
129+
}
130+
if len(device.CustomProperties) > 0 {
131+
for _, cp := range device.CustomProperties {
132+
if *cp.Name == propertyName {
133+
return *cp.Value
134+
}
135+
}
136+
}
137+
if len(device.SystemProperties) > 0 {
138+
for _, cp := range device.SystemProperties {
139+
if *cp.Name == propertyName {
140+
return *cp.Value
141+
}
142+
}
143+
}
144+
return ""
92145
}
93146

94147
func (m *Manager) updateAndReplace(id int32, device *models.Device) (*models.Device, error) {
@@ -124,6 +177,37 @@ func (m *Manager) FindByDisplayName(name string) (*models.Device, error) {
124177
return nil, nil
125178
}
126179

180+
// FindByDisplayNames implements types.DeviceManager.
181+
func (m *Manager) FindByDisplayNames(displayNames ...string) ([]*models.Device, error) {
182+
if len(displayNames) == 0 {
183+
return []*models.Device{}, nil
184+
}
185+
filter := fmt.Sprintf("displayName:\"%s\"", strings.Join(displayNames, "\"|\""))
186+
params := lm.NewGetDeviceListParams()
187+
params.SetFilter(&filter)
188+
restResponse, err := m.LMClient.LM.GetDeviceList(params)
189+
if err != nil {
190+
return nil, err
191+
}
192+
log.Debugf("%#v", restResponse)
193+
return restResponse.Payload.Items, nil
194+
}
195+
196+
// FindByDisplayNameAndClusterName implements types.DeviceManager.
197+
func (m *Manager) FindByDisplayNameAndClusterName(displayName string) (*models.Device, error) {
198+
displayNameWithClusterName := fmt.Sprintf("%s-%s", displayName, m.Config().ClusterName)
199+
devices, err := m.FindByDisplayNames(displayName, displayNameWithClusterName)
200+
if err != nil {
201+
return nil, err
202+
}
203+
for _, device := range devices {
204+
if m.Config().ClusterName == m.GetPropertyValue(device, constants.K8sClusterNamePropertyKey) {
205+
return device, nil
206+
}
207+
}
208+
return nil, nil
209+
}
210+
127211
// Add implements types.DeviceManager.
128212
func (m *Manager) Add(options ...types.DeviceOption) (*models.Device, error) {
129213
device := buildDevice(m.Config(), m.ControllerClient, options...)
@@ -152,7 +236,6 @@ func (m *Manager) Add(options ...types.DeviceOption) (*models.Device, error) {
152236
return nil, err
153237
}
154238
log.Debugf("%#v", restResponse)
155-
156239
return restResponse.Payload, nil
157240
}
158241

@@ -166,7 +249,7 @@ func (m *Manager) UpdateAndReplaceByID(id int32, options ...types.DeviceOption)
166249

167250
// UpdateAndReplaceByDisplayName implements types.DeviceManager.
168251
func (m *Manager) UpdateAndReplaceByDisplayName(name string, options ...types.DeviceOption) (*models.Device, error) {
169-
d, err := m.FindByDisplayName(name)
252+
d, err := m.FindByDisplayNameAndClusterName(name)
170253
if err != nil {
171254
return nil, err
172255
}
@@ -175,7 +258,7 @@ func (m *Manager) UpdateAndReplaceByDisplayName(name string, options ...types.De
175258
log.Warnf("Could not find device %q", name)
176259
return nil, nil
177260
}
178-
261+
options = append(options, m.DisplayName(*d.DisplayName))
179262
// Update the device.
180263
device, err := m.UpdateAndReplaceByID(d.ID, options...)
181264
if err != nil {
@@ -210,7 +293,7 @@ func (m *Manager) UpdateAndReplaceFieldByID(id int32, field string, options ...t
210293

211294
// UpdateAndReplaceFieldByDisplayName implements types.DeviceManager.
212295
func (m *Manager) UpdateAndReplaceFieldByDisplayName(name string, field string, options ...types.DeviceOption) (*models.Device, error) {
213-
d, err := m.FindByDisplayName(name)
296+
d, err := m.FindByDisplayNameAndClusterName(name)
214297
if err != nil {
215298
return nil, err
216299
}
@@ -219,7 +302,7 @@ func (m *Manager) UpdateAndReplaceFieldByDisplayName(name string, field string,
219302
log.Infof("Could not find device %q", name)
220303
return nil, nil
221304
}
222-
305+
options = append(options, m.DisplayName(*d.DisplayName))
223306
// Update the device.
224307
device, err := m.UpdateAndReplaceFieldByID(d.ID, field, options...)
225308
if err != nil {
@@ -239,7 +322,7 @@ func (m *Manager) DeleteByID(id int32) error {
239322

240323
// DeleteByDisplayName implements types.DeviceManager.
241324
func (m *Manager) DeleteByDisplayName(name string) error {
242-
d, err := m.FindByDisplayName(name)
325+
d, err := m.FindByDisplayNameAndClusterName(name)
243326
if err != nil {
244327
return err
245328
}

pkg/device/device_test.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package device
2+
3+
import (
4+
"testing"
5+
6+
"github.com/logicmonitor/lm-sdk-go/models"
7+
)
8+
9+
func TestGetPropertyValue(t *testing.T) {
10+
deviceName := "test-device"
11+
12+
customPropertiesName1 := "name1"
13+
customPropertiesValue1 := "value1"
14+
customPropertiesName2 := "name2"
15+
customPropertiesValue2 := "value2"
16+
17+
systemPropertiesName1 := "system-name1"
18+
systemPropertiesValue1 := "system-value1"
19+
systemPropertiesName2 := "system-name2"
20+
systemPropertiesValue2 := "system-value2"
21+
22+
device := &models.Device{
23+
Name: &deviceName,
24+
DisplayName: &deviceName,
25+
CustomProperties: []*models.NameAndValue{
26+
{
27+
Name: &customPropertiesName1,
28+
Value: &customPropertiesValue1,
29+
}, {
30+
Name: &customPropertiesName2,
31+
Value: &customPropertiesValue2,
32+
},
33+
},
34+
SystemProperties: []*models.NameAndValue{
35+
{
36+
Name: &systemPropertiesName1,
37+
Value: &systemPropertiesValue1,
38+
}, {
39+
Name: &systemPropertiesName2,
40+
Value: &systemPropertiesValue2,
41+
},
42+
},
43+
}
44+
45+
manage := Manager{}
46+
value := manage.GetPropertyValue(device, customPropertiesName1)
47+
t.Logf("name=%s, value=%s", customPropertiesName1, value)
48+
value = manage.GetPropertyValue(device, systemPropertiesName2)
49+
t.Logf("name=%s, value=%s", systemPropertiesName2, value)
50+
value = manage.GetPropertyValue(device, "non-exist-name")
51+
t.Logf("name=%s, value=%s", "non-exist-name", value)
52+
}

pkg/sync/initsyncer.go

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -158,21 +158,19 @@ func (i *InitSyncer) syncDevices(resourceType string, resourcesMap map[string]st
158158
for _, device := range devices {
159159
// the "auto.clustername" property checking is used to prevent unexpected deletion of the normal non-k8s device
160160
// which may be assigned to the cluster group
161-
cps := device.CustomProperties
162-
autoClusterName := ""
163-
for _, cp := range cps {
164-
if *cp.Name == constants.K8sClusterNamePropertyKey {
165-
autoClusterName = *cp.Value
166-
break
167-
}
168-
}
161+
autoClusterName := i.DeviceManager.GetPropertyValue(device, constants.K8sClusterNamePropertyKey)
169162
if autoClusterName != i.DeviceManager.Config().ClusterName {
170163
log.Infof("Ignore the device (%v) which does not have property %v:%v",
171164
*device.DisplayName, constants.K8sClusterNamePropertyKey, i.DeviceManager.Config().ClusterName)
172165
continue
173166
}
174-
175-
_, exist := resourcesMap[*device.DisplayName]
167+
// the displayName may be renamed, we should use the constants.K8sResourceNamePropertyKey property value
168+
resourceName := i.DeviceManager.GetPropertyValue(device, constants.K8sResourceNamePropertyKey)
169+
// for compatibility, if resourceName is empty, use display name
170+
if resourceName == "" {
171+
resourceName = *device.DisplayName
172+
}
173+
_, exist := resourcesMap[resourceName]
176174
if !exist {
177175
log.Infof("Delete the non-exist %v device: %v", resourceType, *device.DisplayName)
178176
err := i.DeviceManager.DeleteByID(device.ID)

pkg/types/types.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ type DeviceMapper interface {
4141
// FindByDisplayName searches for a device by it's display name. It will return a device if and only if
4242
// one device was found, and return nil otherwise.
4343
FindByDisplayName(string) (*models.Device, error)
44+
// FindByDisplayNames searches for devices by the specified string by its display name. It will return the device list.
45+
FindByDisplayNames(...string) ([]*models.Device, error)
46+
// FindByDisplayNameAndClusterName searches for device by the specified string by its display name and clusterName. It will return a device if and only if
47+
FindByDisplayNameAndClusterName(string) (*models.Device, error)
4448
// Add adds a device to a LogicMonitor account.
4549
Add(...DeviceOption) (*models.Device, error)
4650
// UpdateAndReplaceByID updates a device using the 'replace' OpType.

pkg/watch/deployment/deployment.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ func (w *Watcher) args(deployment *v1beta2.Deployment, category string) []types.
127127
w.Auto("selflink", deployment.SelfLink),
128128
w.Auto("uid", string(deployment.UID)),
129129
w.Custom(constants.K8sResourceCreatedOnPropertyKey, strconv.FormatInt(deployment.CreationTimestamp.Unix(), 10)),
130+
w.Custom(constants.K8sResourceNamePropertyKey, fmtDeploymentDisplayName(deployment)),
130131
}
131132
}
132133

pkg/watch/node/node.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ func (w *Watcher) args(node *v1.Node, category string) []types.DeviceOption {
157157
w.Auto("selflink", node.SelfLink),
158158
w.Auto("uid", string(node.UID)),
159159
w.Custom(constants.K8sResourceCreatedOnPropertyKey, strconv.FormatInt(node.CreationTimestamp.Unix(), 10)),
160+
w.Custom(constants.K8sResourceNamePropertyKey, node.Name),
160161
}
161162
}
162163

pkg/watch/pod/pod.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ func (w *Watcher) args(pod *v1.Pod, category string) []types.DeviceOption {
157157
w.Auto("uid", string(pod.UID)),
158158
w.System("ips", pod.Status.PodIP),
159159
w.Custom(constants.K8sResourceCreatedOnPropertyKey, strconv.FormatInt(pod.CreationTimestamp.Unix(), 10)),
160+
w.Custom(constants.K8sResourceNamePropertyKey, pod.Name),
160161
}
161162
if pod.Spec.HostNetwork {
162163
options = append(options, w.Custom("kubernetes.pod.hostNetwork", "true"))

pkg/watch/service/service.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ func (w *Watcher) args(service *v1.Service, category string) []types.DeviceOptio
143143
w.Auto("selflink", service.SelfLink),
144144
w.Auto("uid", string(service.UID)),
145145
w.Custom(constants.K8sResourceCreatedOnPropertyKey, strconv.FormatInt(service.CreationTimestamp.Unix(), 10)),
146+
w.Custom(constants.K8sResourceNamePropertyKey, fmtServiceDisplayName(service)),
146147
}
147148
}
148149

0 commit comments

Comments
 (0)