appops-client 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 34741d326116b6f8d420baba3367f9665ca89926
4
+ data.tar.gz: 3d7d3e37fdddb13d2c34beadc59b5e6fedec651d
5
+ SHA512:
6
+ metadata.gz: f9becd24dc1e34452112295f1a0c397a1eec7dfcd388c1a2fc1e6709d1705bf778bd872d5b552bd7d0ef7197e760f6f53a407bc314c18d0d3ca5c46c85c01ffd
7
+ data.tar.gz: cbc68918813623ced4f1105b562bd635090660dd33c94cb930c94857319f9f32fcf9f9be66e4330a17ace50b121862521c831e5f9c40c2e1a8922bcaa355ed9f
data/README.md ADDED
@@ -0,0 +1,25 @@
1
+ # appops-client
2
+ Application Operations client.
3
+
4
+ Use this to interact with the AppOps Service.
5
+
6
+ # Requirements
7
+
8
+ * Ruby >~ 2.0.0
9
+
10
+ # Install
11
+
12
+ @TODO: Add Gem location.
13
+
14
+ ```
15
+ gem install appops-client
16
+ ```
17
+
18
+ # Examples
19
+
20
+ ## Login
21
+
22
+ `appops login`
23
+
24
+ ## Create client key
25
+ `appops client create`
data/bin/appops-client ADDED
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env ruby
2
+ ##
3
+ # Main AppOps client.
4
+ #
5
+ FS_ROOT=File.expand_path('..', File.dirname( __FILE__ ))
6
+ CONFIG_ROOT=File.expand_path( "%s/.intuit/" % ENV['HOME'] )
7
+ $:.push File.expand_path( "lib/", FS_ROOT )
8
+ require "pp"
9
+ require "xml"
10
+ require "json"
11
+ require "thor"
12
+ require "logger"
13
+ require "rest-client"
14
+ require "securerandom"
15
+ require "appops-client/logger.rb"
16
+ require "appops-client/cli.rb"
17
+
18
+ begin
19
+ AppOpsClientLogger = AppOpsClient::Logger.new( STDOUT )
20
+ service_url = "http://192.168.248.130:8081/"
21
+ #service_url = "https://appops.us-east-1.preprod.mobile.a.intuit.com/"
22
+ AppOpsService = RestClient::Resource.new( service_url )
23
+
24
+ rescue => e
25
+ puts "Failed to get stuff: %s" % e
26
+ pp e.backtrace
27
+ exit
28
+
29
+ end
30
+
31
+ module AppOpsClient
32
+ module CLI
33
+
34
+ class Main < Thor
35
+ register( Client, 'client', 'client <command>', 'Client actions.')
36
+ register( Deployment, 'deployment', 'deployment <command>', 'Deployment actions.')
37
+ register( Application, 'app', 'app <command>', 'Application actions.')
38
+
39
+ #register(NewRelic, 'nr', 'nr <command>', 'New Relic stuff.')
40
+ register( NewRelic, 'new_relic', 'new_relic <command>', 'New Relic stuff.')
41
+
42
+ #register(Confluence, 'c', 'c <command>', 'Confluence interactions.')
43
+ register( Confluence, 'confluence', 'confluence <command>', 'Confluence interactions.')
44
+
45
+ register( CloudWatch, 'cloudwatch', 'cloudwatch <command>', 'CloudWatch interactions.')
46
+
47
+ ## Mobile Services
48
+ register( MTalk, 'mtalk', 'mtalk <command>', 'MTalk service interactions.' )
49
+
50
+ #register(Account, 'account', 'account <command>', 'Account stuff.')
51
+ #register(Deploy, 'deploy', 'deploy <command>', 'Deployment stuff.')
52
+ #register(Launcher, 'launch', 'launch <command>', 'Launch things.')
53
+ #register(CTOF, 'ctof', 'ctof <command>', 'CTOF stuff.')
54
+ #register(Deployment, 'deployment', 'deployment <command>', 'Deployment stuff.')
55
+ end
56
+
57
+ end
58
+ end
59
+
60
+ AppOpsClient::CLI::Main.start(ARGV)
@@ -0,0 +1,11 @@
1
+ ##
2
+ # AppOps
3
+ #
4
+
5
+ module AppOps
6
+ module CLI
7
+ end
8
+ end
9
+
10
+ ## TODO: this runs on magic.
11
+ Dir.glob( "%s/lib/appops-client/cli/*.rb" % FS_ROOT ).each{|f| require f }
@@ -0,0 +1,64 @@
1
+ ##
2
+ # Application actions.
3
+ #
4
+
5
+ module AppOpsClient
6
+ module CLI
7
+
8
+ class Application < Thor
9
+ namespace :appliction
10
+ desc "list", "List applications."
11
+ def list()
12
+ AppOpsService['api/1.0/applications/'].get({ :content_type => 'application/json' }) do |response, request, result, &block|
13
+ json = JSON::parse( response )
14
+ json["data"].each do |row|
15
+ AppOpsClientLogger.debug( row["_id"]["$oid"] ){ row["name"] }
16
+ end
17
+ end
18
+ end
19
+
20
+ desc "launch APPLICATION_NAME APPLICATION_VERSION ACCOUNT_NAME REGION_NAME", "Launch this application."
21
+ def launch( application_name, application_version, account_name, region_name )
22
+ AppOpsService['api/1.0/applications/%s/launch' % application_name].post({
23
+ app_version: application_version,
24
+ #inf_version: inf_version,
25
+ region_name: region_name,
26
+ account_name: account_name
27
+ #git_checksum: git_checksum
28
+ },{ :content_type => 'application/json' }) do |response, request, result, &block|
29
+ json = JSON::parse( response )
30
+ pp json
31
+ end
32
+ end
33
+
34
+ desc "show APP_NAME", "Application details."
35
+ def show( application_id )
36
+ AppOpsService['api/1.0/applications/%s' % application_id].get({ :content_type => 'application/json' }) do |response, request, result, &block|
37
+ json = JSON::parse( response )
38
+ pp json["data"]
39
+ end
40
+ end
41
+
42
+ desc "delete APP_ID", "Delete an application by application id."
43
+ def delete( application_id )
44
+ AppOpsService['api/1.0/applications/%s' % application_id].delete({ :content_type => 'application/json' }) do |response, request, result, &block|
45
+ json = JSON::parse( response )
46
+ AppOpsClientLogger.info( "Delete" ){ json }
47
+ end
48
+ end
49
+
50
+ desc "from file APP_NAME FILE_NAME", "Create an application from a file."
51
+ def from_file( file, application_name, file_name )
52
+ AppOpsClientLogger.debug( "Creating app from file" ){ [application_name, file_name] }
53
+ json = JSON::parse(File.read( file_name ))
54
+ AppOpsService['api/1.0/applications/'].post({ :data => json.to_json, :name => application_name }, { :content_type => 'application/json' }) do |response, request, result, &block|
55
+ json = JSON::parse( response )
56
+ pp json
57
+ end
58
+ end
59
+
60
+ end
61
+
62
+ end
63
+ end
64
+
@@ -0,0 +1,26 @@
1
+ ##
2
+ # AWS Account actions.
3
+ #
4
+
5
+ module AppOpsClient
6
+ module CLI
7
+
8
+ class AWS < Thor
9
+ namespace :aws
10
+ desc "list", "List accounts."
11
+ def list()
12
+ end
13
+
14
+ desc "show ACCOUNT", "Account name."
15
+ def show( name )
16
+ end
17
+
18
+ desc "rotate_keys", "Rotate security keys for the appops user."
19
+ def rotate_keys()
20
+ #AppOpsClient::AWS::IAMUserKeys::enforce( "Dev" )
21
+ end
22
+ end
23
+
24
+ end
25
+ end
26
+
@@ -0,0 +1,34 @@
1
+ ##
2
+ # Client actions.
3
+ #
4
+
5
+ module AppOpsClient
6
+ module CLI
7
+
8
+ class Client < Thor
9
+ namespace :client
10
+ desc "list", "List automation clients."
11
+ def list()
12
+ end
13
+
14
+ desc "login", "Login."
15
+ def login()
16
+ end
17
+
18
+ desc "logout", "Kill your session."
19
+ def logout()
20
+ end
21
+
22
+ desc "register", "Register an automation client.."
23
+ def register()
24
+ end
25
+
26
+ desc "show CLIENT", "Show details about a given client."
27
+ def show( client_name )
28
+ end
29
+
30
+ end
31
+
32
+ end
33
+ end
34
+
@@ -0,0 +1,23 @@
1
+ ##
2
+ # Updating Cloud Watch.
3
+ #
4
+
5
+ module AppOpsClient
6
+ module CLI
7
+
8
+ class CloudWatch < Thor
9
+ namespace :cloudwatch
10
+
11
+ desc "cloudwatch update", "Cloud watch updates."
12
+ def update()
13
+ AppOpsService['api/1.0/cloudwatch/update'].put({ :content_type => 'application/json' }) do |response, request, result, &block|
14
+ json = JSON::parse( response )
15
+ AppOpsClientLogger.debug( "Res" ){ json }
16
+ end
17
+ end
18
+
19
+ end ## NewRelic
20
+
21
+ end
22
+ end
23
+
@@ -0,0 +1,23 @@
1
+ ##
2
+ # Updating confluence.
3
+ #
4
+
5
+ module AppOpsClient
6
+ module CLI
7
+
8
+ class Confluence < Thor
9
+ namespace :confluence
10
+
11
+ desc "confluence update", "Fire off a job to update the wiki."
12
+ def update()
13
+ AppOpsService['api/1.0/confluence/update'].put({ :content_type => 'application/json' }) do |response, request, result, &block|
14
+ json = JSON::parse( response )
15
+ AppOpsClientLogger.debug( "Res" ){ json }
16
+ end
17
+ end
18
+
19
+ end ## NewRelic
20
+
21
+ end
22
+ end
23
+
@@ -0,0 +1,32 @@
1
+ ##
2
+ # CTOF 2014 whatever thing.
3
+ # appId:
4
+ # Intuit.developer.appops.appops
5
+ # secret:
6
+ # preprddTXU55O37KI0bkZvePqSIMGRBDNzNC2XZ3
7
+ # Internal URL:
8
+ # activityfeed-prf.platform.intuit.net
9
+ # External URL:
10
+ # activityfeed-prf.platform.intuit.com
11
+ #
12
+
13
+ module AppOpsClient
14
+ module CLI
15
+
16
+ class CTOF < Thor
17
+ namespace :ctof
18
+ desc "test", "Test junk."
19
+ def test()
20
+ #https://devinternal-prf.intuit.com:443/apip/remote/wbh4/v1/feed/5873
21
+ http = Net::HTTP.new( "devinternal-prf.intuit.com", "443" )
22
+ #Intuit_IAM_Authentication intuit_userid=12345,intuit_appid=Intuit.platform.qbodeveloper.testapp,intuit_app_secret=preprdvbgYUUxBx5SGqpPdOm3Iqhg38R6G7J75BO,id=5873
23
+ http.use_ssl = true
24
+ res = http.get( "/apip/remote/wbh4/v1/feed/5873" )
25
+ pp res.body
26
+ end
27
+
28
+ end
29
+
30
+ end
31
+ end
32
+
@@ -0,0 +1,41 @@
1
+ #!/bin/env ruby
2
+ ##
3
+ # Push things out to other things.
4
+ #
5
+
6
+ module AppOpsClient
7
+ module CLI
8
+
9
+ class Deploy < Thor
10
+ namespace :deploy
11
+ desc "encrypt DIR_NAME", "Encrypt stuff."
12
+ def encrypt( dir_name )
13
+ puts "Dir: %s" % dir_name
14
+ archive_name = "archive_%i.tar.bz" % Time.new.to_i
15
+ cmd_zip = "tar -cjpf %s %s" % [archive_name, dir_name]
16
+ cmd_enc = "openssl enc -kfile %s/.intuit/enc_key -aes-256-cbc -salt -in %s -out %s.enc" % [ENV['HOME'], archive_name, archive_name]
17
+ cmd_dec = "openssl enc -d -kfile %s/.intuit/enc_key -aes-256-cbc -salt -in %s.enc -out %s" % [ENV['HOME'], archive_name, archive_name]
18
+ cmd_push = "aws --profile mag-preprod s3 sync ./ s3://appops0/ --exclude \"*\" --include \"%s.enc\"" % archive_name
19
+
20
+ puts "CMD(push): %s" % cmd_push
21
+
22
+ ## Compress
23
+ puts "CMD(zip): %s" % cmd_zip
24
+ system( cmd_zip )
25
+
26
+ ## Encrypt
27
+ puts "CMD(enc): %s" % cmd_enc
28
+ system( cmd_enc )
29
+
30
+ #puts "CMD(dec): %s" % cmd_dec
31
+ end
32
+
33
+ desc "push ARCHIVE BUCKET_NAME", "Push something up to somewhere"
34
+ def publish( bucket_name )
35
+ end
36
+
37
+ end ## Deploy
38
+
39
+ end
40
+ end
41
+
@@ -0,0 +1,41 @@
1
+ ##
2
+ # Application actions.
3
+ #
4
+
5
+ module AppOpsClient
6
+ module CLI
7
+
8
+ class Deployment < Thor
9
+
10
+ namespace :deployment
11
+ desc "list", "List deployments."
12
+ def list()
13
+ AppOpsService['api/1.0/deployments/'].get({ :content_type => 'application/json' }) do |response, request, result, &block|
14
+ json = JSON::parse( response )
15
+ json["data"].each do |row|
16
+ AppOpsClientLogger.debug( "Row" ){ "%s-%s ( %s )" % [row["name"], row["version_name"], row["id"]] }
17
+ end
18
+ end
19
+ end
20
+
21
+ desc "show DEPLOYMENT_ID", "Deployment details."
22
+ def show( deployment_id )
23
+ AppOpsService['api/1.0/deployments/%s' % deployment_id].get({ :content_type => 'application/json' }) do |response, request, result, &block|
24
+ json = JSON::parse( response )
25
+ pp json
26
+ end
27
+ end
28
+
29
+ desc "launch APPLICATION_ID ACCOUNT_NAME REGION_NAME INF_VERSION GIT_CHECKSUM", "Deployment details."
30
+ def launch( application_id, account_name, region_name, inf_version, git_checksum )
31
+ AppOpsService['api/1.0/applications/%s/launch' % deployment_id].get({ :content_type => 'application/json' }) do |response, request, result, &block|
32
+ json = JSON::parse( response )
33
+ pp json
34
+ end
35
+ end
36
+
37
+ end
38
+
39
+ end
40
+ end
41
+
@@ -0,0 +1,102 @@
1
+ #!/bin/env ruby
2
+ ##
3
+ # Account actions
4
+ #
5
+
6
+ module AppOpsClient
7
+ module CLI
8
+
9
+ class Launcher< Thor
10
+ namespace :launch
11
+
12
+ desc "stack STACK_NAME ACCOUNT_NAME REGION_NAME TEMPLATE", "Launch something."
13
+ def stack( stack_name, account_name, region_name, template )
14
+ fs_root = "%s/dev/appops/cf_templates" % ENV['HOME']
15
+ account = AppOpsClientConfig.get( account_name )
16
+ AppOpsClientConfig.set_aws_config( account )
17
+ #pp AppOpsClientConfig.get( account_name )
18
+
19
+ fs_template_file = "%s/%s.json" % [fs_root, template]
20
+ if(!File.exists?( fs_template_file ))
21
+ puts "Unable to find template file: %s".red % fs_template_file
22
+ exit
23
+ else
24
+ puts "Found template file: %s".green % fs_template_file
25
+ end
26
+
27
+ params = {}
28
+
29
+ ## Add in the default KeyName.
30
+ params["KeyName"] = "appops"
31
+ params["DomainName"] = account["domain_name"]
32
+
33
+ ## Roll in the EncKey.
34
+ params["EncKey"] = File.read( "%s/.intuit/enc_key" % ENV['HOME'] )
35
+ params["AppOpsClientSecureUrl"] = "https://s3.amazonaws.com/appops0/archive_1393206113.bz2.enc"
36
+
37
+ template_json = JSON::parse(File.read( fs_template_file ))
38
+ template_json["Parameters"].each do |el|
39
+ if(el[1].has_key?( "Lookup" ))
40
+ lookup = el[1]["Lookup"]
41
+ filters = []
42
+ lookup["Filters"].each do |f|
43
+ filters.push({
44
+ name: f["name"],
45
+ values: f["values"]
46
+ })
47
+ end
48
+ #puts "Found lookup: %s" % lookup
49
+ t = Kernel.const_get( lookup["Type"] ).new()
50
+ key = (lookup.has_key?( "Key" ) ? lookup["Key"] : nil)
51
+ el[1].delete( "Lookup" )
52
+ el[1]["Default"] = t.get( filters, region_name, key, account_name )
53
+ end
54
+ end
55
+
56
+ ## Format for AWS.
57
+ params = params.map{|k,v| { :parameter_key => k, :parameter_value => v}}.compact
58
+
59
+ ## Look at the stack list.
60
+ AppOpsClientCache.cache.set( "stacks_%s_%s" % [account_name, region_name], nil )
61
+ cf = Aws::CloudFormation.new({ region: region_name })
62
+ summaries = AppOpsClientCache.get( "stacks_%s_%s" % [account_name, region_name], 900 ) do |keyname|
63
+ summaries = cf.list_stacks({ stack_status_filter: [ "CREATE_IN_PROGRESS", "CREATE_COMPLETE", "UPDATE_COMPLETE" ] }).stack_summaries
64
+ ro = []
65
+ summaries.each{|s| ro.push( s.to_hash )}
66
+ ro
67
+ end
68
+
69
+ ## If the stack already exists, update, otherwise create.
70
+ if(summaries.select{|s| s[:stack_name] == stack_name}.compact.size == 0)
71
+ puts "\tUnable to find current stack launching new for %s".yellow % stack_name
72
+ cf.create_stack({
73
+ stack_name: stack_name,
74
+ parameters: params,
75
+ capabilities: ["CAPABILITY_IAM"],
76
+ template_body: template_json.to_json
77
+ #notification_arns: [notification_arn]
78
+ })
79
+
80
+ else
81
+ begin
82
+ puts "\tFound active stack: %s".yellow % stack_name
83
+ cf.update_stack({
84
+ stack_name: stack_name,
85
+ parameters: params,
86
+ capabilities: ["CAPABILITY_IAM"],
87
+ template_body: template_json.to_json
88
+ })
89
+
90
+ rescue Aws::CloudFormation::Errors::ValidationError => e
91
+ puts "Caught exception: %s" % e
92
+
93
+ end
94
+
95
+ end
96
+
97
+ end ## launch
98
+ end
99
+
100
+ end
101
+ end
102
+
@@ -0,0 +1,44 @@
1
+ ##
2
+ # mTalk service handlers.
3
+ #
4
+
5
+ module AppOpsClient
6
+ module CLI
7
+
8
+ class MTalk < Thor
9
+ namespace :mtalk
10
+ desc "check_amq", "Check the AMQ status."
11
+ def check_amq()
12
+ ## Hostnames
13
+ ## TODO: reach out to opsconsole for this data.
14
+ port = 8161
15
+ hosts = [ "pprdsmsas406.ie.intuit.net" ]
16
+
17
+ hosts.each do |hostname|
18
+ http = Net::HTTP.new( hostname, port )
19
+ res = http.get( "/admin/xml/queues.jsp" )
20
+ if(res.code.to_i == 200)
21
+ AppOpsClientLogger.info( "Queue check successful" ){ hostname }
22
+ xml = LibXML::XML::Parser.string( res.body ).parse
23
+ xml.find( "//queue" ).each do |q|
24
+ q_name = q.attributes.get_attribute( "name" )
25
+ q.children.each do |child|
26
+ next if(child.name != "stats")
27
+ q_size = child.attributes.get_attribute( "size" ).value.to_i
28
+ q_consumer_count = child.attributes.get_attribute( "consumerCount" ).value.to_i
29
+ q_enqueue_count = child.attributes.get_attribute( "enqueueCount" ).value.to_i
30
+ q_dequeue_count = child.attributes.get_attribute( "dequeueCount" ).value.to_i
31
+ AppOpsClientLogger.debug( "Metrics for %s" % q_name ){ [q_size, q_consumer_count, q_enqueue_count, q_dequeue_count] }
32
+ end
33
+ end
34
+ else
35
+ AppOpsClientLogger.error( "Queue check unsuccessful" ){ res.code }
36
+ end
37
+ end
38
+ end
39
+
40
+ end
41
+
42
+ end
43
+ end
44
+
@@ -0,0 +1,33 @@
1
+ ##
2
+ # New Relic interactions
3
+ #
4
+ require 'uri'
5
+ require 'openssl'
6
+ require 'net/http'
7
+
8
+ module AppOpsClient
9
+ module CLI
10
+
11
+ class NewRelic < Thor
12
+ namespace :new_relic
13
+
14
+ #desc "new_relic list_apps", "List applications"
15
+ #def list_apps()
16
+ #AppOpsClientStore.collection( "new_relic_cache" ).find().each do |app|
17
+ #AppOpsClientLogger.info( app["application"]["id"] ){ app["application"]["name"] }
18
+ #end
19
+ #end
20
+
21
+ desc "new_relic update", "Fire off a job to update the NR stats."
22
+ def update()
23
+ AppOpsService['api/1.0/new_relic/update'].put({ :content_type => 'application/json' }) do |response, request, result, &block|
24
+ json = JSON::parse( response )
25
+ AppOpsClientLogger.debug( "Res" ){ json }
26
+ end
27
+ end
28
+
29
+ end ## NewRelic
30
+
31
+ end
32
+ end
33
+
@@ -0,0 +1,33 @@
1
+ ##
2
+ # AppOps logger
3
+ #
4
+ module AppOpsClient
5
+ class Logger < Logger
6
+ @intuit_tid
7
+
8
+ def initialize(logdev, shift_age = 0, shift_size = 1048576)
9
+ @intuit_tid = SecureRandom.uuid
10
+ super logdev, shift_age, shift_size
11
+ end
12
+
13
+ def add( severity, msg = nil, progname = nil, &block )
14
+ #puts "Adding message %s :: %s :: %s" % [severity, msg, progname]
15
+ subject = "LogEntry"
16
+ message = progname
17
+
18
+ if(block_given?)
19
+ message = yield
20
+ subject = progname
21
+ end
22
+
23
+ #AppOpsStore.collection( "activity_logs" ).insert({
24
+ #ts: Time.new.to_f,
25
+ #message: message,
26
+ #subject: subject,
27
+ #intuit_tid: @intuit_tid
28
+ #})
29
+ super severity, message, progname, &block
30
+ end
31
+
32
+ end ## Logger
33
+ end ## AppOps
@@ -0,0 +1,6 @@
1
+ ##
2
+ # Version
3
+
4
+ module AppOpsClient
5
+ Version = "0.0.4"
6
+ end
metadata ADDED
@@ -0,0 +1,61 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: appops-client
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.4
5
+ platform: ruby
6
+ authors:
7
+ - Bryan Kroger
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-05-21 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Client interface with AppOps service.
14
+ email:
15
+ - bryan_kroger@intuit.com
16
+ executables:
17
+ - appops-client
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - README.md
22
+ - bin/appops-client
23
+ - lib/appops-client/cli.rb
24
+ - lib/appops-client/cli/application.rb
25
+ - lib/appops-client/cli/aws.rb
26
+ - lib/appops-client/cli/client.rb
27
+ - lib/appops-client/cli/cloudwatch.rb
28
+ - lib/appops-client/cli/confluence.rb
29
+ - lib/appops-client/cli/ctof.rb
30
+ - lib/appops-client/cli/deploy.rb
31
+ - lib/appops-client/cli/deployment.rb
32
+ - lib/appops-client/cli/launcher.rb
33
+ - lib/appops-client/cli/mtalk.rb
34
+ - lib/appops-client/cli/new_relic.rb
35
+ - lib/appops-client/logger.rb
36
+ - lib/appops-client/version.rb
37
+ homepage: http://wiki.intuit.com/
38
+ licenses: []
39
+ metadata: {}
40
+ post_install_message:
41
+ rdoc_options: []
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ requirements:
55
+ - rest-client
56
+ rubyforge_project:
57
+ rubygems_version: 2.2.1
58
+ signing_key:
59
+ specification_version: 4
60
+ summary: AppOps client.
61
+ test_files: []