You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
# TODO:: we can remove this once there is a tenant_id field on modules
###############################################################################################before_action:can_read,only: [:index,:show]before_action:can_write,only: [:create,:update,:destroy,:remove]before_action:check_admin,except: [:index,:state,:show,:ping]before_action:check_support,only: [:state,:show,:ping]###############################################################################################
@[AC::Route::Filter(:before_action,except: [:index,:create])]deffind_current_module(id : String)Log.context.set(module_id: id)# Find will raise a 404 (not found) if there is an error@current_module=Model::Module.find!(id)endgetter!current_module : Model::Module# Permissions###############################################################################################
@[AC::Route::Filter(:before_action,only: [:index])]defcheck_view_permissionsreturnifuser_support?# find the org zoneauthority=current_authority.as(Model::Authority)@org_zone_id=org_zone_id=authority.config["org_zone"]?.try(&.as_s?)raiseError::Forbidden.newunlessorg_zone_idaccess=check_access(current_user.groups,[org_zone_id])raiseError::Forbidden.newunlessaccess.admin?
endgetterorg_zone_id : String? =nil# Response helpers###############################################################################################recordControlSystemDetails,name : String,zone_data : Array(Model::Zone)doincludeJSON::SerializableendrecordDriverDetails,name : String,description : String?,module_name : String?doincludeJSON::Serializableend# extend the ControlSystem model to handle our return valuesclassModel::Module
@[JSON::Field(key: "driver")]propertydriver_details : Api::Modules::DriverDetails?= nil
propertycompiled : Bool? = nil
@[JSON::Field(key: "control_system")]propertycontrol_system_details : Api::Modules::ControlSystemDetails?= nil
end################################################################################################ return a list of modules configured on the cluster
@[AC::Route::GET("/")]defindex(
@[AC::Param::Info(description: "only return modules updated before this time (unix epoch)")]as_of : Int64? = nil,
@[AC::Param::Info(description: "only return modules running in this system (query params are ignored if this is provided)",example: "sys-1234")]control_system_id : String? = nil,
@[AC::Param::Info(description: "only return modules with a particular connected state",example: "true")]connected : Bool? = nil,
@[AC::Param::Info(description: "only return instances of this driver",example: "driver-1234")]driver_id : String? = nil,
@[AC::Param::Info(description: "do not return logic modules (return only modules that can exist in multiple systems)",example: "true")]no_logic : Bool=false,
@[AC::Param::Info(description: "return only running modules",example: "true")]running : Bool? = nil
) : Array(Model::Module)# if a system id is present we query the database directlyifcontrol_system_idcs=Model::ControlSystem.find!(control_system_id)# Include subset of association data with resultsresults=Model::Module.find_all(cs.modules).compact_mapdo |mod|
nextif(driver=mod.driver).nil?# Most human readable module data is contained in drivermod.driver_details=DriverDetails.new(driver.name,driver.description,driver.module_name)mod.compiled=Api::Modules.driver_compiled?(mod,request_id)modend.to_aset_collection_headers(results.size,Model::Module.table_name)returnresultsend# we use Elasticsearchelastic=Model::Module.elasticquery=elastic.query(search_params)query.minimum_should_match(1)# TODO:: we can remove this once there is a tenant_id field on modules# which will make this much simpler to filteriffilter_zone_id=org_zone_id# we only want to show modules in use by systems that include this zoneno_logic=true# find all the non-logic modules that this user can access# 1. grabs all the module ids in the systems of the provided org zone# 2. select distinct modules ids which are not logic modules (99)sql_query=%[ WITH matching_rows AS ( SELECT unnest(modules) AS module_id FROM sys WHERE $1 = ANY(zones) ) SELECT ARRAY_AGG(DISTINCT m.module_id) FROM matching_rows m JOIN mod ON m.module_id = mod.id WHERE mod.role <> 99; ]module_ids=PgORM::Database.connectiondo |conn|
conn.query_one(sql_query,args: [filter_zone_id], &.read(Array(String)))endquery.must({"id"=>module_ids,})endifno_logicquery.must_not({"role"=>[Model::Driver::Role::Logic.to_i]})endifdriver_idquery.filter({"driver_id"=>[driver_id]})endunlessconnected.nil?query.filter({"ignore_connected"=>[false],"connected"=>[connected],})endunlessrunning.nil?query.should({"running"=>[running]})endifas_ofquery.range({"updated_at"=>{:lte=>as_of,},})endquery.has_parent(parent: Model::Driver,parent_index: Model::Driver.table_name)search_results=paginate_results(elastic,query)# Include subset of association data with resultssearch_results.compact_mapdo |d|
sys=d.control_systemdriver=d.drivernextunlessdriver# Include control system on Logic modules so it is possible# to display the inherited settingssys_field=ifsysControlSystemDetails.new(sys.name,Model::Zone.find_all(sys.zones).to_a)elsenilendd.control_system_details=sys_fieldd.driver_details=DriverDetails.new(driver.name,driver.description,driver.module_name)dendend# return the details of a module
@[AC::Route::GET("/:id")]defshow(
@[AC::Param::Info(description: "return the driver details along with the module?",example: "true")]complete : Bool=false) : Model::Moduleifcomplete && (driver=current_module.driver)current_module.driver_details=DriverDetails.new(driver.name,driver.description,driver.module_name)current_moduleelsecurrent_moduleendend# update the details of a module
@[AC::Route::PATCH("/:id",body: :mod)]
@[AC::Route::PUT("/:id",body: :mod)]defupdate(mod : Model::Module) : Model::Modulecurrent=current_modulecurrent.assign_attributes(mod)raiseError::ModelValidation.new(current.errors)unlesscurrent.saveifdriver=current.drivercurrent.driver_details=DriverDetails.new(driver.name,driver.description,driver.module_name)endcurrentend# add a new module / instance of a driver
@[AC::Route::POST("/",body: :mod,status_code: HTTP::Status::CREATED)]defcreate(mod : Model::Module) : Model::ModuleraiseError::ModelValidation.new(mod.errors)unlessmod.savemodend# remove a module
@[AC::Route::DELETE("/:id",status_code: HTTP::Status::ACCEPTED)]defdestroy : Nilcurrent_module.destroyend# Receive the collated settings for a module
@[AC::Route::GET("/:id/settings")]defsettings : Array(PlaceOS::Model::Settings)Api::Settings.collated_settings(current_user,current_module)end# Starts a module
@[AC::Route::POST("/:id/start")]defstart : Nilreturnifcurrent_module.running == truecurrent_module.update_fields(running: true)# Changes cleared on a successful updateifcurrent_module.running_changed?Log.error{{controller: "Modules",action: "start",module_id: current_module.id,event: "failed"}}raise"failed to update database to start module #{current_module.id}"endend# Stops a module
@[AC::Route::POST("/:id/stop")]defstop : Nilreturnunlesscurrent_module.runningcurrent_module.update_fields(running: false)# Changes cleared on a successful updateifcurrent_module.running_changed?Log.error{{controller: "Modules",action: "stop",module_id: current_module.id,event: "failed"}}raise"failed to update database to stop module #{current_module.id}"endend# Executes a command on a module# The `/systems/` route can be used to introspect modules for the list of methods and argument requirements
@[AC::Route::POST("/:id/exec/:method",body: :args)]defexecute(id : String,
@[AC::Param::Info(description: "the name of the methodm we want to execute")]method : String,
@[AC::Param::Info(description: "the arguments we want to provide to the method")]args : Array(JSON::Any)) : Nilsys_id=current_module.control_system_id || ""result,status_code=Driver::Proxy::RemoteDriver.new(module_id: id,sys_id: sys_id,module_name: current_module.name,discovery: self.class.core_discovery,user_id: current_user.id,){ |module_id|
Model::Module.find!(module_id).edge_id.as(String)}.exec(security: driver_clearance(user_token),function: method,args: args,request_id: request_id,)# customise the response based on the execute resultsresponse.content_type="application/json"rendertext: result,status: status_coderescuee : Driver::Proxy::RemoteDriver::Error
The text was updated successfully, but these errors were encountered:
which will make this much simpler to filter
grabs all the module ids in the systems of the provided org zone
select distinct modules ids which are not logic modules (99)
to display the inherited settings
to display the inherited settings
get("/:id/settings", :settings) do
rest-api/src/placeos-rest-api/controllers/modules.cr
Line 114 in e912723
The text was updated successfully, but these errors were encountered: