forked from pongasoft/glu
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
first iteration at back porting glu console cli.
broken and needs to be made more generic
- Loading branch information
Showing
14 changed files
with
677 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/* | ||
* Copyright 2010-2010 LinkedIn, Inc | ||
* | ||
* 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 | ||
* | ||
* http://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. | ||
*/ | ||
|
||
apply plugin: 'org.linkedin.release' | ||
apply plugin: 'org.linkedin.cmdline' | ||
|
||
cmdline { | ||
// no dependency at all | ||
dependsOn = null | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# | ||
# Copyright 2010-2010 LinkedIn, Inc | ||
# | ||
# 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 | ||
# | ||
# http://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. | ||
# | ||
|
||
import os | ||
from setuptools import setup | ||
|
||
setup( | ||
name = "gluconsole", | ||
version = "0.1", | ||
author = "Manish Dubey", | ||
author_email = "mdubey@linkedin.com", | ||
description = ("GLU REST API"), | ||
install_requires = ['restkit', 'progressbar'], | ||
packages = ['gluconsole'], | ||
scripts = ['src/cmdline/resources/bin/glu'], | ||
|
||
package_dir = { | ||
'gluconsole': 'src/cmdline/resources/lib/python/gluconsole' | ||
}, | ||
) |
240 changes: 240 additions & 0 deletions
240
console/org.linkedin.glu.console-cli/src/cmdline/resources/bin/glu
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,240 @@ | ||
#!/usr/bin/python | ||
|
||
# | ||
# Copyright 2010-2010 LinkedIn, Inc | ||
# | ||
# 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 | ||
# | ||
# http://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. | ||
# | ||
|
||
# | ||
# This script provides a way to communicate with GLU console via REST API. | ||
# It provides high level actions (by constructing lower level REST calls to the console), such as: | ||
# -- start (to start apps in a fabric) | ||
# -- stop (to stop apps in a fabric) | ||
# -- load (to load a new model for a fabric) | ||
# -- status (to load a new model for a fabric) | ||
# | ||
# It used gluconsole.rest.Client, which encapsulates these methods. | ||
# | ||
import sys | ||
import os | ||
import getpass | ||
import site | ||
|
||
bin = os.path.abspath((os.path.dirname(sys.argv[0]))) | ||
lib = os.path.join(os.path.dirname(bin), 'lib', 'python') | ||
|
||
site.addsitedir(lib) | ||
site.addsitedir(os.path.join(lib, 'site-packages')) | ||
|
||
import logging | ||
logging.basicConfig(format="%(asctime)s [%(levelname)s] - %(name)s - %(message)s") | ||
|
||
import gluconsole.rest | ||
from optparse import OptionParser | ||
|
||
def main(): | ||
log = logging.getLogger("glu") | ||
|
||
# current username | ||
user = getpass.getuser() | ||
|
||
# command line parsing | ||
usage = "usage: %prog <start|stop|load|status> [flags]" | ||
parser = OptionParser(usage=usage, version="%prog 0.2") | ||
|
||
# common options for all actions | ||
parser.add_option("-d", "--debug", dest="debug", | ||
action="store_true", default=False, | ||
help="Turn on debug output") | ||
|
||
parser.add_option("-c", "--console", dest="consoleurl", | ||
action="store", | ||
help="Url to GLU Console for the given fabric.") | ||
|
||
parser.add_option("-f", "--fabric", dest="fabric", | ||
action="store", | ||
help="Perform action on a fabric") | ||
|
||
parser.add_option("-U", "--user", dest="user", | ||
action="store", default=user, | ||
help="GLU user to use for authentication, defaults to " + user) | ||
|
||
parser.add_option("-x", "--xpassword", dest="password", | ||
action="store", | ||
help="Password. Warning password will appear in clear in ps output. Use only for testing.") | ||
|
||
parser.add_option("-X", "--xpasswordfile", dest="passwordfile", | ||
action="store", | ||
help="Read user password from passwordfile specified. Make sure to protect this file using unix permissions") | ||
|
||
# controlling start/stop actions | ||
parser.add_option("-a", "--all", dest="all", | ||
default=False, action="store_true", | ||
help="Perform action on all entries") | ||
|
||
parser.add_option("-H", "--host", dest="host", | ||
action="store", | ||
help="Perform action on one or more host(s)") | ||
|
||
parser.add_option("-I", "--instance", dest="instance", | ||
action="store", | ||
help="Perform action on one or more instance(s)") | ||
|
||
parser.add_option("-p", "--parallel", dest="parallel", | ||
action="store_true", default=False, | ||
help="Perform action on all instances in parallel. Default is serial.") | ||
|
||
parser.add_option("-n", "--dryrun", dest="dryrun", | ||
action="store_true", default=False, | ||
help="Do a dry run of your plan. No changes will be made. Default is false.") | ||
|
||
# options for status action | ||
parser.add_option("-s", "--systemFilter", dest="filter", | ||
action="store", | ||
help="Filter in DSL sytax for filtering the model. Applicable only with 'status' command. See 'Filter Syntax' section here: https://iwww.corp.linkedin.com/wiki/cf/display/ENGS/GLU+CLI+-+InDay+work ") | ||
|
||
parser.add_option("-S", "--systemFilterFile", dest="filterFile", | ||
action="store", | ||
help="Filter file with filters in DSL sytax for filtering the model. Applicable only with 'status' command. See 'Filter Syntax' section here: https://iwww.corp.linkedin.com/wiki/cf/display/ENGS/GLU+CLI+-+InDay+work ") | ||
|
||
parser.add_option("-l", "--live", dest="live", | ||
action="store_true", default=False, | ||
help="Show current model instead of expected model. Applicable only with 'status' command.") | ||
|
||
parser.add_option("-b", "--beautify", dest="beautify", | ||
action="store_true", default=False, | ||
help="Pretty print the model.") | ||
|
||
# options for load action | ||
parser.add_option("-u", "--url", dest="systemUrl", | ||
action="store", | ||
help="Required if loading new system. ex: file:/tmp/root/system.json or http://localhost/system.json") | ||
|
||
# get options provided on commandline. Remaining arg is 'action' | ||
(options, args) = parser.parse_args() | ||
if len(args) != 1: | ||
parser.error("One action must be specified") | ||
else: | ||
action=args[0] | ||
|
||
# validate options | ||
if not options.fabric: | ||
parser.error("Fabric must be specified") | ||
|
||
if not options.consoleurl: | ||
parser.error("Console URL must be specified") | ||
|
||
if options.debug: | ||
log.setLevel(logging.DEBUG) | ||
gluconsole.rest.log.setLevel(logging.DEBUG) | ||
|
||
if options.filter and options.filterFile: | ||
parser.error("Only filter or filterFile must be specified, not both.") | ||
|
||
# Only one of the following options can be specified. | ||
# FWIW, argparse supports mutually exclusive groups. | ||
exclusive_options = dict() | ||
|
||
if options.cluster: | ||
exclusive_options['cluster'] = True | ||
|
||
if options.appname: | ||
exclusive_options['appname'] = True | ||
|
||
if options.host: | ||
exclusive_options['host'] = True | ||
|
||
if options.instance: | ||
exclusive_options['instance'] = True | ||
|
||
if options.filter or options.filterFile: | ||
exclusive_options['filter'] = True | ||
|
||
if options.all: | ||
exclusive_options['all'] = True | ||
|
||
if len(exclusive_options.keys()) > 1: | ||
parser.error("Only one of: cluster, appname, host, instance, filter or all may be used.") | ||
|
||
# validate manifest loading options, make sure everything we need is specified | ||
manifestSpecified = False; | ||
if options.manifestrelease or options.manifesturl: | ||
manifestSpecified = True | ||
if not options.manifesturl: | ||
parser.error("Need to specify Manifest URL when specifying a release") | ||
if not options.manifestrelease: | ||
parser.error("Need to specify Manifest release when specifying a URL") | ||
if not options.product: | ||
parser.error("Need to specify Product when trying to load a new manifest") | ||
if action == "load" and not manifestSpecified: | ||
parser.error("Need to specify Manifest details for load action.") | ||
|
||
# get user's and password | ||
if options.password: | ||
password = options.password | ||
elif options.passwordfile: | ||
with open(options.passwordfile, 'r') as fh: | ||
password = fh.readline().strip() | ||
else: | ||
password = getpass.getpass("Enter " + options.user + "'s password: ") | ||
|
||
filter = None | ||
|
||
if options.filter: | ||
filter = options.filter | ||
|
||
if options.filterFile: | ||
with open(options.filterFile, 'r') as fh: | ||
filter = fh.read().strip() | ||
|
||
# create client to process the request | ||
log.info("Will run action '%s' on fabric '%s'" % (action, options.fabric)) | ||
|
||
client = gluconsole.rest.Client(fabric=options.fabric, url=options.consoleurl, username=options.user, password=password) | ||
|
||
# now perform the action | ||
result = "<unknown>" | ||
if action in ("start", "stop", "bounce", "deploy", "undeploy", "redeploy"): | ||
|
||
if manifestSpecified: | ||
if not client.loadModel(options.manifestrelease, options.manifesturl, options.product): | ||
log.critical("Model load failed") | ||
|
||
if filter is None: | ||
filter = client.generateSystemFilter(options.appname, options.cluster, options.host, options.instance) | ||
|
||
result = client.executePlan(action, filter, options.parallel, options.dryrun) | ||
|
||
elif action == "load": | ||
|
||
result = client.loadModel(options.manifestrelease, options.manifesturl, options.product) | ||
|
||
elif action == "status": | ||
|
||
if manifestSpecified: | ||
if not client.loadModel(options.manifestrelease, options.manifesturl, options.product): | ||
log.critical("Model load failed"); | ||
|
||
if filter is None: | ||
filter = client.generateSystemFilter(options.appname, options.cluster, options.host, options.instance) | ||
|
||
result = client.status(options.live, options.legacy, options.beautify, filter) | ||
|
||
else: | ||
parser.error("Unknown action: " + action) | ||
|
||
print result | ||
|
||
if __name__ == "__main__": | ||
main() |
15 changes: 15 additions & 0 deletions
15
console/org.linkedin.glu.console-cli/src/cmdline/resources/lib/python/gluconsole/__init__.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# | ||
# Copyright 2010-2010 LinkedIn, Inc | ||
# | ||
# 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 | ||
# | ||
# http://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. | ||
# |
Oops, something went wrong.