This is a near identical guide to the awesome work of @Gordon_Geist I have used the same text as the original and only changed bits I needed to.
I couldnt quite get the original tutorial to work, so I had a go at it and I have made some adjustments and tuning of the same solution
-
This is just for device policies
-
Uses Python instead of BASH
-
It uses just one exec binding thing
-
It supports passing mac addresses and policies
-
It supports standard policies (normal,blocked,whitelisted)
-
I used the Meraki API namespace instead of dashboard
My use case is:
- Allow my wife/rules to turn off streaming content and similar when our kids should get back to the real world
- set up Cron rules to change policies based on time of day - Meraki only allows you to set a “day” period meaning if I block the kids at 10.30pm - 11:59pm, at midnight they can get back up and go nuts on youtube till 10.30pm the next day
You should know how to manipulate your linux environment and secure your installation along with good RBAC controls to your configs.
DevicePolicy.items
- Create items to manipulate/display in the sitemap.
//Device Policy
String Policy_Jackson "Jackson Laptop"
String Policy_Hamish "Hamish Laptop"
Things
I do all my things in PaperUI, so add a new Command thing from the exec binding
Exec.items
- Maraki has three default policies Normal, Blocked and Whitelisted then your group policies are exposed in order of creation by 102,103, etc - u can find the # of your policy by editing the policy within the Meraki portal and looking at the url in your browser:
//Device Policy change
String ExecMerakiDevicePolicyChange_Output "Output" {channel="exec:command:ExecMerakiDevicePolicyChange:output"}
String ExecMerakiDevicePolicyChange_Input "Input" {channel="exec:command:ExecMerakiDevicePolicyChange:input"}
Number ExecMerakiDevicePolicyChange_Exit "Exit Value" {channel="exec:command:ExecMerakiDevicePolicyChange:exit"}
Switch ExecMerakiDevicePolicyChange_Run "Running" {channel="exec:command:ExecMerakiDevicePolicyChange:run"}
DateTime ExecMerakiDevicePolicyChange_Lastexecution "Last Execution" {channel="exec:command:ExecMerakiDevicePolicyChange:lastexecution"}
Devicepolicy.rules
- Rules to implement changes when a new policy is selected via the sitemap. This could be shortened by the bash script using multiple variables but just havent gotten around to changing it (hint hint)
- MAC address substituted here for each device you want to control by policy. MAC is right there in the Meraki portal -copy paste
note the sendCommand the format is macaddress|policy The exec binding only supports sending one parameter so I seperate with a pipe and split it in the receiving script
////////////////////
//Policy_Jackson
/////////////////////
rule "Policy_Jackson Actions"
when Item Policy_Jackson changed
then
if (Policy_Jackson.state == "norm") {
ExecMerakiDevicePolicyChange_Input.sendCommand("ff:ff:ff:ff:ff:ff|Normal")
ExecMerakiDevicePolicyChange_Run.sendCommand(ON)
}
if (Policy_Jackson.state == "block") {
ExecMerakiDevicePolicyChange_Input.sendCommand("ff:ff:ff:ff:ff:ff|Blocked")
ExecMerakiDevicePolicyChange_Run.sendCommand(ON)
}
if (Policy_Jackson.state == "white") {
ExecMerakiDevicePolicyChange_Input.sendCommand("ff:ff:ff:ff:ff:ff|Whitelisted")
ExecMerakiDevicePolicyChange_Run.sendCommand(ON)
}
if (Policy_Jackson.state == "p_103") {
ExecMerakiDevicePolicyChange_Input.sendCommand("ff:ff:ff:ff:ff:ff|103")
ExecMerakiDevicePolicyChange_Run.sendCommand(ON)
}
if (Policy_Jackson.state == "p_104") {
ExecMerakiDevicePolicyChange_Input.sendCommand("ff:ff:ff:ff:ff:ff|104")
ExecMerakiDevicePolicyChange_Run.sendCommand(ON)
}
end
//rinse repeat for all devices
Home.sitemap
- Simple to make this pin code protected but thats out of scope here
Group item=Device_Policy_Group {
Switch item=Policy_Jackson mappings=[norm="Norm",block="Block",white="White",p_103="No Youtube",p_104="Homework"]
}
Python script
- The exec item sends the MAC address and policy as the variable
- < NetworkID > is your Network ID that contains the Meraki devices you are managing.Read the Meraki API manual
- <api_key> is the unique api-key for your organization and received after you apply for api access. Consider this as important as securing your root access password i.e. where the script is and the users/groups that can read.
- You just need to change these two variables and the rest is taken care of
- I found the application postman really useful to find out how to get the script to work (and better debugging - this application also allows you to export as various formats.
Postman application
Postman Meraki Collection
meraki1.py
import requests, sys
strMacaddress,strPolicy = sys.argv[1].split("|")
strNetworkID = "<NetworkID>"
strAPIKey = "<api_key>"
url = "https://api.meraki.com/api/v0/networks/" + strNetworkID + "/clients/" + strMacaddress +"/policy"
headers = {
'Content-Type': "application/json",
'X-Cisco-Meraki-API-Key': "" + strAPIKey + "",
}
if strPolicy == "Normal" or strPolicy == "Blocked" or strPolicy == "Whitelisted":
payload = "{\n \"devicePolicy\": \"" + strPolicy + "\"\n}"
else:
payload = "{\n \"devicePolicy\": \"group\",\n \"type\": \"Group policy\",\n \"groupPolicyId\": \"" + strPolicy + "\"\n}"
response = requests.request("PUT", url, data=payload, headers=headers)