Skip to content

Commit 2e0e88a

Browse files
authored
Cope with faulty configs (name or id is null) (#169)
It can happen that you have a faulty config deployed in your environment, which has no id or name set. These special cases were not handled correctly before. Instead, `monaco` crashed when getting the list of configs. This commit introduces a graceful handling of these configs t monaco. If the id is null -> Return an error If the name is null -> Fill in the id as the name (as done by the extensions API)
1 parent 79d93fd commit 2e0e88a

File tree

2 files changed

+103
-3
lines changed

2 files changed

+103
-3
lines changed

pkg/rest/config_upload.go

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,11 @@ func unmarshalJson(theApi api.Api, err error, resp Response, values []api.Value,
232232
}
233233

234234
if available, array := isResultArrayAvailable(objmap, theApi); available {
235-
values = append(values, translateGenericValues(array)...)
235+
genericValues, err := translateGenericValues(array, theApi.GetId())
236+
if err != nil {
237+
return err, values
238+
}
239+
values = append(values, genericValues...)
236240
}
237241

238242
} else {
@@ -262,17 +266,41 @@ func isPaginatedResponse(jsonResponse map[string]interface{}) (paginated bool, p
262266
return false, ""
263267
}
264268

265-
func translateGenericValues(inputValues []interface{}) []api.Value {
269+
func translateGenericValues(inputValues []interface{}, configType string) ([]api.Value, error) {
270+
266271
numValues := len(inputValues)
267272
values := make([]api.Value, numValues, numValues)
273+
268274
for i := 0; i < numValues; i++ {
269275
input := inputValues[i].(map[string]interface{})
276+
277+
if input["id"] == nil {
278+
return values, fmt.Errorf("config of type %s was invalid: No id", configType)
279+
}
280+
281+
// repair invalid configs - but log them
282+
if input["name"] == nil {
283+
jsonStr, err := json.Marshal(input)
284+
if err != nil {
285+
util.Log.Warn("Config of type %s was invalid. Ignoring it!", configType)
286+
continue
287+
}
288+
289+
util.Log.Warn("Config of type %s was invalid. Auto-corrected to use ID as name!\nInvalid config: %s", configType, string(jsonStr))
290+
291+
values[i] = api.Value{
292+
Id: input["id"].(string),
293+
Name: input["id"].(string), // use the id as name
294+
}
295+
continue
296+
}
297+
270298
values[i] = api.Value{
271299
Id: input["id"].(string),
272300
Name: input["name"].(string),
273301
}
274302
}
275-
return values
303+
return values, nil
276304
}
277305

278306
func translateSyntheticValues(syntheticValues []api.SyntheticValue) []api.Value {

pkg/rest/config_upload_test.go

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// +build unit
2+
3+
/**
4+
* @license
5+
* Copyright 2020 Dynatrace LLC
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
package rest
20+
21+
import (
22+
"gotest.tools/assert"
23+
"testing"
24+
)
25+
26+
func TestTranslateGenericValuesOnStandardResponse(t *testing.T) {
27+
28+
entry := make(map[string]interface{})
29+
entry["id"] = "foo"
30+
entry["name"] = "bar"
31+
32+
response := make([]interface{}, 1)
33+
response[0] = entry
34+
35+
values, err := translateGenericValues(response, "extensions")
36+
37+
assert.NilError(t, err)
38+
assert.Check(t, len(values) == 1)
39+
40+
assert.Equal(t, values[0].Id, "foo")
41+
assert.Equal(t, values[0].Name, "bar")
42+
}
43+
44+
func TestTranslateGenericValuesOnIdMissing(t *testing.T) {
45+
46+
entry := make(map[string]interface{})
47+
entry["name"] = "bar"
48+
49+
response := make([]interface{}, 1)
50+
response[0] = entry
51+
52+
_, err := translateGenericValues(response, "extensions")
53+
54+
assert.ErrorContains(t, err, "config of type extensions was invalid: No id")
55+
}
56+
57+
func TestTranslateGenericValuesOnNameMissing(t *testing.T) {
58+
59+
entry := make(map[string]interface{})
60+
entry["id"] = "foo"
61+
62+
response := make([]interface{}, 1)
63+
response[0] = entry
64+
65+
values, err := translateGenericValues(response, "extensions")
66+
67+
assert.NilError(t, err)
68+
assert.Check(t, len(values) == 1)
69+
70+
assert.Equal(t, values[0].Id, "foo")
71+
assert.Equal(t, values[0].Name, "foo")
72+
}

0 commit comments

Comments
 (0)