# encoding: utf-8 # # Copyright 2018-2020 Greg Neagle. # # Licensed under the Apache License, Version 2.0 (the 'License'); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an 'AS IS' BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """ updatecheck.autoconfig Created by Greg Neagle on 2018-04-17. Functions for automatically discovering and configuring some Munki settings. """ from __future__ import absolute_import, print_function # Apple frameworks via PyObjC # PyLint cannot properly find names inside Cocoa libraries, so issues bogus # No name 'Foo' in module 'Bar' warnings. Disable them. # pylint: disable=E0611 from SystemConfiguration import SCDynamicStoreCopyValue # pylint: enable=E0611 # our libs from .. import display from .. import fetch from .. import prefs def get_domain_name(): '''Return current domain name''' dns_config = SCDynamicStoreCopyValue(None, 'State:/Network/Global/DNS') try: return dns_config.get('DomainName') except AttributeError: return None def guess_repo_url(): '''Tries a few default URLs and returns the first one that doesn't fail utterly''' # default to the default repo for Munki up until version 3.2.x autodetected_url = prefs.DEFAULT_INSECURE_REPO_URL domain_name = get_domain_name() if domain_name is None: # No DomainName set return autodetected_url if domain_name == 'local': # no guesses if we are on a .local domain return autodetected_url possible_urls = [ 'https://munki.' + domain_name + '/repo', 'https://munki.' + domain_name + '/munki_repo', 'http://munki.' + domain_name + '/repo', 'http://munki.' + domain_name + '/munki_repo' ] for url in possible_urls: try: display.display_info('Checking for Munki repo at: %s', url) # a normal Munki repo should have a catalog at this URL # if it returns anything, we'll use this as the repo fetch.getDataFromURL(url + '/catalogs/all') autodetected_url = url break except fetch.Error as err: # couldn't connect or other error display.display_info('URL error: %s', err) return autodetected_url def autodetect_repo_url_if_needed(): '''If Munki repo URL is not defined, (or is the insecure default) attempt to discover one. If successful, record the discovered URL in Munki's preferences.''' if prefs.pref('SoftwareRepoURL') not in (None, prefs.DEFAULT_INSECURE_REPO_URL): # SoftwareRepoURL key is defined. exit. return all_keys_defined = True # it's OK if SoftwareRepoURL is not defined as long as all of these # other keys are defined. I think in the real world we'll never see this. for key in ['CatalogURL', 'IconURL', 'ManifestURL', 'PackageURL' 'ClientResourceURL']: if not prefs.pref(key): # some repo url key is not defined. break. all_keys_defined = False break if not all_keys_defined: display.display_info('Looking for local Munki repo server...') detected_url = guess_repo_url() if detected_url: display.display_info( 'Auto-detected Munki repo at %s', detected_url) if detected_url != prefs.DEFAULT_INSECURE_REPO_URL: # save it to Munki's prefs prefs.set_pref('SoftwareRepoURL', detected_url) if __name__ == '__main__': print('This is a library of support tools for the Munki Suite.')