Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update API to rest framework #34

Merged
merged 16 commits into from
Jun 23, 2024
Prev Previous commit
Next Next commit
clean up
  • Loading branch information
Steve Küng committed Jun 23, 2024
commit 579217c3b9c569c17149b7c87fdefd0144f4ef83
200 changes: 2 additions & 198 deletions api/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@
"""
from django.conf import settings

import os
import sys
import logging
import plistlib

LOGGER = logging.getLogger('munkiwebadmin')
MUNKI_REPO_URL = settings.MUNKI_REPO_URL
Expand All @@ -18,13 +16,7 @@

try:
from munkilib.admin import makecatalogslib
from munkilib.cliutils import ConfigurationSaveError
from munkilib.cliutils import configure as _configure
from munkilib.cliutils import libedit
from munkilib.cliutils import get_version, pref, path2url
from munkilib.wrappers import (get_input,
readPlistFromString, writePlistToString,
PlistReadError, PlistWriteError)
from munkilib.wrappers import (readPlistFromString, writePlistToString)
from munkilib import munkirepo
except ImportError:
LOGGER.error('Failed to import munkilib')
Expand Down Expand Up @@ -133,192 +125,4 @@ def makecatalogs(cls, output_fn=print):
makecatalogslib.makecatalogs(repo, {}, output_fn=output_fn)
except makecatalogslib.MakeCatalogsError as err:
LOGGER.error('makecatalogs failed: %s', err)
raise FileError(err)

class Plist(object):
'''Pseudo-Django object'''
@classmethod
def list(cls, kind):
'''Returns a list of available plists'''
plists = repo.itemlist(kind)
return plists

@classmethod
def new(cls, kind, pathname, user, plist_data=None):
'''Returns a new plist object'''
filepath = os.path.join(REPO_DIR, kind, os.path.normpath(pathname))
if os.path.exists(filepath):
raise FileAlreadyExistsError(
'%s/%s already exists!' % (kind, pathname))
plist_parent_dir = os.path.dirname(filepath)
if not os.path.exists(plist_parent_dir):
try:
# attempt to create missing intermediate dirs
os.makedirs(plist_parent_dir)
except (IOError, OSError) as err:
LOGGER.error('Create failed for %s/%s: %s', kind, pathname, err)
raise FileWriteError(err)
if plist_data:
plist = plist_data
else:
# create a useful empty plist
if kind == 'manifests':
plist = {}
for section in [
'catalogs', 'included_manifests', 'managed_installs',
'managed_uninstalls', 'managed_updates',
'optional_installs']:
plist[section] = []
elif kind == "pkgsinfo":
plist = {
'name': 'ProductName',
'display_name': 'Display Name',
'description': 'Product description',
'version': '1.0',
'catalogs': ['development']
}
try:
plistFile=open(filepath,'wb')
plistlib.dump(plist, plistFile)
plistFile.close()
LOGGER.info('Created %s/%s', kind, pathname)
except (IOError, OSError) as err:
LOGGER.error('Create failed for %s/%s: %s', kind, pathname, err)
raise FileWriteError(err)
return plist

@classmethod
def read(cls, kind, pathname):
'''Reads a plist file and returns the plist as a dictionary'''
try:
return readPlistFromString(repo.get(kind + '/' + pathname))
except munkirepo.RepoError as err:
LOGGER.error('Read failed for %s/%s: %s', kind, pathname, err)
return {}

@classmethod
def write(cls, data, kind, pathname, user):
'''Writes a text data to (plist) file'''
filepath = os.path.join(REPO_DIR, kind, os.path.normpath(pathname))
plist_parent_dir = os.path.dirname(filepath)
if not os.path.exists(plist_parent_dir):
try:
# attempt to create missing intermediate dirs
os.makedirs(plist_parent_dir)
except OSError as err:
LOGGER.error('Create failed for %s/%s: %s', kind, pathname, err)
raise FileWriteError(err)
try:
fileref=open(filepath,'wb')
plistlib.dump(data, fileref)
fileref.close()
LOGGER.info('Wrote %s/%s', kind, pathname)
except (IOError, OSError) as err:
LOGGER.error('Write failed for %s/%s: %s', kind, pathname, err)
raise FileWriteError(err)

@classmethod
def delete(cls, kind, pathname, user):
'''Deletes a plist file'''
filepath = os.path.join(REPO_DIR, kind, os.path.normpath(pathname))
if not os.path.exists(filepath):
raise FileDoesNotExistError(
'%s/%s does not exist' % (kind, pathname))
try:
os.unlink(filepath)
LOGGER.info('Deleted %s/%s', kind, pathname)
except (IOError, OSError) as err:
LOGGER.error('Delete failed for %s/%s: %s', kind, pathname, err)
raise FileDeleteError(err)


class MunkiFile(object):
'''Pseudo-Django object'''
@classmethod
def get_fullpath(cls, kind, pathname):
'''Returns full filesystem path to requested resource'''
return os.path.join(REPO_DIR, kind, pathname)

@classmethod
def list(cls, kind):
'''Returns a list of available plists'''
files_dir = os.path.join(REPO_DIR, kind)
files = []
for dirpath, dirnames, filenames in os.walk(files_dir):
# don't recurse into directories that start with a period.
dirnames[:] = [name for name in dirnames if not name.startswith('.')]
subdir = dirpath[len(files_dir):].lstrip(os.path.sep)
if os.path.sep == '\\':
files.extend([os.path.join(subdir, name).replace('\\', '/')
for name in filenames
if not name.startswith('.')])
else:
files.extend([os.path.join(subdir, name)
for name in filenames
if not name.startswith('.')])
return files

@classmethod
def new(cls, kind, fileupload, pathname, user):
'''Creates a new file from a file upload; returns
FileAlreadyExistsError if the file already exists at the path'''
filepath = os.path.join(REPO_DIR, kind, os.path.normpath(pathname))
if os.path.exists(filepath):
raise FileAlreadyExistsError(
'%s/%s already exists!' % (kind, pathname))
file_parent_dir = os.path.dirname(filepath)
if not os.path.exists(file_parent_dir):
try:
# attempt to create missing intermediate dirs
os.makedirs(file_parent_dir)
except (IOError, OSError) as err:
LOGGER.error(
'Create failed for %s/%s: %s', kind, pathname, err)
raise FileWriteError(err)
cls.write(kind, fileupload, pathname, user)

@classmethod
def write(cls, kind, fileupload, pathname, user):
'''Retreives a file upload and saves it to pathname'''
filepath = os.path.join(REPO_DIR, kind, os.path.normpath(pathname))
LOGGER.debug('Writing %s to %s', fileupload, filepath)
try:
with open(filepath, 'wb') as fileref:
for chunk in fileupload.chunks():
LOGGER.debug('Writing chunk...')
fileref.write(chunk)
LOGGER.info('Wrote %s/%s', kind, pathname)
except (IOError, OSError) as err:
LOGGER.error('Write failed for %s/%s: %s', kind, pathname, err)
raise FileWriteError(err)
except Exception as err:
LOGGER.error('Write failed for %s/%s: %s', kind, pathname, err)
raise FileWriteError(err)

@classmethod
def writedata(cls, kind, filedata, pathname, user):
'''Retreives a file upload and saves it to pathname'''
filepath = os.path.join(REPO_DIR, kind, os.path.normpath(pathname))
try:
with open(filepath, 'wb') as fileref:
fileref.write(filedata)
LOGGER.info('Wrote %s/%s', kind, pathname)
except (IOError, OSError) as err:
LOGGER.error('Write failed for %s/%s: %s', kind, pathname, err)
raise FileWriteError(err)

@classmethod
def delete(cls, kind, pathname, user):
'''Deletes file at pathname'''
filepath = os.path.join(REPO_DIR, kind, os.path.normpath(pathname))


if not os.path.exists(filepath):
raise FileDoesNotExistError(
'%s/%s does not exist' % (kind, pathname))
try:
os.unlink(filepath)
LOGGER.info('Deleted %s/%s', kind, pathname)
except (IOError, OSError) as err:
LOGGER.error('Delete failed for %s/%s: %s', kind, pathname, err)
raise FileDeleteError(err)
raise FileError(err)
8 changes: 4 additions & 4 deletions api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from django.http import FileResponse
from django.conf import settings

from api.models import Plist, MunkiRepo
from api.models import MunkiRepo
from api.models import FileReadError, \
FileDoesNotExistError, FileDeleteError

Expand Down Expand Up @@ -216,7 +216,7 @@ def get_queryset(self):
return response

def get_object(self):
queryset = Plist.list('catalogs')
queryset = MunkiRepo.list('catalogs')

filter_terms = self.request.GET.copy()
LOGGER.debug("filter_terms: %s", filter_terms)
Expand Down Expand Up @@ -303,7 +303,7 @@ class ManifestsListView(GenericAPIView, ListModelMixin):

def get_queryset(self):
try:
items = Plist.list('manifests')
items = MunkiRepo.list('manifests')
response = ManifestFile.objects.all()
response.values = items
except FileDoesNotExistError as err:
Expand Down Expand Up @@ -448,7 +448,7 @@ def get_queryset(self):
return response

def get_object(self):
queryset = Plist.list('pkgsinfo')
queryset = MunkiRepo.list('pkgsinfo')
filter_terms = self.request.GET.copy()

# remove the _ parameter
Expand Down
4 changes: 0 additions & 4 deletions catalogs/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,13 @@

"""
#from django.db import models
import os
import plistlib
from xml.parsers.expat import ExpatError

from django.conf import settings
from django.db import models

from api.models import MunkiRepo

REPO_DIR = settings.MUNKI_REPO_URL


def trim_version_string(version_string):
### from munkilib.updatecheck
Expand Down
9 changes: 2 additions & 7 deletions munkiwebadmin/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@

#not changing this
MUNKISCRIPTS_PATH = os.path.join(BASE_DIR, 'munkiscripts', 'build')
MEDIA_ROOT = os.path.join(MUNKI_REPO_URL, 'icons')
ICONS_URL = MEDIA_URL

# CORS settings
CORS_ORIGIN_ALLOW_ALL = DEBUG
Expand Down Expand Up @@ -183,11 +181,8 @@
USE_L10N = True
USE_TZ = True

#### end basic Django settings
if DEBUG:
LOGLEVEL = 'DEBUG'
else:
LOGLEVEL = 'WARNING'

LOGLEVEL = 'WARNING'

LOGGING = {
'version': 1,
Expand Down
16 changes: 6 additions & 10 deletions pkgsinfo/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,18 @@
from api.models import MunkiRepo, \
FileReadError, FileWriteError, FileDeleteError

REPO_DIR = settings.MUNKI_REPO_URL
PKGSINFO_PATH = os.path.join(REPO_DIR, 'pkgsinfo')
PKGSINFO_PATH_PREFIX_LEN = len(PKGSINFO_PATH) + 1
PKGSINFO_STATUS_TAG = 'pkgsinfo_list_process'

LOGGER = logging.getLogger('munkiwebadmin')

def pkg_ref_count(pkginfo_path, catalog_items):
'''Returns the number of pkginfo items containing a reference to
the installer_item_location in pkginfo_path and the relative path to
the installer_item_location'''
filepath = os.path.join(PKGSINFO_PATH, os.path.normpath(pkginfo_path))
try:
with open(filepath, 'rb') as f:
plistdata = plistlib.load(f)
except (ExpatError, IOError):
plistdata = MunkiRepo.read('pkgsinfo', pkginfo_path)
except FileReadError:
return 0, ''

pkg_path = plistdata.get('installer_item_location')
if not pkg_path:
return 0, ''
Expand Down Expand Up @@ -63,14 +58,15 @@ def process_file(pkginfo_path):
def any_files_in_list_newer_than(files, filepath):
'''Returns true if any file in the list of files
is newer that filepath'''
try:
# todo: needs to be fixed
'''try:
mtime = os.stat(filepath).st_mtime
except OSError:
return True
for fname in files:
fullpath = os.path.join(PKGSINFO_PATH, fname)
if os.stat(fullpath).st_mtime > mtime:
return True
return True'''
return False


Expand Down
9 changes: 1 addition & 8 deletions pkgsinfo/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

from pkgsinfo.models import Pkginfo, PKGSINFO_STATUS_TAG
from process.models import Process
from api.models import Plist, MunkiRepo, \
from api.models import MunkiRepo, \
FileError, FileDoesNotExistError

import json
Expand All @@ -18,14 +18,7 @@
import plistlib
import urllib

REPO_DIR = settings.MUNKI_REPO_URL
ICONS_DIR = os.path.join(REPO_DIR, 'icons')
STATIC_URL = settings.STATIC_URL
try:
ICONS_URL = settings.ICONS_URL
except AttributeError:
ICONS_URL = None

LOGGER = logging.getLogger('munkiwebadmin')


Expand Down
1 change: 0 additions & 1 deletion process/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
from api.models import MunkiRepo
from process.utils import record_status

REPO_DIR = settings.MUNKI_REPO_URL
MAKECATALOGS = settings.MAKECATALOGS_PATH

FLAG_FILE = '/tmp/makecatalogs_running'
Expand Down
3 changes: 1 addition & 2 deletions reports/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@

from .models import Machine, MunkiReport
from catalogs.models import Catalog
from api.models import Plist, MunkiRepo, FileDoesNotExistError, FileReadError
from api.models import MunkiRepo, FileDoesNotExistError, FileReadError

import os
import plistlib
import urllib
from datetime import timedelta, date
import json
import logging
Expand Down