Git Product home page Git Product logo

netkes's Introduction

Build Status

The OpenManage Virtual Appliance

The OpenManage Virtual Appliance (OMVA) provides automatically managed configuration for SpiderOak Blue™ services. It provides three major services: LDAP-driven automatic user provisioning, user authentication to either LDAP or RADIUS servers, and encryption key escrow management for the enterprise.

The net_kes project provides all these services for the OMVA.

Building

The (currently clunky) way to create a deployment tarball is:

$ ./make_tarball.sh <source_directory> <version> <brand_id> ldap.

Where:

  • source_directory: where to find the deployment source.
  • version: Human-readable version number.
  • brand_id: Enterprise brand id to build for
  • ldap: Leave as ldap. Will be removed in future versions.

This will create a file called openmanage.tar.bz2, ready for deployment on an OMVA.

netkes's People

Contributors

bdzim avatar merickson avatar hamptus avatar sirpengi avatar chiiph avatar rixon avatar d3f0 avatar brian-emery avatar kenmanheimer avatar dangle avatar

Stargazers

 avatar  avatar Emanuel Gawrieh avatar Yuko avatar Romuald Bruno Aquinas avatar  avatar Brian Luby avatar  avatar Keith Yang avatar kush avatar  avatar  avatar  avatar David Dahl avatar Aditya Ivaturi avatar

Watchers

Michael A. Crane avatar Diego Marcovecchio avatar tommy-carlos williams avatar Frank Sievertsen avatar  avatar James Cloos avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar Rebecca Watson avatar Adam Tervort avatar  avatar Leandro Balmaceda avatar  avatar  avatar Reed Haynes avatar  avatar  avatar  avatar  avatar  avatar

netkes's Issues

Show high priority logs

We need to alert admins when something breaks. When they log in show the most recent several logs of Error or higher since they last logged in or in the past 24 hours.

Local user creation

Local users should be creatable on the users page. Much of the functionality for this exists, but the ability to choose a group and set a password need to be added.

Reduce verbosity in logging

Many of the VMs the netkes stack is deployed on have limited filesystems, and with larger installations, logging every last little thing that the VM does can fill up the filesystem.

Edit policy page

See #40 for all available policies. This page will allowing editing a set of policies. There are a large number of policies and it would be foolish to create django forms containing all of them. Instead I envision configuration files that list all policies and there types. This can then be used to dynamically generate the forms.

[['LaunchMinimzedAtStartup', 'boolean'],
 ['ShowSplashScreenAtStartup', 'boolean']
]

Log unsuccessful API requests

Requests that fail should be logged with priority error or critical.

Traceback (most recent call last):
  File "/opt/openmanage/netkes/account_mgr/api_interface.py", line 98, in create_user
    result = _run_api_call("users/", new_user_data)
  File "/opt/openmanage/netkes/account_mgr/api_interface.py", line 72, in _run_api_call
    fh = urllib2.urlopen(uri, datastr)
  File "/usr/lib/python2.6/urllib2.py", line 126, in urlopen
    return _opener.open(url, data, timeout)
  File "/usr/lib/python2.6/urllib2.py", line 397, in open
    response = meth(req, response)
  File "/usr/lib/python2.6/urllib2.py", line 510, in http_response
    'http', request, response, code, msg, hdrs)
  File "/usr/lib/python2.6/urllib2.py", line 435, in error
    return self._call_chain(*args)
  File "/usr/lib/python2.6/urllib2.py", line 369, in _call_chain
    result = func(*args)
  File "/usr/lib/python2.6/urllib2.py", line 518, in http_error_default
    raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
HTTPError: HTTP Error 400: Bad Request
Traceback (most recent call last):
  File "/opt/openmanage/netkes/account_mgr/account_runner.py", line 132, in _api_create_users
    result = api_interface.create_user(user, self._promo_code)
  File "/opt/openmanage/netkes/account_mgr/api_interface.py", line 102, in create_user
    raise ManipulateUserFailed(str(e))
ManipulateUserFailed: HTTP Error 400: Bad Request

Edit local users on the user detail page

All information given when creating local users should be editable on the user detail page. This includes changing a password. Much of this functionality exists, but it will need to be cleaned up and only shown for local users.

Disabled users in LDAP need to be disabled in SO User's DB

At one point, we successfully did catch users that were locked out in LDAP and disabled them on the SpiderOak account side. Unfortunately, that doesn't seem to have escaped the labs.

ldap_source needs to detect when a user is locked out and apply that to the sync database appropriately.

Automatically escape special LDAP characters

Filters in LDAP do not allow certain characters, like '(' and ')'. We need to handle it when a user enters these special characters in the blue console. Options:

  1. Look for invalid chars in input fields, either in real time with javascript, or after submitting the form
  2. Allow the characters, and escape them. We need to test this out, because it wouldn't work during initial attempts. Should still have a list of characters that can be escaped and ones that can't

Preference and policy management

Preferences / Policy Management

OpenManage will gain the ability to directly control the desktop client's policy to a much greater extent than before. We will be able to create policies and apply them to groups or the entire enterprise.

General Structure & Implementation

The AccountsApi will be extended to provide an interface for policy, keeping the policy in the SpiderOak users DB. Policy can consist of several subobjects:

  • Client preferences
  • Backup selection
  • Data management policy (ShareLink TTL, data retention policy)

Policies exist on their own outside of groups or the global enterprise within the DB. They are ''owned'' by an enterprise, but just creating a policy does not immediately push it on everyone.

Groups and the whole enterprise reference a policy set that will apply to them. For ease of implementation, let us specify that there is one and only one policy set to be applied to each group, and one set of policy to be applied to the global enterprise. In the event of conflict settings for the group will override global enterprise settings.

Preferences and data management policy will be merged (see example below), however backup selection at this time will be a raw override; a defined backup selection for a group will just outright replace that of a higher-level policy.

''Aside:'' this looks like a perfect use case for Postgresql's hstore type. To investigate.

Preferences will be pushed to the client at three points: during initial syndication / setup, at client reconnect, and whenever the policy is updated on the server side. Policy pushed to the client will override any combination of locally-set configuration. It is '''incorrect''' for policy pushed from the StorageBackend to the DesktopClient to be overridden by any other method.

Example for Preferences Override

If policy for an EndUser's group is defined as:

LaunchMinimzedAtStartup: True

And policy for the global enterprise is defined as:

ShowSplashScreenAtStartup: True

Then the resulting policy will be:

LaunchMinimzedAtStartup: True
ShowSplashScreenAtStartup: True

However, if the policy for an EndUser's group is defined as:

LaunchMinimizedAtStartup: True

And the policy for the global enterprise is defined as:

LaunchMinimizedAtStartup: False

Then the resulting value for LaunchMinimizedAtStartup will be True due to the group configuration.

Policy Definition

Policy will be discussed and defined via JSON-formatted objects. Each policy object will contain at least one of the following objects:

preferences:: Client preferences (contents of which are same as in https://spideroak.com/business/blue/docs/remote_prefs.html)
backup:: Client backup selection (contents of which are same as in https://spideroak.com/business/blue/docs/backup_policy.html)
data_management:: Data management policy that the client enforces. See below.

Preferences

Preferences simply mirror that of https://spideroak.com/business/blue/docs/remote_prefs.html . Specifically, see the section on [https://spideroak.com/business/blue/docs/remote_prefs.html#macos-x-and-linux-json-preferences Mac and Linux JSON preferences].

The concept of ''Defaults'' in preferences are at this time unsupported in Blue 2.0.

Data Management

Data management right now consists of the following options:

ShareLink TTL:: Time-to-live of single-file ShareLinks. Expressed in days. Must be at least 1 day.
Historical Versions TTL:: Time-to-live for historical versions. Expressed in days. A value of '0' implies no limit. Historical versions older than this are automatically purged by the client.
Deleted Items TTL:: Time-to-live for deleted items. Expressed in days. A value of '0' implies no limit. Deleted items older than this are automatically purged by the client.

Backup

The backup policy mirrors that of https://spideroak.com/business/blue/docs/remote_prefs.html . Specifically, see the section on Mac and Linux JSON implementation.

In order to safely abstract out policy, the client '''will''' implement [http://docs.python.org/2/library/os.path.html#os.path.expanduser os.path.expanduser] so that admins can define policy using ~ to represent the user's home directory regardless of OS.

UI on the Management Console

The Management Console will provide an interface to be able to manipulate policy. Policy in the interface, like in implementation, exists alongside and not directly slaved to groups or global configuration. Each group will be defined by a name and have a button for editing the policy.

'''Implementation note:''' Need to figure out a clean way to express all manner of options that we have in the client.

Groups configuration will include an additional field to specify which policy they will be subjected to. In addition, global enterprise settings will allow an admin to select the global policy that will apply to all [[EndUser]]s on the account.

Issues

#49
#50
#51

Different LDAPs present different group membership attributes

In LdapGroup._build_user_details, we make the apparently crass assumption that the list of members in a group are full-blown DNs. Some LDAPs just give us uids. We need to account for and handle both kinds of things.

Proposal

If dir_member_source matches a regex like member([:alpha:]), we will use the match group as a search filter string to grab the user details.

Automatic Updates

The stack should also be able to update itself. The UI should consist entirely of a modal dialog asking for a file to upload and an "upload" button. Upon receiving the update package, it should run a spinner for the user.

Return list of failed user creation in account_runner

In migrating everything to the Accounts API, the calls in netkes.account_mgr.account_runner now return a list of the users gone through as well as an empty list. The definition of the function requires that the lists we return are the list of created users and the list of users for whom the API calls failed for. Either modify the code to send the proper lists and report errors clearly (preferred) or modify the code and comments to not use the lists.

Create policy page

This page will list all existing policies by name. You will be able to create new policies or edit existing policies. Creating a policy will consist of choosing a name. The user will then be sent to the edit policy page to set the actual policy. Clicking a policy from the list will take you to the same page.

This will require create policy, edit policy, and list policy functions in the management console.

Users in multiple groups

Users in Multiple Groups

Groups will have a configuration parameter for priority. Users discovered in multiple groups will be assigned to the highest priority group they were discovered in during the sync run.

Multiple groups can have the same priority, however it is undefined which group a user will be placed in in the event of multiple matching groups.

Users '''cannot''' be in multiple groups across user sources at this time, however. This is due to the fact that the UIDs we use to match users to avatars are non-portable across user sources.

Implementation

Group object implementations in agent_config.json will include a ''priority'' field. This is a positive or zero integer. Groups lacking a priority field will be assumed to be 0.

UI in the Management Console

The group creation widget will include a priority field to assign a priority to the group, with the default being 0. All groups under management will also have a priority field as part of each group. If there is no priority defined for the group, it will default to 0.

Issues

#42
#43

Polling MSAD groups require paging

Large MSAD result lists need to be paged.

Previously in our Large AD-Equipped Customers, we were searching against the memberOf attribute and paging the results. In moving to a more generic system, it appears that in addition to using account_mgr.user_source.ldap_source._PagedAsyncSearch, we also need to specify and understand ranged retrieval. This is because if a group has a large list of entries in a list value for an attribute, we will get ranged results. This is in addition to the PagedAsyncSearch requirement as well for long result lists.

I'd like to be a little intelligent and try to detect the existence of memberOf and use that, but we'll have to implement the paging anyway for MSAD instances that have disabled memberOf for reasons.

Elimination of initial setup console work

Everything for initial setup should happen automatically or through the management console.

Two sections of setup need to be completed by the system before it's "up":

  • Steps contained in the first_setup.sh script:
    • TZ configuration
    • Escrow key generation
    • Django setup
  • Steps contained in finish_setup.sh:
    • Create an hourly cron job to run the LDAP sync
    • Creation of a runsv-supervised job for the openmanage web server.
    • Ensures latest SQL is up to date
    • Runs the initial LDAP sync operation.

Most of the above can be rolled into either OMVA build-time steps, a revamped initial boot sequence, or a simple suite of settings. Largely, the user-directed settings:

  • Time zone configuration
  • OMVA network configuration (Unnecessary in OpenManage/CloudConsole configuration)
  • Enable / disable LDAP perodic automatic sync.

TODO's for 2.0

  • Sort functions for *
  • Sort by Service, Date for /logs/
  • Ticket #68
  • Breadcrumbs functionality
  • Descriptions for items in /manage/

AFAIK that's all that's left for the MC 2.0
Feel free to add or remove as necessary.

Customizable non-email usernames for Private Cloud

Implement a method by which the management VM, communicating with a private cloud installation, can pull a username from the directory and use that as the SpiderOak storage backend username. This also needs some elementary protection in the code to prevent accidentally using it in a hosted storage context (as we use names that act like email addresses to prevent namespace issues).

Implementation

A new configuration variable dir_email_source will be introduced and made available for customer configuration, if and only if the configuration for api_root does not point to spideroak.com. An exception is to be raised if dir_email_source is used without a configured non-SpiderOak api_root. If dir_email_source is defined:

  1. dir_username_source will be expected to be set as whatever actual username the Customer is expecting to use from the LDAP.
  2. dir_email_source will be expected to be set as whatever field will provide an email address for all EndUser accounts automatically generated.
  3. API calls to the storage backend will not be configured to produce automatically-generated usernames, but instead use the field from dir_username_source for the username field when creating accounts through the API.

The relationship of dir_username_source and dir_auth_username (see #1) should remain the same regardless of the use of a dir_email_source field in the LDAP configuration on the NetKES stack.

Add tests for system health

These tests will show the health of the management vm. There will be a button to rerun the tests.

Tests

  • Can we connect to the DB?
  • Is the openmanage service running?
  • Last LDAP Sync: we look in the log file for indication of a successful sync operation.
    • ''Successful sync operation'': We see a begin sync message in the logs, and find a matching completion tag.
  • LDAP connectivity: Last LDAP sync operation ''did not'' fail out with an LDAP connectivity error.
  • AccountsApi connectivity: Last AccountsApi operation ''did not'' fail out with a connection error.

Allow modifiable filterstr for user lookups

Some organizations have a different definition of what a human is that isn't covered by "(|(objectClass=person)(objectClass=user)(objectClass=organizationalUser))". This should be moved into its own directory configuration variable dir_human_filterstr.

Log failed console login attempts

Login attempts (failures) are not logged. There are now login success messages with the IP. Let's extend this to the beginning of the login attempt, and add a success message after the fact.

Login failures need to be detailed. There should be an indication of the route taken (accounts API or the same method used by openmanage) for authentication and the cause of the failure as indicated by the upstream.

Example:

INFO 2013-12-02 11:33:50,712 Login attempt: paul_hosted from ip: 127.0.0.1
INFO 2013-12-02 11:33:50,712 paul_hosted (superuser): logged in

and, for failure, from API

INFO 2013-12-02 11:33:50,712 Login attempt: paul_hosted from ip: 127.0.0.1
INFO 2013-12-02 11:33:50,712 paul_hosted: login failure

or, from AD

INFO 2013-12-02 11:33:50,712 Login attempt: [email protected] from ip: 127.0.0.1
INFO 2013-12-02 11:33:50,712 [email protected]: login failure [[LDAP: error code 49 - 80090308: LdapErr: DSID-0C0903A9, comment: AcceptSecurityContext error, data 701, v1db0]

Handle group conflicts

With the addition of group priority in #42 we can now resolve sync conflicts. If a user is in multiple groups we should keep the highest priority group and remove the rest. We can do that by ordering the groups by priority and then looping over them deleting any conflicting rows. If two groups have the same priority it is undefined which will get the users. A proof of concept of this idea is here: 2689a0b

Configure dynamic lookup of user to authenticate against

Instead of blindly assuming that the email address (or something that looks like an email address, like a userPrincipalName on Win32) is the legitimate user account, we want to dynamically look up the username we're actually supposed to use based on the email-looking field. For example in an AD environment, we could use an actual email field for the SpiderOak username, and lookup the userPrincipalName on login.

This behavior should be triggered on the existence of a dir_auth_username field in the configuration. If this field exists, it should lookup the contents of the field named in dir_auth_username based on a the definition of dir_user_source and the username presented from SpiderOak.

Remote login field length limitation

The username field on the login screen has too short a limit. Since a user may have an arbitrarily long username@domain, the length limit here should just be removed.

Add local users

User / Group Management

User Sources

Blue 2.0 will include the concept of the ''user source''. A ''user source'' provides a way to have more than once source of user provisioning and authentication. Blue 2.0 will include the ability to have up to one LDAP server and up to one user DB kept locally on the Management VM.

A Blue 2.0 installation will require '''at least''' one user source, but it does not matter which one. ''User source'' definitions are invisible to any of the SpiderOak backend database; it is entirely how we define users to be managed via the AccountsApi.

Users '''will not''' be able to be migrated between user sources in the Blue 2.0 release.

Implementation

agent_config.json's expected syntax will be expanded in two ways:

  • A new empty list object ''user_sources'' will be created under the root. It will contain the following objects in the list as populated via the Management VM.:
{
    'dir_type': <String, either 'ldap' or 'local'>,
    'dir_name': <String>,
    <--- existing LDAP configuration parameters here --->
}

It is '''incorrect''' to have more than one element of the same dir_type in the list.

  • Group object definitions will be extended to include a member named ''user_source'', which will correspond to the dir_name in the above definition of a ''user_source''.
    • Group objects defined as local will not include LDAP fields in their definition.

Conversion of Existing Installations

A script will be created to:

  1. Move existing LDAP configuration into a proper ''user_source'' definition.
  2. Modify existing group definitions to include an appropriate reference to the newly-created ''user_source'' definition.

UI in the Management Console

A control for user sources will be present alongside groups management. It will:

  • Offer a checkbox for enabling / disabling the local user DB and LDAP sources.
    • If the checkbox is enabled, disabling it will display a warning to the user that the groups and users in them will be non-recoverably disabled within SpiderOak. It will require the admin typing something like "I understand" before allowing the user to actually disable the local user DB.
  • If the checkbox for LDAP is enabled, it will present LDAP configuration parameters for the user to fill out.
  • Upon LDAP user source creation, we will attempt to connect to the LDAP with the provided information, and report error if it doesn't work.

The group creation widget will present the user with the ability to select a source for the group to use. In the event an LDAP group is chosen, only then will the group widget display an LDAP DN field. Groups cannot change user sources once created; there will be no ability to manipulate a group's user source once it's created.

Management of Local Users

  1. User creation on the users page
  2. Edit users on the user detail page
  3. Change password on the user detail page

Issues

#44
#45
#46
#47
#48

Extended management VM logging of all services.

There should be extensive logging, and log output should be at the appropriate log levels. Limited filesystem limitations are strictly environment dependent, and we should instead empower the installer to determine logging requirements and management. Here's how we do it:

  1. Ensure log entries have an appropriate log level. Exception causing output should have error, critical, or warning priority. Mark points (things like a new user being created) should be info level, and stuff you only need for troubleshooting should be debug.
  2. Make it easy to set and change the log output priority.
  3. In any systems we deploy, set up log rotation. We can also set this up within netkes, but it should have the configurability sysadmins need: number of log files to retain, log rotate time, log rotate size.
  4. Centralize logging in standard directories. This means /var/log. In systems with limited resources and logging enabled, it's a best practice to put /var/log on a separate mount point.

Enable or disable local users

See #38. Enabling will allow you to choose the local user source when creating groups, allow creation of new users on the users page, and allow editing of users on the user detail page. Much of this functionality exists to some extent, but will need clean up.

Disabling will permanently disable all local users. There will be a confirmation before this is allowed.

Admin Groups - adjust layout

The Admin Groups tab has a poor layout of the options for each group. The check box for each option is above the option, so it takes two lines instead of one. Putting this on the same line would be an improvement, but maybe there's a better way to put all the options on one or two lines, below the Name and DN fields.
screenshot from 2013-12-02 07 41 23

Choose user source when creating a group

When creating a group there should be a drop down with all existing user sources. The user source will be saved in the group definition. After creation user source cannot be changed. This is because we do not support moving users between user sources.

Validate configuration file at startup

There should be a config file validator for the openmanage service that runs at startup. This should check the following:

  • Is the file valid json?
  • Are all required keys there?
  • Do the required keys have valid data?
  • Are there any unrecognized keys? (Just warn the user but run.)

A frequent source of problems with the service is getting to a part of code that has a key that it can't load. Maybe it doesn't exist, or the value isn't valid. Catching these at load time would catch most problems created during reconfiguration or upgrade when an admin is present. Otherwise, problems may not turn up until much later than changes were made.

Log Django Errors

By default django tries to email errors. Instead these errors should be logged to a file.

Total management via the web console

Total Management via the Web Console

All routine administrative tasks should be able to be performed through the management console. The only time an admin should need to SSH in is on a screen share with some from SpiderOak, and the necessity to SSH in should be reduced or eliminated.

Between the enhanced group controls above and the enhanced controls below, there is no need to modify the agent_config.json file. This file should be considered entirely for maintenance operations and internal use only now.

Sync Controls

Users should have the ability to immediately run a user DB - LDAP sync. This should be a nice, friendly button, and only available if an LDAP user source is enabled.

In addition, hidden away somewhere should be a rebuild user sync DB button. This should also only be available when the user has LDAP enabled. With selected this should create a dialogue asking users they are sure.

In both cases the UI should display a busy indicator during the length of the operation.

Log Display

In 1.3, we display all admin console log messages to provide an audit trail. In Blue 2.0, this will be expanded to provide complete system logs. Additionally, there will be a button to generate a zip file of the entire /var/log/omva directory and download it to the user's machine to send to us for technical support reasons.

We will keep track of all the "ERROR" logs since the last time the user visited the page, and display them as an alert on the landing page.

System Health

A system health board will display:

  • "Internal State": This will be a single OK/BAD indicator for the following conditions:
    • Is the agent_config.json valid?
    • Can we connect to the DB?
    • Is the openmanage service running?
  • Last LDAP Sync: we look in the log file for indication of a successful sync operation.
    • ''Successful sync operation'': We see a begin sync message in the logs, and find a matching completion tag.
  • Connectivity indicators. These should also have a refresh button next to them to immediately test.
    • LDAP connectivity: Last LDAP sync operation ''did not'' fail out with an LDAP connectivity error.
    • AccountsApi connectivity: Last AccountsApi operation ''did not'' fail out with a connection error.

Elimination of initial setup console work

Two sections of setup need to be completed by the system before it's "up":

  • Steps contained in the first_setup.sh script:
    • TZ configuration
    • Escrow key generation
    • Django setup
  • Steps contained in finish_setup.sh:
    • Create an hourly cron job to run the LDAP sync
    • Creation of a runsv-supervised job for the openmanage web server.
    • Ensures latest SQL is up to date
    • Runs the initial LDAP sync operation.

Most of the above can be rolled into either OMVA build-time steps, a revamped initial boot sequence, or a simple suite of settings. Largely, the user-directed settings:

  • Time zone configuration
  • OMVA network configuration (Unnecessary in OpenManage/CloudConsole configuration)
  • Enable / disable LDAP perodic automatic sync.

Automatic Updates

The stack should also be able to update itself. The UI should consist entirely of a modal dialog asking for a file to upload and an "upload" button. Upon receiving the update package, it should run a spinner for the user.

Issues

#52
#53
#54
#55
#56
#57
#58

Upgrade scripts should install from local files

The new script, upgrade/gather_resources.sh, installs new versions of Django and Python using pip over the Internet. Some installations won't have public access to the net, so the upgrade scripts need to be modified to allow installation from local copies.

Since 1.3 is already behind, users who need these files can manually put them into place for installation. My goal is to make the script get the files via the net if not available locally.

Ref: http://www.pip-installer.org/en/latest/usage.html#pip-install

Sync and rebuild db in the management console

There should be buttons to sync or rebuild the db. Rebuilding the db should require confirmation. Show a busy indicator during the operation, log all output, and show a success or failure message.

Add a priority field to groups

Groups need a priority to determine which group gets users who are in multiple groups. In the initial implementation priority can be entered by the user in the management console. Priority will be saved in agent_config.json

Eventually it might be nice to hide priority and allow the user to drag and drop groups to change the priority.

Automatic configuration testing

We need tests to help with Blue deployments, just to make sure that everything works out (as per suggestion by @rixon ). This covers all tests that cover configuration of this module.

To test:

  • Basic config file validity
  • LDAP Configuration:
    • Access to the LDAP server
    • Ability to bind as the openmanage search user
    • Ability to search against the configured base DN.
  • Network Configuration:
    • Ability to reach the storage backend AccountsAPI as configured via the api_root configuration variable.
    • Ability to login against the storage backend AccountsAPI as configured.
    • Ability for the storage backend to reach the local Management VM.

Other requirements as @rixon informs me I've missed something.

DB rebuild doesn't properly capture disabled users

In the DB rebuild section of group_manager, we don't appropriately add users who exist on the SpiderOak side and not on the LDAP side. This causes them to effectively become orphaned from a groups management perspective, and never properly disabled.

Single script to apply all SQL updates

There is some SQL and a python script already to apply new SQL updates. Create a single script that runs all, suitable for a run-once-on-first-boot situation.

Download zip file of all logs

In order to aid debugging have a button that downloads a zip file of all logs. These logs can then be sent to SpiderOak for debugging.

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.