ControlSystemStudio / phoebus

A framework and set of tools to monitor and operate large scale control systems, such as the ones in the accelerator community.
http://phoebus.org/
Eclipse Public License 1.0
92 stars 89 forks source link

Save and Restore 405 Error on Delete #3172

Closed kathryn-baker closed 3 weeks ago

kathryn-baker commented 3 weeks ago

I am trying to modify some code that interacts with the save and restore service via Python using the requests library. I am working in Docker, running the save and restore service with the following configuration / start up script.

bash -c "wait-for-it elastic:9200 -t 0 && sleep 30 && java -Delasticsearch.network.host=elastic -Delasticsearch.http.port=9200 -Dspring.config.location=/service-save-and-restore/application.properties -jar /service-save-and-restore/service-save-and-restore.jar"

Where applications.properties is as follows:

logging.level.org.springframework=DEBUG
app.version=@project.version@
app.name=@project.artifactId@

# The server port for the rest service
server.port=8080

# Elasticsearch connection parameters
elasticsearch.network.host=localhost
elasticsearch.http.port=9200

# Do not change this!
spring.jackson.serialization.write-dates-as-timestamps=false

server.servlet.contextPath=/save-restore

# The names of the index to use for save&restore
elasticsearch.tree_node.index=saveandrestore_tree
elasticsearch.configuration_node.index=saveandrestore_configuration
elasticsearch.snapshot_node.index:saveandrestore_snapshot
elasticsearch.composite_snapshot_node.index:saveandrestore_composite_snapshot
elasticsearch.filter.index:saveandrestore_filter

############################## REST Logging ###############################
# DEBUG level will log all requests and responses to and from the REST end points
logging.level.org.springframework.web.filter.CommonsRequestLoggingFilter=INFO

# Mapping of static resources. Needed as otherwise the web front-end (if present) will intercept and fail to
# serve a resource like for instance SearchHelp.html
spring.mvc.static-path-pattern=/**

############## AD - External ##############
ad.enabled = false
ad.url = ldap://127.0.0.1
ad.domain = test.com

############## LDAP - External ##############
# If uncommenting in this section, make sure
# to comment out in LDAP - Embedded section
#############################################
#ldap.urls=ldaps://ldap-cslab.cslab.esss.lu.se
#ldap.base.dn = dc=esss,dc=lu,dc=se
#ldap.user.search.base=
# User search pattern, e.g. uid={0},ou=People. No default value as LDAP environment may not
# support user search by pattern.
#ldap.user.dn.pattern=uid={0},ou=Users
# User search filter, e.g. (&(objectClass=person)(SAMAccountName={0})). No default value as LDAP environment
# may not support user search by filter.
#ldap.user.search.filter=
#ldap.groups.search.base = ou=Groups
#ldap.groups.search.pattern = (memberUid= {1})
# dn of manager account, may be required for group search
ldap.manager.dn=
# password of account
ldap.manager.password=

############## LDAP - Embedded ##############
# If uncommenting in this section, make sure
# to comment out in LDAP - External section
#############################################
ldap.urls=ldap://localhost:8389/dc=sar,dc=local
ldap.base.dn = dc=sar,dc=local
ldap.user.dn.pattern = uid={0},ou=Group
ldap.groups.search.base = ou=Group
ldap.groups.search.pattern = (memberUid= {1})
spring.ldap.embedded.ldif=classpath:sar.ldif
spring.ldap.embedded.base-dn=dc=sar,dc=local
spring.ldap.embedded.port=8389 
spring.ldap.embedded.validation.enabled=false

############## Demo credentials ##############
demo.user=user
demo.user.password=userPass
demo.admin=admin
demo.admin.password=adminPass
demo.readOnly=johndoe
demo.readOnly.password=1234

############## Authentication Implementation ##############
# Supported options:
# ad - Microsoft AD
# ldap - Probably Open LDAP
# ldap_embedded - Embedded LDAP. Config in sar.ldif
# demo - Hard coded, see WebSecurityConfig class
auth.impl = demo

###### Bypass authorization (but not authentication!) #######
authorization.permitall = true

############## Authorization Roles ################

# role.user=sar-user
role.admin=sar-admin

I believe this means I should have minimal authentication required as this is purely a test environment, not production.

However, when trying to delete a node using the following commands:

r = requests.delete('http://service-save-and-restore:8080/save-restore/node/{nodeid}', auth=('admin', 'adminPass'))
r.status_code

I get a 405 status code, suggesting that the delete method is not allowed.

Is there something missing in the configuration file that is preventing the deletion?

The version of the save-and-restore service was built from the Phoebus repo yesterday (21st October 2024) and I am running a python:3.11-slim container with save and restore built using openjdk:22-jdk-slim and elasticsearch 8.12.0

Thanks for your help 😄

georgweiss commented 3 weeks ago

I'm afraid the documentation lags behind a bit. I will update as soon as possible, but in the meanwhile: Delete endpoint is http://service-save-and-restore:8080/save-restore/node, but you need to send a body containing a list of the node ids to be deleted, e.g. ["id_1","id_2"]

I am aware that a body with DELETE is discouraged :-).

There are more updates to the documentation pending, e.g. the return value from /restore/node.

kathryn-baker commented 3 weeks ago

Thanks, that's worked! I can delete the nodes with this function now :)

def delete_folder(settings: dict, node_id: NodeId):
    r = requests.delete(settings["save_restore_url"], auth=(settings["username"], settings["password"]), json=[node_id])
    r.raise_for_status()

Does this apply to the other endpoints like PUT and POST etc as well or just DELETE?

georgweiss commented 3 weeks ago

Difficult to answer with yes/no... On top of the (somewhat crippled) documentation, there is also the Swagger UI which by definition should be correct: http://service-save-and-restore:8080/swagger-ui/index.html

kathryn-baker commented 3 weeks ago

Thanks, I'll have a look through the swagger UI to see if I can find what I need, that looks very useful.

Just to correct the link to save anyone else confusion, the swagger UI docs are actually at http://service-save-and-restore:8080/save-restore/swagger-ui/index.html with the additional save-restore in the middle

georgweiss commented 3 weeks ago

You are right, by default /save-restore needs to be there in the URL, but this is configurable. We use just / as context root.

georgweiss commented 3 weeks ago

Can we close this?

kathryn-baker commented 3 weeks ago

Yep this can be closed, thanks again!