-
Notifications
You must be signed in to change notification settings - Fork 217
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
HTTP Error does not prevent restapi_object state from being updated #152
Comments
This is a big issue as 400+ errors should indicate that no changes were made, hence the state should not be updated. There might be cases where this is not the case, but that would be the exception rather than the norm. |
Hey there, @jollyroger - I'm embarrassed by the delay responding. Somehow I opened this report marking it as 'read' in GitHub... but I never actually READ it! I will have to work on a reproduction recipe for this to triage - totally agreed that 4xx errors would indicate the request was never accepted by the API so a state change wouldn't make sense. If you have a handy way to make this easily reproducible (maybe with fakeserver), let me know and it can shortcut some of the process :-) |
Hi there, |
Hi @DRuggeri , sorry to keep you waiting, here are two files for you to test this case. terraform {
required_providers {
restapi = {
source = "Mastercard/restapi"
}
}
}
provider "restapi" {
uri = "http://localhost:8000"
debug = false
write_returns_object = true
id_attribute = "id"
}
resource "random_uuid" "uuid" {count = 2}
resource "restapi_object" "redis_db" {
path = "/objects"
update_path = "/objects/{id}"
data = jsonencode({"property" = random_uuid.uuid[0].result})
} This is a terraform file I'm using. By changing Here's a server code written in Python. You'd need to install few Python packages first by running #!/usr/bin/env python3
import io
import bottle
import json
from bottle_sqlite import SQLitePlugin
bottle.install(SQLitePlugin(dbfile="db.sqlite"))
app = application = bottle.default_app()
@app.route('/db/init')
def populate(db):
db.execute("CREATE TABLE IF NOT EXISTS objects(id INT PRIMARY KEY, data BLOB)")
bottle.response.status = 200
bottle.response.headers['Content-Type'] = 'application/json'
return json.dumps({'status':'ok', 'description':'Database initialized'})
@app.route('/objects', method=['GET'])
def list_items(db):
res = db.execute("SELECT ROWID, DATA from objects")
bottle.response.status = 200
bottle.response.headers['Content-Type'] = 'application/json'
columns = ["id", "data"]
return json.dumps([dict(zip(columns, tuple(row))) for row in res])
@app.route('/objects', method=['POST'])
def create_item(db):
wrapper = io.TextIOWrapper(bottle.request.body, encoding='utf-8')
new_data = wrapper.read()
res = db.execute("INSERT INTO objects(data) VALUES(?)", (new_data,))
return get_item(db, res.lastrowid)
@app.route('/objects/<object_id:int>', method=['GET'])
def get_item(db, object_id):
res = db.execute("SELECT ROWID, DATA from objects where ROWID = ?", (object_id,))
row = tuple(res.fetchone())
columns = ["id", "data"]
bottle.response.status = 200 if len(row) > 0 else 404
bottle.response.headers['Content-Type'] = 'application/json'
return json.dumps(dict(zip(columns, tuple(row))))
@app.route('/objects/<object_id:int>', method=['PUT'])
def update_item(db, object_id):
try:
new_data = bottle.request.json
if new_data is None or "property" not in new_data:
raise ValueError
except ValueError:
bottle.response.status = 406
# ^^^^^ Update HTTP Error Code here ^^^^^
return json.dumps({'status':'ko', 'description': 'Malformed JSON Object'})
wrapper = io.TextIOWrapper(bottle.request.body, encoding='utf-8')
new_data = wrapper.read()
res = db.execute("UPDATE objects SET data = ? WHERE ROWID = ?", (new_data, object_id))
return get_item(db, object_id)
if __name__ == '__main__':
bottle.run(app, host = '127.0.0.1', port = 8000) |
Sorry, forgot to add steps to reproduce:
-data = jsonencode({"property" = random_uuid.uuid[0].result})
+data = jsonencode({"new_property" = random_uuid.uuid[0].result})
Expected result:
|
Applying the workaround from hashicorp/terraform-plugin-sdk#476 in the PR above. I also verified the change with terraform v1.6.3 and v1.7.5 in a similar way to what @jollyroger suggested. |
This issue has been around for quite some time and it's occasionally causing problems to us. A review for the fix would be greatly appreciated. I'm not sure who is the right person to ping but judging by the commit activity, maybe @DRuggeri ? |
This is awesome, @ugur-zongur - thank you for the PR! Merging now! |
As noted in the PR feedback, I plan to release this soon along with the fix for #231 - massive thank you for the PR and for validating the fix in your local environment, @ugur-zongur ! |
Hi! First of all, thanks for your great work! I'm facing an issue when HTTP API call fails due to an error(HTTP 406). Usually this means the change was not applied and I'd be happy to update object properties and run
terraform apply
again to retry. But during second run terraform shows that no changes will be applied becauserestapi_object
resource state was already updated during previous run.Is there any way to prevent state update in case of HTTP Error?
Version info:
The text was updated successfully, but these errors were encountered: