EA for CrashPlan PROe (the 'e' matters...)

JPDyson
Valued Contributor

The available, pre-made Extension Attribute for CPP does not seem to work with PROe servers. I was wondering if anybody else had noticed this and tweaked their EA(s) to pull data from a PROe server. I'll buy you a beer!

36 REPLIES 36

appleconvert
New Contributor III

+ 1

msardes
New Contributor III

bump

JPDyson
Valued Contributor

For those still tuned in, I don't know if this ever got resolved. The API is different...

stevewood
Honored Contributor II
Honored Contributor II

I've been working on this some this morning, and yes, the API was changed. To get to the API viewer that shows the methods you can call, you can issue the following in a browser:

http://crashplanserver:4280/apidocviewer

The following article on the support site shows how to get there: http://www.crashplan.com/enterprise/support/doku.php/api

I've been able to fix the Status EA:

#!/bin/sh
CP_ServerAddress="your.crashplanserver.com"
CP_ServerPort="4280"
CP_AdminUsername="youradmin"
CP_AdminPassword="youradminpassword"

if [ "$CP_ServerAddress" == "" ] || [ "$CP_ServerPort" == "" ] || [ "$CP_AdminUsername" == "" ] || [ "$CP_AdminPassword" == "" ];then
    echo "<result>Please ensure all variables are set in the extension attribute script.</result>"
else
    if [ -f /Library/Application Support/CrashPlan/.identity ];then
        GUID=`/bin/cat /Library/Application Support/CrashPlan/.identity | grep guid | sed s/guid=//g`
        echo "<result>`/usr/bin/curl -u "$CP_AdminUsername":"$CP_AdminPassword" -k http://"$CP_ServerAddress":"$CP_ServerPort"/api/computers?guid="$GUID" | grep -w status | awk '{print $2}' | sed s/,//g | sed 's/.(.*)/1/' | sed 's/(.*)./1/'`</result>"
    else
        echo "<result>Not installed</result>"
    fi
fi

If you want to use HTTPS, just change the port number to 4285 and the curl line to https.

And the GUID EA should work as is since it is reading from a local file and not curling data from the server.

The rest of the EAs I've had problems getting to work. Code42 changed some of the method calls and it's difficult to get info like backupPercent, etc. I've got an email in to my sales rep to see if he can give me some help.

eric_hutter
New Contributor

Just wanted to let you guys know that we will be posting a set of EAs for CrashPlan PROe in the very near future.

Also, is anyone planning on using the Windows CrashPlan PROe scripts?

Chris
Valued Contributor
Just wanted to let you guys know that we will be posting a set of EAs for CrashPlan PROe in the very near future.

Amazing, can't wait for that!

pereljon
New Contributor III

Here are my scripts for this. Not to hard to change the current scripts to work with the new API. Enjoy and contribute!

Show state/status:
Shows Crashplan Pro E state. Shows additional error states.

#!/bin/sh
CP_ServerAddress="SERVERADDRESS
CP_ServerPort="4285"
CP_AdminUsername="ADMINUSER"
CP_AdminPassword="ADMINPASSWORD"

if [ "$CP_ServerAddress" == "" ] || [ "$CP_ServerPort" == "" ] || [ "$CP_AdminUsername" == "" ] || [ "$CP_AdminPassword" == "" ]; then
    echo "<result>Please ensure all variables are set in the extension attribute script.</result>"
elif [ -f /Library/Application Support/CrashPlan/.identity ]; then
    GUID=`/bin/cat /Library/Application Support/CrashPlan/.identity | grep guid | sed s/guid=//g`
    theReply=`/usr/bin/curl -s -u "$CP_AdminUsername":"$CP_AdminPassword" -G -d guid="$GUID" -k https://"$CP_ServerAddress":"$CP_ServerPort"/api/Computer`
    isActive=`echo "$theReply" | grep -w active | awk '{print $2}' | sed s/,//g`
    theState=`echo "$theReply" | grep -w alertStates | awk '{print $2}' | sed s/,//g | sed 's/..(.*)/1/' | sed 's/(.*)../1/'`
    theProcessList=`ps awx | grep CrashPlanService | grep -v grep`

    if [ "$GUID" == "" ]; then
        theResult="No GUID"
    elif [ "$theReply" == "" ]; then
        theResult="No reply"
    elif [ "$isActive" == "" ]; then
        theResult="Not registered"
    elif [ "$isActive" == "false" ]; then
        theResult="Not active"
    elif [ "$theState" == "" ]; then
        theResult="No state"
    elif [ "$theProcessList" == "" ]; then
        theResult="Not running"
    else
        theResult="$theState"
    fi
    echo "<result>$theResult</result>"
else
    echo "<result>Not installed</result>"
fi

Percentage complete:

#!/bin/sh
CP_ServerAddress="SERVERADDRESS"
CP_ServerPort="4285"
CP_AdminUsername="ADMINUSER"
CP_AdminPassword="ADMINPASSWORD"

if [ "$CP_ServerAddress" == "" ] || [ "$CP_ServerPort" == "" ] || [ "$CP_AdminUsername" == "" ] || [ "$CP_AdminPassword" == "" ];then
    echo "<result>Please ensure all variables are set in the extension attribute script.</result>"
else
    if [ -f /Library/Application Support/CrashPlan/.identity ];then
        GUID=`/bin/cat /Library/Application Support/CrashPlan/.identity | grep guid | sed s/guid=//g`
        server=`/usr/bin/curl -s -u "$CP_AdminUsername":"$CP_AdminPassword" -k -G -d websiteHost=https://"$CP_ServerAddress":"$CP_ServerPort" https://"$CP_ServerAddress":"$CP_ServerPort"/api/Server | grep destinationId | head -1 | awk '{print $2}' | sed s/,//g`
        totalSize=`/usr/bin/curl -s -u "$CP_AdminUsername":"$CP_AdminPassword" -G -d guid="$GUID" -d targetComputerId="$server" -k https://"$CP_ServerAddress":"$CP_ServerPort"/api/Archive | grep selectedBytes | head -1 | awk '{print $2}' | sed s/,//g`
        todo=`/usr/bin/curl -s -u "$CP_AdminUsername":"$CP_AdminPassword"  -G -d guid="$GUID" -d targetComputerId="$server" -k https://"$CP_ServerAddress":"$CP_ServerPort"/api/Archive | grep todoBytes | head -1 | awk '{print $2}' | sed s/,//g`
        if [ "$totalSize" == "" ] || [ "$todo" == "" ]; then
            echo "<result>Unknown.</result>"
            exit 0;
        fi
        done=`expr "$totalSize" - "$todo"`

        result=$( echo "scale=4; ($done / $totalSize) * 100" | bc | sed 's/(.*)../1/' )

        echo "<result>$result</result>"
    else
        echo "<result>Not installed</result>"
    fi
fi

Last connected:

#!/bin/sh
CP_ServerAddress="SERVERADDRESS"
CP_ServerPort="4285"
CP_AdminUsername="ADMINUSER"
CP_AdminPassword="ADMINPASSWORD"

if [ "$CP_ServerAddress" == "" ] || [ "$CP_ServerPort" == "" ] || [ "$CP_AdminUsername" == "" ] || [ "$CP_AdminPassword" == "" ];then
echo "Please ensure all variables are set in the extension attribute script."
else
if [ -f /Library/Application Support/CrashPlan/.identity ];then
    GUID=`/bin/cat /Library/Application Support/CrashPlan/.identity | grep guid | sed s/guid=//g`
    value=`/usr/bin/curl -s -u "$CP_AdminUsername":"$CP_AdminPassword" -G -d guid="$GUID" -k https://"$CP_ServerAddress":"$CP_ServerPort"/api/Computer | grep -w lastConnected | awk '{print $2}' | sed s/,//g | sed 's/.(.*)/1/'`
    result=`/bin/date -j -f "%Y-%m-%dT%H:%M:%S" "$value" "+%Y-%m-%d %H:%M:%S"`
    echo "<result>$result</result>"
else
    echo "<result>Not installed</result>"
fi
fi

Selected Files Size (GB)
I'm only showing in GB for sorting purposes. Just comment the final result and uncomment the if block otherwise.

#!/bin/sh
CP_ServerAddress="SERVERADDRESS"
CP_ServerPort="4285"
CP_AdminUsername="ADMINUSER"
CP_AdminPassword="ADMINPASSWORD"

if [ "$CP_ServerAddress" == "" ] || [ "$CP_ServerPort" == "" ] || [ "$CP_AdminUsername" == "" ] || [ "$CP_AdminPassword" == "" ];then
echo "<result>Please ensure all variables are set in the extension attribute script.</result>"
else
if [ -f /Library/Application Support/CrashPlan/.identity ];then
    GUID=`/bin/cat /Library/Application Support/CrashPlan/.identity | grep guid | sed s/guid=//g`
    server=`/usr/bin/curl -s -u "$CP_AdminUsername":"$CP_AdminPassword" -G -d websiteHost=https://"$CP_ServerAddress":"$CP_ServerPort" -k https://"$CP_ServerAddress":"$CP_ServerPort"/api/Server | grep destinationId | awk '{print $2}' | sed s/,//g`
    value=`/usr/bin/curl -s -u "$CP_AdminUsername":"$CP_AdminPassword" -G -d guid="$GUID" -d targetComputerId="$server" -k https://"$CP_ServerAddress":"$CP_ServerPort"/api/Archive | grep selectedBytes |  awk '{print $2}' | sed s/,//g`

    kilo=$( echo "scale=2; $value / 1024" | bc )
    kiloint=$( echo "$value / 1024" | bc )

    mega=$( echo "scale=2; $kilo / 1024" | bc )
    megaint=$( echo "$kilo / 1024" | bc )

    giga=$( echo "scale=2; $mega / 1024" | bc )
    gigaint=$( echo "$mega / 1024" | bc )

#   if [ $kiloint -lt 1 ] ; then
#       result="$value bytes"
#   elif [ $megaint -lt 1 ] ; then
#       result="${kilo} KB"
#   elif [ $gigaint -lt 1 ] ; then
#       result="${mega} MB"
#   else
#       result="${giga} GB"
#   fi

    result="${giga}"

    echo "<result>$result</result>"
else
    echo "<result>Not installed</result>"
fi
fi

GUID

#!/bin/sh
if [ -f /Library/Application Support/CrashPlan/.identity ];then
echo "<result>`/bin/cat /Library/Application Support/CrashPlan/.identity | grep guid | sed s/guid=//g`</result>"
else
echo "<result>Not installed</result>"
fi

jhbush
Valued Contributor II

I'm not having any luck with these EA's. I either get bad date formats or no useful information at all. The old one versions always worked well for me. Any ideas like bad forum text formatting?

eric_hutter
New Contributor

JAMF's CrashPlan PROe extension attributes have been upload to the nation.
You can check them out over here:https://jamfnation.jamfsoftware.com/viewProduct.html?id=217&view=extensionAttributes

jhbush
Valued Contributor II

Eric, most of those new EA's aren't working for me. Only the GUID which worked before.

stevewood
Honored Contributor II
Honored Contributor II

Jason you are running CrashPlanPROe and not CrashPlanPRO, right? I've got them loaded up and they are working great for me (thanks Eric!).

jhbush
Valued Contributor II

Steve, we are running the latest and greatest CrashPlan PROe. I get:

Failed conversion of ``'' using format ``%Y-%m-%dT%H:%M:%S''
date: illegal time format

and other strange errors.

eric_hutter
New Contributor

Hey Jason, I'd be interested in checking out the errors you're getting. Would you be up for a Web-ex on Monday?

jhbush
Valued Contributor II

Eric, I can do a webex Monday.

John_Wetter
Release Candidate Programs Tester

Eric, will there be a self-service plug-in coming also? Thanks for the EA's!

eric_hutter
New Contributor

John - There will indeed be a self-service plug-in. The code might be complete, and is perhaps going though some final testing...maybe...

eric_hutter
New Contributor

Just wanted everyone know that I've posted the CrashPlan PROe Self Service Plug-in over here:https://jamfnation.jamfsoftware.com/discussion.html?id=6592

... and here: https://jamfnation.jamfsoftware.com/discussion.html?id=6593

-10 for double post

pickerin
Contributor II

First post.

I too had issues with the "JAMF CrashPlan PROe extension attributes" posted by @eric.hutter. However, the ones in this thread posted by @pereljon work fine (though he gave us fewer of them). Looking through the differences, I noticed that @pereljon provided port numbers on his versions. The JAMF versions assume your server is running on Port 443 and if it's not, or if you have a redirect, they fail.

I'd love to get the official ones supported with a port number (4285 is the default for SSL on CrashPlan PROe). It's a trickier curl syntax, but would be a lot more flexible for different environments, like mine and others.

Thanks to @pereljon for taking the time to modify them in the first place to work with the new PROe API syntax, I may use his command syntax and the other non-working-for-me JAMF EAs and update them and post here.

eric_hutter
New Contributor

@pickerin

It's actually curl assuming port 443 because one wasn't provided. You can use 4285 by entering https://your-proe-sever:4285 as the address.

If you're having issues with redirects you can add '--location-trusted' to the curl command. This is the only way i know how to get curl to pass along the authentication information over a redirect. But according to curl's man page 'this may or may not introduce a security breach', so I didn't add it to the posted versions.

Chris
Valued Contributor

Looks like the latest CrashPlan update (3.5.5 to 3.6.1.2) broke most of the EAs...
For example,

curl -q -u "$CP_AdminUsername:$CP_AdminPassword" -k "$SERVER/api/Computer?guid=$GUID&incBackupUsage=1" | sed -n 's/.*archiveBytes": ([^,]*).*/1/p'

doesn't return anything.
Any sed wizards out there able to fix it? ;)

b3nn
New Contributor II

Ya mine ended up breaking too. I am still trying different things to sort out why it broke.

Anyone else have this issue?

Chris
Valued Contributor

Finally had some time to look into this.
Only AFTER i had built my own sed statement,
i figured out that there's just one extra space that has to be removed in the original EA.

For example in the Last Backup EA:

DATA=`curl -q -u "$CP_AdminUsername:$CP_AdminPassword" -k "$SERVER/api/Computer?guid=$GUID&incBackupUsage=1" | sed -n 's/.*lastBackup": "([^"]*).*/1/p'`

has to be changed to

DATA=`curl -q -u "$CP_AdminUsername:$CP_AdminPassword" -k "$SERVER/api/Computer?guid=$GUID&incBackupUsage=1" | sed -n 's/.*lastBackup":"([^"]*).*/1/p'`

Notice the space in lastBackup": " has to be removed: lastBackup":"
The other EAs need to be adjusted accordingly
This works with our CPPe 3.6.1.5 server.

clifhirtle
Contributor II

FWIW, getting very mixed results with these EAs, even after removing the colon space issue cited above or using pereljon's version or the official JN ones. For example:

Backup Percent Complete EA listed at https://jamfnation.jamfsoftware.com/viewProductFile.html?id=217&fid=623 with a CURL command listed below simply kicks back a blank $DATA value:

`curl -q -u "$CP_AdminUsername:$CP_AdminPassword" -k "$SERVER/api/Computer?guid=$GUID&incBackupUsage=1" | sed -n 's/.*percentComplete":"([^"]*).*/1/p'`

Meanwhile the Last Backup EA listed at: https://jamfnation.jamfsoftware.com/viewProductFile.html?id=217&fid=625 seems like more of just a basic formatting issue since it generates an "illegal time format" error on run with a CURL command below:

DATA=`curl -q -u "$CP_AdminUsername:$CP_AdminPassword" -k "$SERVER/api/Computer?guid=$GUID&incBackupUsage=1" | sed -n 's/.*lastBackup":"([^"]*).*/1/p'`        
        FORMATTED=`date -j -f "%Y-%m-%dT%H:%M:%S" "$DATA" "+%Y-%m-%d %H:%M:%S"`
        echo "<result>$FORMATTED</result>"

Chris
Valued Contributor

For Backup Percent Complete, try

`curl -q -u "$CP_AdminUsername:$CP_AdminPassword" -k "$SERVER/api/Computer?guid=$GUID&incBackupUsage=1" | sed -n 's/.*percentComplete":([^,]*).*/1/p'`

The Last Backup EA works for me as you quoted it.
Which version is your CPPe server?

clifhirtle
Contributor II

Thanks Chris. We're running v3.6.1.5.

Backup Complete seems to be working with that edit (which I could have sworn I had tried before), but other EAs may actually be related to some other kind of issue going on, since dumping out the entire GUID record via:

curl -q -u "$CP_AdminUsername:$CP_AdminPassword" -k "$SERVER/api/Computer?guid=$GUID&incBackupUsage=1"

Generates a variety of incorrect record values. For example here's what I'm seeing for last Backup/Completed/Connected:

"lastBackup":null,"lastCompletedBackup":null,"lastConnected":null,"lastMaintenanceDate":"2013-10-31T10:53:49.646-04:00","lastCompactDate":null

Chris
Valued Contributor

Yeah that's not how it's supposed to look...
Have you tried a different GUID? Maybe that one has never backed up.
Otherwise maybe have codefortytwo look into it?

clifhirtle
Contributor II

Mystery solved: turns out that CrashPlan can store a computer's .identity file in two different places, with our custom installer defaulting not to /Library/Application Support/CrashPlan/.identity, but rather ~/Library/Application Support/CrashPlan/.identity.

Reference:
http://support.code42.com/CrashPlan/Latest/Configuring/Computer_Identities_How_They_Work

Making matters worse, my test machine (having gone through multiple installs over our beta rollout) actually had .identity files in both places - so while the EA was reporting on the one in the /Library, the correct Computer ID file was resting in ~/Library. Nice!

So here's an updated EA script I put together that looks first in the /Library location, then falls back to ~/Library if there's nothing found there:

if [ "$CP_ServerAddress" == "" ] || [ "$CP_AdminUsername" == "" ] || [ "$CP_AdminPassword" == "" ];then
        echo "<result>Please ensure all variables are set in the extension attribute script.</result>"
elif [ -f /Library/Application Support/CrashPlan/.identity ] || [ -f ~/Library/Application Support/CrashPlan/.identity ];then
        SERVER=`echo $CP_ServerAddress | sed 's|/$||'`
        GUID=`cat /Library/Application Support/CrashPlan/.identity | sed -n  's/guid=//p'`
        if [ "$GUID" == "" ];then
            GUID=`cat ~/Library/Application Support/CrashPlan/.identity | sed -n 's/guid=//p'`
        fi        
        DATA=`curl -q -u "$CP_AdminUsername:$CP_AdminPassword" -k "$SERVER/api/Computer?guid=$GUID&incBackupUsage=1" | sed -n 's/.*percentComplete":([^,]*).*/1/p'`

        echo "<result>$DATA</result>" 
else
        echo "<result>Not installed</result>"
fi

bwilkins
New Contributor

Has anyone made any further discoveries?

djdavetrouble
Contributor III

I discovered that http://server.address.goes.here/api/computer?guid=$guid is deprecated, it is now: http://server.address.goes.here/api/Computer/$GUID?idType=guid

What I don't understand at all is the sed awk part or processing the json that it spits out.

djdavetrouble
Contributor III

curl -q -s -u user:pass -k "http://my.crashplan.server:port/api/Computer/$GUID?idType=guid" | python -m json.tool | grep -w status

returns

"status": "Active",

getting closer. Not sure where I got the flags from but one of them was to get rid of the status bar thingy. The API Doc viewer recommends curl -X GET, haven't tried that yet.

stevewood
Honored Contributor II
Honored Contributor II

@djdavetrouble I'm still able to get these EAs to complete with the deprecated method you mentioned, and even switching over to the new method, they still work. I'm using the following for each one:

Last Connected

#!/bin/sh
# Modified 1/24/13
# Third-Part Product page for CrashPlan PROe - https://jamfnation.jamfsoftware.com/viewProduct.html?id=217

CP_ServerAddress="https://yourcppeserver:4285"
CP_AdminUsername="cppadmin"
CP_AdminPassword='cpppassword'

if [ "$CP_ServerAddress" == "" ] || [ "$CP_AdminUsername" == "" ] || [ "$CP_AdminPassword" == "" ];then
        echo "<result>Please ensure all variables are set in the extension attribute script.</result>"
elif [ -f /Library/Application Support/CrashPlan/.identity ];then
        SERVER=`echo $CP_ServerAddress | sed 's|/$||'`
        GUID=`cat /Library/Application Support/CrashPlan/.identity | sed -n 's/guid=//p'`

        DATA=`curl -q -u ${CP_AdminUsername}:${CP_AdminPassword} -k "$SERVER/api/Computer/$GUID?idType=guid&incBackupUsage=1" | sed -n 's/.*lastConnected":"([^"]*).*/1/p'`        

        FORMATTED=`date -j -f "%Y-%m-%dT%H:%M:%S" "$DATA" "+%Y-%m-%d %H:%M:%S"`
        echo "<result>$FORMATTED</result>"
else
        echo "<result>Not installed</result>"
fi

Last Backup

#!/bin/sh
# Modified 1/24/13
# Third-Part Product page for CrashPlan PROe - https://jamfnation.jamfsoftware.com/viewProduct.html?id=217

CP_ServerAddress="https://yourcppeserver:4285"
CP_AdminUsername="cppadmin"
CP_AdminPassword='cpppassword'

if [ "$CP_ServerAddress" == "" ] || [ "$CP_AdminUsername" == "" ] || [ "$CP_AdminPassword" == "" ];then
        echo "<result>Please ensure all variables are set in the extension attribute script.</result>"
elif [ -f /Library/Application Support/CrashPlan/.identity ];then
        SERVER=`echo $CP_ServerAddress | sed 's|/$||'`
        GUID=`cat /Library/Application Support/CrashPlan/.identity | sed -n 's/guid=//p'`

        DATA=`curl -q -u ${CP_AdminUsername}:${CP_AdminPassword} -k "$SERVER/api/Computer/$GUID?idType=guid&incBackupUsage=1" | sed -n 's/.*lastBackup":"([^"]*).*/1/p'`        

        FORMATTED=`date -j -f "%Y-%m-%dT%H:%M:%S" "$DATA" "+%Y-%m-%d %H:%M:%S"`
        echo "<result>$FORMATTED</result>"
else
        echo "<result>Not installed</result>"
fi

Status

#!/bin/sh
# Modified 1/24/13
# Third-Part Product page for CrashPlan PROe - https://jamfnation.jamfsoftware.com/viewProduct.html?id=217
CP_ServerAddress="https://yourcppeserver:4285"
CP_AdminUsername="cppadmin"
CP_AdminPassword='cpppassword'

if [ "$CP_ServerAddress" == "" ] || [ "$CP_AdminUsername" == "" ] || [ "$CP_AdminPassword" == "" ];then
        echo "<result>Please ensure all variables are set in the extension attribute script.</result>"
elif [ -f /Library/Application Support/CrashPlan/.identity ];then
        SERVER=`echo $CP_ServerAddress | sed 's|/$||'`
        GUID=`cat /Library/Application Support/CrashPlan/.identity | sed -n 's/guid=//p'`

        DATA=`curl -q -u ${CP_AdminUsername}:${CP_AdminPassword} -k "$SERVER/api/Computer/$GUID?idType=guid" | sed -n 's/.*status":"([^"]*).*/1/p'`

        echo "<result>$DATA</result>"
else
        echo "<result>Not installed</result>"
fi

I just tested all three of these and they appear to be working correctly.

djdavetrouble
Contributor III

Thanks Steve, are you running the latest server version? I inherited the EAs, and figured I'd poke into the API and see what changed. I have a working curl that uses the new syntax, and am going to work it into an EA tomorrow.

stevewood
Honored Contributor II
Honored Contributor II

@djdavetrouble We are running version 5.1.2.

djdavetrouble
Contributor III

here is the working curl with the new API syntax

sudo curl -X GET -s -u api_user:password -k "http://my.crashplan.server:port/api/Computer/$GUID?idType=guid" | python -m json.tool | grep -w status | awk '{print $2}' | sed -e 's/^"//g' | sed -e 's/",$//g'

I tried using the less frowned upon python -c json.load but kept getting errors so gave up and did this instead.

This returns the string "Active"

djdavetrouble
Contributor III

We are using 5.2.0 and the old ones are not working for me, in particular, the Computer call does not have information on last connected or percentage complete.

djdavetrouble
Contributor III

New EA's for CrashPlan 5.2 Posted here:
https://jamfnation.jamfsoftware.com/discussion.html?id=19962