Skip to content

Commit

Permalink
POST /v1/objects: allow array of attrs to undo modifications of
Browse files Browse the repository at this point in the history
  • Loading branch information
Al2Klimov committed Jun 13, 2023
1 parent a3dabde commit c498794
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 7 deletions.
40 changes: 37 additions & 3 deletions doc/12-icinga2-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -890,9 +890,15 @@ curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \
Existing objects must be modified by sending a `POST` request. The following
parameters need to be passed inside the JSON body:

Parameters | Type | Description
-----------|------------|---------------------------
attrs | Dictionary | **Required.** Set specific object attributes for this [object type](09-object-types.md#object-types).
| Parameters | Type | Description |
|----------------|------------|----------------------------------------------------------------------------------------------------------------------------|
| attrs | Dictionary | **Optional.** Set specific object attributes for this [object type](09-object-types.md#object-types). |
| restore\_attrs | Array | **Optional.** Discard modifications of specific object attributes for this [object type](09-object-types.md#object-types). |

!!! info

If a particular attribute is given in both sets,
it's first restored and then set to the desired new value.

In addition to these parameters a [filter](12-icinga2-api.md#icinga2-api-filters)
parameter should be provided.
Expand Down Expand Up @@ -936,6 +942,34 @@ curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \
}
```

To undo such modifications to specific object attributes,
list the latter in the `restore_attrs` parameter. E.g.:

```bash
curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \
-X POST 'https://localhost:5665/v1/objects/hosts/example.localdomain' \
-d '{ "restore_attrs": [ "address", "vars.os" ] }, "pretty": true }'
```

```json
{
"results": [
{
"code": 200.0,
"name": "example.localdomain",
"status": "Attributes updated.",
"type": "Host"
}
]
}
```

Giving `attrs` with the original value would have almost the same effect.
But in this case Icinga would still store that value as a modified attribute,
overriding DSL/Director config (changes). In contrast, `restore_attrs` tells
Icinga to actually forget particular modified attributes, so that changes to
them via Director or plain config are effective again.

### Deleting Objects <a id="icinga2-api-config-objects-delete"></a>

You can delete objects created using the API by sending a `DELETE`
Expand Down
48 changes: 44 additions & 4 deletions lib/remote/modifyobjecthandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ bool ModifyObjectHandler::HandleRequest(

Value attrsVal = params->Get("attrs");

if (attrsVal.GetReflectionType() != Dictionary::TypeInstance) {
if (attrsVal.GetReflectionType() != Dictionary::TypeInstance && attrsVal.GetType() != ValueEmpty) {
HttpUtility::SendJsonError(response, params, 400,
"Invalid type for 'attrs' attribute specified. Dictionary type is required."
"Or is this a POST query and you missed adding a 'X-HTTP-Method-Override: GET' header?");
Expand All @@ -73,6 +73,23 @@ bool ModifyObjectHandler::HandleRequest(

Dictionary::Ptr attrs = attrsVal;

Value restoreAttrsVal = params->Get("restore_attrs");

if (restoreAttrsVal.GetReflectionType() != Array::TypeInstance && restoreAttrsVal.GetType() != ValueEmpty) {
HttpUtility::SendJsonError(response, params, 400,
"Invalid type for 'restore_attrs' attribute specified. Array type is required.");
return true;
}

Array::Ptr restoreAttrs = restoreAttrsVal;

if (!(attrs || restoreAttrs)) {
HttpUtility::SendJsonError(response, params, 400,
"Missing both 'attrs' and 'restore_attrs'. "
"Or is this a POST query and you missed adding a 'X-HTTP-Method-Override: GET' header?");
return true;
}

bool verbose = false;

if (params)
Expand All @@ -95,6 +112,26 @@ bool ModifyObjectHandler::HandleRequest(

String key;

try {
if (restoreAttrs) {
ObjectLock oLock (restoreAttrs);

for (auto& attr : restoreAttrs) {
key = attr;
obj->RestoreAttribute(key);
}
}
} catch (const std::exception& ex) {
result1->Set("code", 500);
result1->Set("status", "Attribute '" + key + "' could not be restored: " + DiagnosticInformation(ex, false));

if (verbose)
result1->Set("diagnostic_information", DiagnosticInformation(ex));

results.push_back(std::move(result1));
continue;
}

try {
if (attrs) {
ObjectLock olock(attrs);
Expand All @@ -103,17 +140,20 @@ bool ModifyObjectHandler::HandleRequest(
obj->ModifyAttribute(kv.first, kv.second);
}
}

result1->Set("code", 200);
result1->Set("status", "Attributes updated.");
} catch (const std::exception& ex) {
result1->Set("code", 500);
result1->Set("status", "Attribute '" + key + "' could not be set: " + DiagnosticInformation(ex, false));

if (verbose)
result1->Set("diagnostic_information", DiagnosticInformation(ex));

results.push_back(std::move(result1));
continue;
}

result1->Set("code", 200);
result1->Set("status", "Attributes updated.");

results.push_back(std::move(result1));
}

Expand Down

0 comments on commit c498794

Please sign in to comment.