Code Monkey home page Code Monkey logo

spruce's Introduction

JSSImporter processor for AutoPkg

Deprecation Notice

This project is deprecated and is likely to stop functioning with upcoming versions of Jamf Pro. Please consider using JamfUploader instead.

Instructions for use

For details on how to use JSSImporter, please visit our Wiki.

Acknowledgements

Huge thanks to Shea Craig, who wrote the bulk of this work. Later versions were produced by Graham Pugh, who now maintains JamfUploader.

License

See the LICENSE file.

spruce's People

Contributors

grahampugh avatar homebysix avatar mscottblake avatar sheagcraig avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

spruce's Issues

UnicodeEncodeError: 'ascii' codec can't encode characters in position 7-8: ordinal not in range(128)

Seeing this post ElCap update on my iMac:

/Users/ega/Documents/Projects/Spruce-2.0.0/spruce.py -t > ./policies.txt
Traceback (most recent call last):
File "/Users/ega/Documents/Projects/Spruce-2.0.0/spruce.py", line 1931, in
main()
File "/Users/ega/Documents/Projects/Spruce-2.0.0/spruce.py", line 1927, in main
run_reports(args)
File "/Users/ega/Documents/Projects/Spruce-2.0.0/spruce.py", line 1757, in run_reports
print_output(report, args.verbose)
File "/Users/ega/Documents/Projects/Spruce-2.0.0/spruce.py", line 1379, in print_output
print "\t%s" % line
UnicodeEncodeError: 'ascii' codec can't encode characters in position 7-8: ordinal not in range(128)

SSL: WRONG_VERSION_NUMBER

I ran this a while back and had no issues.

For the life of my i can't figure out what is happening. Anytime I try and run this script i get the following:

๐ŸŒฒ Building: Computer Groups Report... ๐ŸŒฒ
Traceback (most recent call last):
File "/Users/dennis/Desktop/spruce.py", line 2001, in
main()
File "/Users/dennis/Desktop/spruce.py", line 1997, in main
run_reports(args)
File "/Users/dennis/Desktop/spruce.py", line 1792, in run_reports
results.append(func(**args_dict))
File "/Users/dennis/Desktop/spruce.py", line 901, in build_computer_groups_report
group_list = jss_connection.ComputerGroup()
File "/Library/Python/2.7/site-packages/jss/jamf_software_server.py", line 566, in ComputerGroup
return self.factory.get_object(jssobjects.ComputerGroup, data)
File "/Library/Python/2.7/site-packages/jss/jamf_software_server.py", line 875, in get_object
return self.get_list(obj_class, data, subset)
File "/Library/Python/2.7/site-packages/jss/jamf_software_server.py", line 901, in get_list
result = self.jss.get(url)
File "/Library/Python/2.7/site-packages/jss/jamf_software_server.py", line 200, in get
response = self.session.get(request_url)
File "/Library/Python/2.7/site-packages/requests/sessions.py", line 525, in get
return self.request('GET', url, **kwargs)
File "/Library/Python/2.7/site-packages/requests/sessions.py", line 512, in request
resp = self.send(prep, **send_kwargs)
File "/Library/Python/2.7/site-packages/requests/sessions.py", line 622, in send
r = adapter.send(request, **kwargs)
File "/Library/Python/2.7/site-packages/requests/adapters.py", line 511, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host='casper.mycompany.com', port=8443): Max retries exceeded with url: /JSSResource/computergroups (Caused by SSLError(SSLError(1, u'[SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:590)'),))

Receiving "Instances of 'NoneType'" error message when running spruce

I am also getting errors when running jss_helper as well that seem like they may be related to this.

When I run spruce, here is the output I receive:

lcacioppo@CSI361362 Desktop % /usr/local/autopkg/python ~/Desktop/spruce.py   
JSS: https://jamf-pro-url:8443
Preferences used: ~/Library/Preferences/com.github.autopkg.plist
*  Building: Computer Report... *
Traceback (most recent call last):
  File "/Users/lcacioppo/Desktop/spruce.py", line 2436, in <module>
    main()
  File "/Users/lcacioppo/Desktop/spruce.py", line 2432, in main
    run_reports(args)
  File "/Users/lcacioppo/Desktop/spruce.py", line 2187, in run_reports
    results.append(func(**args_dict))
  File "/Users/lcacioppo/Desktop/spruce.py", line 650, in build_computers_report
    report = build_device_report(check_in_period, all_computers)
  File "/Users/lcacioppo/Desktop/spruce.py", line 448, in build_device_report
    ) = get_version_and_model_spread(devices)
  File "/Users/lcacioppo/Desktop/spruce.py", line 601, in get_version_and_model_spread
    strings = sorted(get_histogram_strings(model_counts, padding=8), key=model_compare)
TypeError: '<' not supported between instances of 'NoneType' and 'str'

PreStage Enrollment Packages detected as unused

I recently ran a Spruce report and noticed that one of our PreStage Enrollment Packages (to install Rosetta 2) was picked up as being unused.

The package was not in use in any policies, only in the PreStage.

Not a major problem as we only have a few PreStage Enrollment Packages, but has the potential to cause issues if reports are not reviewed closely. Would be a 'nice to have' if it could also scan the PreStage.

Thanks

Request: Exclude Smart Groups that include Groups that are scoped

When I run Spruce against my smart groups, I may get something like the example below.

Group "All Laptops" is not used in scoping.

When I go to delete "All Laptops" I am told that it is in use in another group called "Department Encrypted".

"Department Encrypted" IS used in policies so it didn't show up on the list. But since "All Laptops" helps to create the group "Department Encrypted", it is technically required to stay in order for the scoped group to keep working.

It would be nice if Spruce could account for this linkage.

Thanks! Love Spruce so much.

Testing branch - Mobile apps report fails due to requests module not imported

Just trying the Testing branch (db4ce4c) and when either running all reports or just the mobile apps report (-b, --apps) I get the following:

iMac:Spruce jwrn3 % ./spruce.py -b
JSS: https://jss.blah.com:8443
Preferences used: ~/Library/Preferences/com.github.autopkg.plist
๐ŸŒฒ  Building: Mobile Apps... ๐ŸŒฒ
Traceback (most recent call last):
  File "./spruce.py", line 2054, in <module>
    main()
  File "./spruce.py", line 2050, in main
    run_reports(args)
  File "./spruce.py", line 1829, in run_reports
    results.append(func(**args_dict))
  File "./spruce.py", line 1201, in build_apps_report
    session = requests.session()
NameError: global name 'requests' is not defined

All other reports are fine.

UnboundLocalError when using a specified prefs file

Running
/usr/local/autopkg/python spruce.py --prefs edu.umn.oit.spruce.plist --scripts

results in
UnboundLocalError: local variable 'connection' referenced before assignment

Here is the traceback
Traceback (most recent call last): File "spruce.py", line 2249, in <module> main() File "spruce.py", line 2236, in main connect(args) File "spruce.py", line 2219, in connect JSSConnection.setup(connection)

Additional error catching in the IF block on line 2389 will fix the traceback and can provide additional information about how to provide the file location.

Something like:

        else:
            print("Unable to find file " + str(args.prefs))
            print("Add prefs file location like ~/Library/Preferences/com.company.preferences.plist")
            sys.exit()

Few Errors

screen shot 2019-01-10 at 14 30 24

Get the above when I try and run Spruce?

Option to remove Casper Remote one-off policies

When running a Casper Remote task, a policy object is created. This policy does not show up in the web ui, but does remain in the object db.

I'll add a command to search for these and allow you to clean them.

AttributeError: 'Element' object has no attribute 'getchildren'

Unable to run any of the commands besides -h as I always receive this error. python-jss 2.1.0 is installed and I have replicated the same error across multiple machines (Big Sur and Catalina)

Any suggestions? Screenshot of the entire output is attached.

Screenshot 2021-04-16 at 12 33 26

Confused about SSL

So I want to do some spruce reporting from individual JSS machines in a pool (i.e. hit their ip directly)
Made sure there was just python-jss defaults:
ls ~/Library/Preferences/com.github*
~/Library/Preferences/com.github.GitHub.LSSharedFileList.plist
~/Library/Preferences/com.github.sheagcraig.JSSRecipeCreator.plist
~/Library/Preferences/com.github.GitHub.plist
~/Library/Preferences/com.github.sheagcraig.python-jss.plist

Even overloaded the preferences file with different syntax for SSL verify:

defaults read ~/Library/Preferences/com.github.sheagcraig.python-jss.plist
{
"JSS_VERIFY_SSL" = 0;
"jss_pass" = "uwish!";
"jss_url" = "https://107.23.24.212:443/";
"jss_user" = audit;
"ssl_verify" = 0;
}

Then I get this below. So am I confused ? I get the name and the cert don't match but don't care.

/Desktop/Spruce-testing/spruce.py --packages
๐ŸŒฒ Building: Package Report... ๐ŸŒฒ
Traceback (most recent call last):
File "
/Desktop/Spruce-testing/spruce.py", line 1668, in
main()
File "/Desktop/Spruce-testing/spruce.py", line 1664, in main
run_reports(args)
File "
/Desktop/Spruce-testing/spruce.py", line 1611, in run_reports
results.append(func(*_args_dict))
File "~/Desktop/Spruce-testing/spruce.py", line 781, in build_packages_report
all_policies = jss_connection.Policy().retrieve_all(
File "/Library/Python/2.7/site-packages/jss/jss.py", line 440, in Policy
return self.factory.get_object(Policy, data, subset)
File "/Library/Python/2.7/site-packages/jss/jss.py", line 525, in get_object
result = self.jss.get(url)
File "/Library/Python/2.7/site-packages/jss/jss.py", line 232, in get
response = self.session.get(request_url)
File "/Library/Python/2.7/site-packages/requests-2.7.0-py2.7.egg/requests/sessions.py", line 477, in get
return self.request('GET', url, *_kwargs)
File "/Library/Python/2.7/site-packages/requests-2.7.0-py2.7.egg/requests/sessions.py", line 465, in request
resp = self.send(prep, *_send_kwargs)
File "/Library/Python/2.7/site-packages/requests-2.7.0-py2.7.egg/requests/sessions.py", line 573, in send
r = adapter.send(request, _kwargs)
File "/Library/Python/2.7/site-packages/requests-2.7.0-py2.7.egg/requests/adapters.py", line 431, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: hostname '107.23.24.212' doesn't match either of '
.jamfcloud.com', 'jamfcloud.com'

Getting packages not listed in my jss

When I run this I get packages in the output that aren't listed in my jss, then if I try and run it to remove them all I get errors.
Are there perhaps packages I'm not seeing for some reason?

The error is
./Spruce.py --remove output.txt
Traceback (most recent call last):
File "./Spruce.py", line 367, in
main()
File "./Spruce.py", line 363, in main
remove(j, removal_set)
File "./Spruce.py", line 220, in remove
j.distribution_points.delete(item)
File "/Library/Python/2.7/site-packages/python_jss-1.2.0-py2.7.egg/jss/distribution_points.py", line 246, in delete
repo.delete(filename)
File "/Library/Python/2.7/site-packages/python_jss-1.2.0-py2.7.egg/jss/distribution_points.py", line 870, in delete
self.connection['jss'].Package(filename).delete()
File "/Library/Python/2.7/site-packages/python_jss-1.2.0-py2.7.egg/jss/jss.py", line 421, in Package
return self.factory.get_object(Package, data)
File "/Library/Python/2.7/site-packages/python_jss-1.2.0-py2.7.egg/jss/jss.py", line 524, in get_object
xmldata = self.jss.get(url)
File "/Library/Python/2.7/site-packages/python_jss-1.2.0-py2.7.egg/jss/jss.py", line 231, in get
self._error_handler(JSSGetError, response)
File "/Library/Python/2.7/site-packages/python_jss-1.2.0-py2.7.egg/jss/jss.py", line 185, in _error_handler
raise exception
jss.exceptions.JSSGetError: Response Code: 404 Response: Not Found. The server has not found anything matching the request URI

Error not returned if error.status_code does not exist

During testing, I encountered a situation in which there was no status_code attribute in the JSSError object, and as a result the error message was never printed. In this case, it was caused by the existence of a &#22; character within the run_command section of a policy to be removed.

I worked around this by skipping the error.status_code output, but there may be a better way. PR incoming.

Results list uppercase before lowercase

The report results list the scripts and packages that begin with an uppercase letter alphabetically, and then list the scripts and packages that begin with a lowercase letter alphabetically. For example:

########## Unused scripts:
Alpha.sh
Bravo.py
Delta.rb
Golf.sh
India.sh
Lima.py
Tango.sh
Yankee.py
charlie.sh
echo.py
hotel.py
oscar.rb
romeo.js
uniform.py
xray.sh
zulu.py

It would be better, I think, if the scripts were listed in alphabetical order regardless of capitalization. For example:

########## Unused scripts:
Alpha.sh
Bravo.py
charlie.sh
Delta.rb
echo.py
Golf.sh
hotel.py
India.sh
Lima.py
oscar.rb
romeo.js
Tango.sh
uniform.py
xray.sh
Yankee.py
zulu.py

Error deleting packages

My master DP is a JDS. There are other File Share DPs, but the configured option is that JDS. I do it this way because I have automated processes to distribute content to the other shares and it's faster than uploading from my client machine.

I am getting the following when I try to remove packages:

computername:Spruce username$ ./spruce.py --remove removals.xml
Are you sure you want to continue deleting objects from https://casper.domain.com? (Y or N): y
Package object 1887: Adobe Shockwave Player-12.2.3r183.pkg deleted.
Traceback (most recent call last):
  File "./spruce.py", line 1931, in <module>
    main()
  File "./spruce.py", line 1925, in main
    remove(removal_tree)
  File "./spruce.py", line 1875, in remove
    jss_connection.distribution_points.delete(item.text)
  File "/Library/Python/2.7/site-packages/python_jss-1.4.0-py2.7.egg/jss/distribution_points.py", line 273, in delete
  File "/Library/Python/2.7/site-packages/python_jss-1.4.0-py2.7.egg/jss/distribution_point.py", line 730, in delete
  File "/Library/Python/2.7/site-packages/python_jss-1.4.0-py2.7.egg/jss/jamf_software_server.py", line 589, in Package
  File "/Library/Python/2.7/site-packages/python_jss-1.4.0-py2.7.egg/jss/jamf_software_server.py", line 736, in get_object
  File "/Library/Python/2.7/site-packages/python_jss-1.4.0-py2.7.egg/jss/jamf_software_server.py", line 811, in get_individual_object
  File "/Library/Python/2.7/site-packages/python_jss-1.4.0-py2.7.egg/jss/jamf_software_server.py", line 202, in get
  File "/Library/Python/2.7/site-packages/python_jss-1.4.0-py2.7.egg/jss/tools.py", line 87, in error_handler
jss.exceptions.JSSGetError: Response Code: 404  Response: Not Found. The server has not found anything matching the request URI

It does remove the package properly, but only does one then fails.

I was looking through the code and it looks like it's polling the JSS for its DPs rather than look at what is configured. Unfortunately, I don't know enough to actually fix it.

Check for usage in Configurations as well...

This is really an enhancement I think. I got feedback from several of my Casper Site admins that they had 10s to 100s of packages that are used only in Casper Configurations and not policies. Our folks would be interested in packages and scripts that are not used in anything (policy, configuration, whatever).

does not work with SSO enabled

followed all the guides, used before in the past no issue. OS 10.12.4 beta 5

tim.kimpton$ python /Users/tim.kimpton/Downloads/Spruce-master/spruce.py --packages -o cruftypackages.xml
๐ŸŒฒ Building: Package Report... ๐ŸŒฒ
Traceback (most recent call last):
File "/Users/tim.kimpton/Downloads/Spruce-master/spruce.py", line 1955, in
main()
File "/Users/tim.kimpton/Downloads/Spruce-master/spruce.py", line 1951, in main
run_reports(args)
File "/Users/tim.kimpton/Downloads/Spruce-master/spruce.py", line 1747, in run_reports
results.append(func(**args_dict))
File "/Users/tim.kimpton/Downloads/Spruce-master/spruce.py", line 732, in build_packages_report
subset=["general", "package_configuration", "packages"])
File "/Library/Python/2.7/site-packages/jss/jssobjectlist.py", line 179, in retrieve_all
in self]
File "/Library/Python/2.7/site-packages/jss/jssobjectlist.py", line 66, in id
return int(self["id"])
File "/Library/Python/2.7/site-packages/jss/jssobjectlist.py", line 38, in getitem
return self.store[key]
KeyError: 'id'

Computer groups are reported as "unused" even if they are used for Restricted Software

If a computer group is used in Restricted Software (either as a target or as an exclusion), Spruce doesn't omit it from the Unused section of its computer groups report.

Here's the relevant section of the Restricted Software API result:

<restricted_software>
  <general>
    <id>24</id>
    <name>Restrict 10.13 Developer Beta</name>
    <process_name>Install macOS 10.13 Beta.app</process_name>
    <match_exact_process_name>true</match_exact_process_name>
    <send_notification>false</send_notification>
    <kill_process>true</kill_process>
    <delete_executable>false</delete_executable>
    <display_message>High Sierra is not certified to be compatible with software on your Mac. Please contact the Help Desk for assistance.</display_message>
    <site>
      <id>-1</id>
      <name>None</name>
    </site>
  </general>
  <scope>
    <all_computers>false</all_computers>
    <computers/>
    <computer_groups>
      <computer_group>
        <id>79</id>
        <name>Has High Sierra-incompatible software</name>
      </computer_group>
    </computer_groups>
    <buildings/>
    <departments/>
    <exclusions>
      <computers/>
      <computer_groups>
        <computer_group>
          <id>392</id>
          <name>10.13 Early Access Allowed</name>
        </computer_group>
      </computer_groups>
      <buildings/>
      <departments/>
      <users/>
    </exclusions>
  </scope>
</restricted_software>

Issues with JSSConnection

New install. Testing both Sprice 2.0.1 and 3.0.0.b1.

JSSImporter 1.05 configured through AutoPKGR, appears to be working as expected.

When running Spruce, recieving the following errors:

Spruce 2.0.1:

Spruce-2.0.1 % ./spruce.py Traceback (most recent call last): File "./spruce.py", line 1955, in <module> main() File "./spruce.py", line 1942, in main JSSConnection.setup(connection) File "./spruce.py", line 207, in setup cls._jss = jss.JSS(**cls._jss_prefs) File "/Library/Python/2.7/site-packages/python_jss-1.5.0-py2.7.egg/jss/jamf_software_server.py", line 144, in __init__ self.distribution_points = distribution_points.DistributionPoints(self) File "/Library/Python/2.7/site-packages/python_jss-1.5.0-py2.7.egg/jss/distribution_points.py", line 89, in __init__ dpt = self._get_auto_configured_dp(repo) File "/Library/Python/2.7/site-packages/python_jss-1.5.0-py2.7.egg/jss/distribution_points.py", line 140, in _get_auto_configured_dp jss=self.jss) File "/Library/Python/2.7/site-packages/python_jss-1.5.0-py2.7.egg/jss/distribution_point.py", line 563, in __init__ self.is_mounted() File "/Library/Python/2.7/site-packages/python_jss-1.5.0-py2.7.egg/jss/distribution_point.py", line 301, in is_mounted valid_mount_strings = self._get_valid_mount_strings() File "/Library/Python/2.7/site-packages/python_jss-1.5.0-py2.7.egg/jss/distribution_point.py", line 379, in _get_valid_mount_strings ip_address = socket.gethostbyname(url) socket.gaierror: [Errno 8] nodename nor servname provided, or not known

Similar error with Spruce 3.0:

Spruce-3.0.0b1 % ./spruce.py JSS: <Jamf-hosted JSS URL> Preferences used: ~/Library/Preferences/com.github.autopkg.plist Traceback (most recent call last): File "./spruce.py", line 2054, in <module> main() File "./spruce.py", line 2041, in main connect(args) File "./spruce.py", line 2024, in connect JSSConnection.setup(connection) File "./spruce.py", line 210, in setup cls._jss = jss.JSS(**cls._jss_prefs) File "/Library/Application Support/JSSImporter/jss/jamf_software_server.py", line 203, in __init__ self.distribution_points = DistributionPoints(self) File "/Library/Application Support/JSSImporter/jss/distribution_points.py", line 89, in __init__ dpt = self._get_auto_configured_dp(repo) File "/Library/Application Support/JSSImporter/jss/distribution_points.py", line 152, in _get_auto_configured_dp jss=self.jss) File "/Library/Application Support/JSSImporter/jss/distribution_point.py", line 528, in __init__ self.is_mounted() File "/Library/Application Support/JSSImporter/jss/distribution_point.py", line 289, in is_mounted valid_mount_strings = self._get_valid_mount_strings() File "/Library/Application Support/JSSImporter/jss/distribution_point.py", line 367, in _get_valid_mount_strings ip_address = socket.gethostbyname(url) socket.gaierror: [Errno 8] nodename nor servname provided, or not known

Using a service account with full read permissions.

Testing Branch - seeing encoding error

So with:
defaults read com.github.autopkg
2015-08-28 10:03:45.945 defaults[45503:11294452]
Domain com.github.autopkg does not exist
and
defaults read com.github.sheagcraig.python-jss.plist jss_url
https://nc.jamfcloud.com:443/
I get an encode error on testing branch.

/Desktop/Spruce-testing/spruce.py --apps -v
๐ŸŒฒ Building: Mobile Apps... ๐ŸŒฒ
Traceback (most recent call last):
File "/Users/ega/Desktop/Spruce-testing/spruce.py", line 1798, in
main()
File "/Users/ega/Desktop/Spruce-testing/spruce.py", line 1794, in main
run_reports(args)
File "/Users/ega/Desktop/Spruce-testing/spruce.py", line 1731, in run_reports
results.append(func(*_args_dict))
File "/Users/ega/Desktop/Spruce-testing/spruce.py", line 1147, in build_apps_report
page = session.get(external_url).text
File "/Library/Python/2.7/site-packages/requests-2.7.0-py2.7.egg/requests/sessions.py", line 477, in get
return self.request('GET', url, *_kwargs)
File "/Library/Python/2.7/site-packages/requests-2.7.0-py2.7.egg/requests/sessions.py", line 451, in request
prep = self.prepare_request(req)
File "/Library/Python/2.7/site-packages/requests-2.7.0-py2.7.egg/requests/sessions.py", line 382, in prepare_request
hooks=merge_hooks(request.hooks, self.hooks),
File "/Library/Python/2.7/site-packages/requests-2.7.0-py2.7.egg/requests/models.py", line 304, in prepare
self.prepare_url(url, params)
File "/Library/Python/2.7/site-packages/requests-2.7.0-py2.7.egg/requests/models.py", line 362, in prepare_url
to_native_string(url, 'utf8')))
requests.exceptions.MissingSchema: Invalid URL '': No schema supplied. Perhaps you meant http://?

No pkgs removed, am I stupid or is it not working with v10 cloud?

I've tried spruce to clean out old autopkg-pkgs that's now outdated, but it doesn't seem to do anything.

Am I doing something fundamentally wrong, or is it not working with a Jamf Pro v10 cloud?

Below is a log from my shell doing step-by-step, finishing with a diff of a run before and after --remove.

19:50:56 [jonasb:~/src/div/Spruce] master 1 ยฑ ./spruce.py -p -o /tmp/pkgs
๐ŸŒฒ  Building: Package Report... ๐ŸŒฒ
๐ŸŒฒ  Wrote output to /tmp/pkgs
19:51:13 [jonasb:~/src/div/Spruce] master ยฑ ./spruce.py --remove /tmp/pkgs
Are you sure you want to continue deleting objects from https://[myjss].jamfcloud.com? (Y or N): Y
19:51:22 [jonasb:~/src/div/Spruce] master ยฑ ./spruce.py -p -o /tmp/pkgs2
๐ŸŒฒ  Building: Package Report... ๐ŸŒฒ
๐ŸŒฒ  Wrote output to /tmp/pkgs2
19:51:38 [jonasb:~/src/div/Spruce] master ยฑ diff /tmp/pkgs /tmp/pkgs2
diff --git a/tmp/pkgs b/tmp/pkgs2
index d659715..d4dce15 100644
--- a/tmp/pkgs
+++ b/tmp/pkgs2
@@ -1,6 +1,6 @@
 <?xml version='1.0' encoding='UTF-8'?>
 <SpruceReport>
-    <ReportDate>20171213-195109</ReportDate>
+    <ReportDate>20171213-195134</ReportDate>
19:51:38 [jonasb:~/src/div/Spruce] master 1 ยฑ

Error when trying to remove packages from provided xml

Here is the error I see:

JSS: https://JSSServer.com
Preferences used: ~/Library/Preferences/com.github.autopkg.plist
Are you sure you want to continue deleting objects from https://JSSServer.com? (Y or N): y
Traceback (most recent call last):
  File "/Users/autopkg/Downloads/Spruce-master/spruce.py", line 2054, in <module>
    main()
  File "/Users/autopkg/Downloads/Spruce-master/spruce.py", line 2048, in main
    remove(removal_tree)
  File "/Users/autopkg/Downloads/Spruce-master/spruce.py", line 1936, in remove
    except jss.JSSGetError as error:
AttributeError: 'module' object has no attribute 'JSSGetError'```

I have the latest JSSImporter + python-jss and am using the newest release of spruce.

Computers Report fails with homebysix-patch-1 branch

Autopkg v2.0.1RC2
python-jss v2.1
JSSImporter v1.1.0

When invoking Spruce either via /Library/AutoPkg/Python3/Python.framework/Versions/Current/bin/python3 ./spruce.py --computers or /Library/AutoPkg/Python3/Python.framework/Versions/Current/bin/python3 ./spruce.py the report fails with the following error:

jwrn3@iMac Spruce % /Library/AutoPkg/Python3/Python.framework/Versions/Current/bin/python3 ./spruce.py --computers
JSS: https://jssdev.jamfcloud.com
Preferences used: ~/Library/Preferences/com.github.autopkg.plist
๐ŸŒฒ  Building: Computer Report... ๐ŸŒฒ
Traceback (most recent call last):
  File "./spruce.py", line 2170, in <module>
    main()
  File "./spruce.py", line 2166, in main
    run_reports(args)
  File "./spruce.py", line 1945, in run_reports
    results.append(func(**args_dict))
  File "./spruce.py", line 644, in build_computers_report
    report = build_device_report(check_in_period, all_computers)
  File "./spruce.py", line 425, in build_device_report
    "Hardware Model Spread"] = get_version_and_model_spread(devices)
  File "./spruce.py", line 561, in get_version_and_model_spread
    strings = sorted(get_histogram_strings(version_counts, padding=8))
  File "./spruce.py", line 1661, in get_histogram_strings
    result.append((preamble + histogram_bar).decode("utf-8"))
AttributeError: 'str' object has no attribute 'decode'

I have no mobile devices in this JSS so cannot test --mobile_devices but all other reports succeed.

If I drop the .decode I get further but then hit the following error:

jwrn3@iMac Spruce % /Library/AutoPkg/Python3/Python.framework/Versions/Current/bin/python3 ./spruce.py --computers
JSS: https://jssdev.jamfcloud.com
Preferences used: ~/Library/Preferences/com.github.autopkg.plist
๐ŸŒฒ  Building: Computer Report... ๐ŸŒฒ
Traceback (most recent call last):
  File "./spruce.py", line 2173, in <module>
    main()
  File "./spruce.py", line 2169, in main
    run_reports(args)
  File "./spruce.py", line 1948, in run_reports
    results.append(func(**args_dict))
  File "./spruce.py", line 644, in build_computers_report
    report = build_device_report(check_in_period, all_computers)
  File "./spruce.py", line 425, in build_device_report
    "Hardware Model Spread"] = get_version_and_model_spread(devices)
  File "./spruce.py", line 569, in get_version_and_model_spread
    cmp=model_identifier_cmp)
TypeError: 'cmp' is an invalid keyword argument for sort()

After doing a little digging it looks like the sort() function is rather different in Py3 so a lot of the code in model_identifier_cmp() needs reworking. Additionally cmp() isn't available in python3 I'm not sure how viable it is to ensure compatibility with both py2 & py3.

I'll try and kick the issue around a little.

Issue with the remove.xm file and command

I get this error trying to run the remove command

administrator@AutoPKG ~ % sudo /usr/bin/python /usr/local/bin/spruce.py --remove /Users/administrator/Desktop/remove2.xml
JSS: https://myorg.jamfcloud.com
Preferences used: ~/Library/Preferences/com.github.autopkg.plist
Are you sure you want to continue deleting objects from https://myorg.jamfcloud.com? (Y or N): Y
Traceback (most recent call last):
File "/usr/local/bin/spruce.py", line 2249, in
main()
File "/usr/local/bin/spruce.py", line 2243, in main
remove(removal_tree)
File "/usr/local/bin/spruce.py", line 2069, in remove
if not check_with_user():
File "/usr/local/bin/spruce.py", line 2188, in check_with_user
"from %s? (Y or N): " % jss_connection.base_url)
File "", line 1, in
NameError: name 'Y' is not defined

Don't show policies generated by Jamf Remote

I am seeing return from spruce -v --policies that look like:
2014-02-27 at 8:31 PM | casmit14 | 1 Computer 2014-02-27 at 8:34 PM | casmit14 | 1 Computer 2014-02-27 at 8:43 PM | casmit14 | 1 Computer 2014-03-13 at 5:52 PM | djgreen | 4 Computers 2014-03-13 at 5:56 PM | djgreen | 6 Computers 2014-05-21 at 3:23 PM | rjblanke | 1 Computer
followed by "normal" . So looks like of like this:

/Desktop/Spruce-testing/spruce.py --policies -v ๐ŸŒฒ Policies not Scoped (369) 2015-08-19 at 12:43 PM | mortonwd | 1 Computer ... 100's more with date time stamp Acrobat Pro Test Install Adobe CS6 Design Standard Adobe-Premiere-CS6
Of course none of our policies are named with time/date.
This very odd did I miss a feature?

DeleteError response handling

When trying to remove packages, spruce will eventually fail and exit with an error code when there are 404 responses. It seems to be unable to handle a 404 after the removal of the package, but during the check phase it seems to work fine.

Example:

JSS: https://jssserver.com
Preferences used: ~/Library/Preferences/com.github.autopkg.plist
Are you sure you want to continue deleting objects from https://jssserver.com? (Y or N): y
Package object Firefox-67.0.2.pkg with ID 511 is not available or does not exist.
Status Code: 404
Error: Response Code: 404	Response: Not Found. The server has not found anything matching the request URI https://jssserver.com/JSSResource/packages/id/511.
Package object Firefox-67.0.3.pkg with ID 531 is not available or does not exist.
Status Code: 404
Error: Response Code: 404	Response: Not Found. The server has not found anything matching the request URI https://jssserver.com/JSSResource/packages/id/531.
Package object Firefox-67.0.4.pkg with ID 535 is not available or does not exist.
Status Code: 404
Error: Response Code: 404	Response: Not Found. The server has not found anything matching the request URI https://jssserver.com/JSSResource/packages/id/535.
Package object 462: Firefox-67.0.pkg deleted.
Package file Firefox-67.0.pkg deleted.
Package object 583: Firefox-68.0.1.pkg deleted.
Package object 568: Firefox-68.0.pkg deleted.
Traceback (most recent call last):
  File "/AutoPkg/Spruce-master/spruce.py", line 2054, in <module>
    main()
  File "/AutoPkg/Spruce-master/spruce.py", line 2048, in main
    remove(removal_tree)
  File "/AutoPkg/Spruce-master/spruce.py", line 1976, in remove
    jss_connection.distribution_points.delete(filename)
  File "/Library/Application Support/JSSImporter/jss/distribution_points.py", line 272, in delete
    repo.delete(filename)
  File "/Library/Application Support/JSSImporter/jss/distribution_point.py", line 724, in delete
    self.connection["jss"].Package(filename).delete()
  File "/Library/Application Support/JSSImporter/jss/jssobject.py", line 702, in delete
    self.jss.delete(self.url)
  File "/Library/Application Support/JSSImporter/jss/jamf_software_server.py", line 452, in delete
    error_handler(DeleteError, response)
  File "/Library/Application Support/JSSImporter/jss/tools.py", line 94, in error_handler
    raise exception
jss.exceptions.DeleteError: Response Code: 404	Response: Not Found. The server has not found anything matching the request URI https://jssserver.com/JSSResource/packages/id/568.```

Error when using --remove option

Hoping you may be able to provide some insight on an error I'm getting when I attempt to use the --remove option with an xml file. This is what I'm seeing:

computername:~ username$ ~/Desktop/spruce.py --remove ~/Desktop/test3.xml 
Are you sure you want to continue deleting objects from https://jssaddress.company.com? (Y or N): y
ComputerGroup object 999: Name of a Computer Group deleted.
Traceback (most recent call last):
  File "/Users/username/Desktop/spruce.py", line 1949, in <module>
    main()
  File "/Users/username/Desktop/spruce.py", line 1943, in main
    remove(removal_tree)
  File "/Users/username/Desktop/spruce.py", line 1873, in remove
    if item.tag in needs_file_removal and file_type_removals:
UnboundLocalError: local variable 'needs_file_removal' referenced before assignment

It results in the first item in the list being removed and then stopping with the above error.

Thanks!

JSS can't return data...

Just an FYI we have over 1800 packages and when I call spruce-test/spruce --packages I always get 500 errors like below. I have a call opened with JAMF to see what we can do. FWIW JAMF is saying the searches need to be qualified (like only ones in certain categories) but looks to me like the initial query just asking for the list of packages is causing the 500's. Not sure if that is true but I can go to the web interface for the api and get a good full list. Also happens to me with Scripts.


~/Spruce-testing/spruce.py --packages
๐ŸŒฒ Building: Package Report... ๐ŸŒฒ
Traceback (most recent call last):
File "/Users/ega/Desktop/Spruce-testing/spruce.py", line 1943, in
main()
File "/Users/ega/Desktop/Spruce-testing/spruce.py", line 1939, in main
run_reports(args)
File "/Users/ega/Desktop/Spruce-testing/spruce.py", line 1783, in run_reports
results.append(func(**args_dict))
File "/Users/ega/Desktop/Spruce-testing/spruce.py", line 808, in build_packages_report
all_configs = jss_connection.ComputerConfiguration().retrieve_all()
File "/Library/Python/2.7/site-packages/jss/jss.py", line 1948, in retrieve_all
self.obj_class, int(self[i]['id']), subset)
File "/Library/Python/2.7/site-packages/jss/jss.py", line 550, in get_object
xmldata = self.jss.get(url)
File "/Library/Python/2.7/site-packages/jss/jss.py", line 238, in get
self._error_handler(JSSGetError, response)
File "/Library/Python/2.7/site-packages/jss/jss.py", line 194, in _error_handler
raise exception
jss.exceptions.JSSGetError: Response Code: 500 Response: Internal Server Error. The server encountered an unexpected condition which prevented it from fulfilling the request

Make Spruce work with JSSImporter installation

Recent versions of JSSImporter include python-jss, but it is installed in /Library/Application Support/JSSImporter/ rather than in the standard path. We should add this path to Spruce's search path so that python-jss does not need to be installed again.

Packages list not checking for multiple packages in policies

I ran Spruce against two of our Jamf Pro instances today. The output showed a list of 489 packages that were not used in a policy or configuration. I did a spot check on the list and found that several were indeed still attached to policies.

I then used a MySQL query to determine the policy ID of any package ID that was attached to a policy using this query:

select package_id,policy_id from policy_packages where package_id in ('1','2','3'....);

I was able to take the output of that and compare it to the output from Spruce and found 90 packages that were indeed still attached to policies.

I did a spot check of about 10 of the policies that packages were still attached to, and in all 10 cases there were multiple packages assigned to the policy. I'm thinking that may be what is causing the issue.

Latest version of Spruce that is on GitHub.

Jamf Pro 10.20.1

I saw this behavior on two different Jamf Pro servers, both the same version.

Happy to provide any other data or testing.

Steve

Suggestion: Change repo description

The repo description is a bit out of date:

Identify unused packages and scripts on a JAMF Casper JSS and optionally remove them.

I'd recommend something like:

Identify unused objects in Jamf Pro and optionally remove them.

Getting error from current testing branch 08122015...

I know it is testing but just FYI seeing this error on subset with any flag.

leeta:Spruce-testing ega$ /Users/ega/Downloads/Spruce-testing/spruce.py -t -v
๐ŸŒฒ Building: Policy Report... ๐ŸŒฒ
Traceback (most recent call last):
File "/Users/ega/Downloads/Spruce-testing/spruce.py", line 1373, in
main()
File "/Users/ega/Downloads/Spruce-testing/spruce.py", line 1369, in main
run_reports(args)
File "/Users/ega/Downloads/Spruce-testing/spruce.py", line 1316, in run_reports
results.append(func(**args_dict))
File "/Users/ega/Downloads/Spruce-testing/spruce.py", line 798, in build_policies_report
subset=["general", "scope"])
TypeError: retrieve_all() got an unexpected keyword argument 'subset'

Feature request: List smart/static groups which aren't used in any scope

It would blow people's minds if Spruce could provide a report on the smart groups and static groups that are not currently being used in any scope. The pseudo-logic would look something like this:

$computer_groups = array_merge( $smart_computer_groups, $static_computer_groups )
$mobile_groups = array_merge( $smart_mobile_groups, $static_mobile_groups )

for each $group in $computer_groups {
    check for $group.id in all policy scopes
    check for $group.id in all configuration profile scopes
    check for $group.id in all managed preferences scopes
    check for $group.id in all restricted software scopes
    check for $group.id in all mac app store scopes
    check for $group.id in all ebooks scopes
    if any of the above is true { return } else { return $group }
}

for each $group in $mobile_groups {
    check for $group.id in all configuration profile scopes
    check for $group.id in all provisioning profile scopes
    check for $group.id in all mobile apps scopes
    check for $group.id in all ebooks scopes
    if any of the above is true { return } else { return $group }
}

I know many people have smart groups simply for reporting/monitoring purposes, but the above feature would really help us sort through which non-scoped groups are useful to us and which are not.

๐Ÿ‘

Unable to run mobile device report

In the current testing branch, I'm getting errors when spruce attempts to run a mobile device report. Let me know what I can provide to give more insight.

$ python spruce.py --verbose -d
๐ŸŒฒ  Building: Mobile Device Report... ๐ŸŒฒ
Traceback (most recent call last):
  File "spruce.py", line 1668, in <module>
    main()
  File "spruce.py", line 1664, in main
    run_reports(args)
  File "spruce.py", line 1611, in run_reports
    results.append(func(**args_dict))
  File "spruce.py", line 719, in build_mobile_devices_report
    report = build_device_report(check_in_period, mobile_devices)
  File "spruce.py", line 468, in build_device_report
    device_name = device_type(devices)
  File "spruce.py", line 559, in device_type
    raise ValueError
ValueError

The rest of the reports seem to succeed:

$ python spruce.py -a
๐ŸŒฒ  Building: Computer Groups Report... ๐ŸŒฒ
๐ŸŒฒ  Building: Computer Configuration Profile Report... ๐ŸŒฒ
๐ŸŒฒ  Building: Mobile Device Configuration Profile Report... ๐ŸŒฒ
๐ŸŒฒ  Building: Mobile Device Group Report... ๐ŸŒฒ
๐ŸŒฒ  Building: Computer Report... ๐ŸŒฒ
๐ŸŒฒ  Building: Mobile Apps... ๐ŸŒฒ
๐ŸŒฒ  Building: Policy Report... ๐ŸŒฒ
๐ŸŒฒ  Building: Scripts Report... ๐ŸŒฒ
๐ŸŒฒ  Building: Mobile Device Report... ๐ŸŒฒ
Traceback (most recent call last):
  File "spruce.py", line 1668, in <module>
    main()
  File "spruce.py", line 1664, in main
    run_reports(args)
  File "spruce.py", line 1611, in run_reports
    results.append(func(**args_dict))
  File "spruce.py", line 719, in build_mobile_devices_report
    report = build_device_report(check_in_period, mobile_devices)
  File "spruce.py", line 468, in build_device_report
    device_name = device_type(devices)
  File "spruce.py", line 559, in device_type
    raise ValueError
ValueError

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.