openshift 0.60.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Error codes.txt +15 -0
- data/bin/os +42 -0
- data/bin/os-add-cartridge +190 -0
- data/bin/os-clone-application +175 -0
- data/bin/os-create-application +306 -0
- data/bin/os-create-environment +306 -0
- data/bin/os-delete-application +141 -0
- data/bin/os-delete-environment +140 -0
- data/bin/os-deregister-cloud +124 -0
- data/bin/os-help +108 -0
- data/bin/os-inspect-application +222 -0
- data/bin/os-list-applications +139 -0
- data/bin/os-list-cartridges +182 -0
- data/bin/os-list-clouds +137 -0
- data/bin/os-list-environments +188 -0
- data/bin/os-list-servers +122 -0
- data/bin/os-open-console +162 -0
- data/bin/os-register-cloud +181 -0
- data/bin/os-remove-cartridge +170 -0
- data/bin/os-restart-application +147 -0
- data/bin/os-start-application +147 -0
- data/bin/os-start-environment +144 -0
- data/bin/os-stop-application +147 -0
- data/bin/os-stop-environment +144 -0
- data/bin/os-tail-logs +159 -0
- data/conf/openshift.conf +5 -0
- data/lib/openshift.rb +666 -0
- metadata +192 -0
data/Error codes.txt
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
-1: ^C quit
|
2
|
+
|
3
|
+
-100: Error parsing arguments
|
4
|
+
-101: Missing parameters
|
5
|
+
|
6
|
+
-200: object not found
|
7
|
+
-201: Multiple objects with same name. Ambiguous choice
|
8
|
+
-218: Server not reachable
|
9
|
+
-219: Incomplete operation
|
10
|
+
|
11
|
+
-300: Unknown server communication error
|
12
|
+
-301: Generic server side error
|
13
|
+
|
14
|
+
-400: Error parsing data from sub-command
|
15
|
+
-401: Invalid credentials
|
data/bin/os
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Copyright 2010 Red Hat, Inc.
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person
|
5
|
+
# obtaining a copy of this software and associated documentation files
|
6
|
+
# (the "Software"), to deal in the Software without restriction,
|
7
|
+
# including without limitation the rights to use, copy, modify, merge,
|
8
|
+
# publish, distribute, sublicense, and/or sell copies of the Software,
|
9
|
+
# and to permit persons to whom the Software is furnished to do so,
|
10
|
+
# subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
19
|
+
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
20
|
+
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
21
|
+
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
22
|
+
# SOFTWARE.
|
23
|
+
|
24
|
+
require 'openshift'
|
25
|
+
|
26
|
+
print "Redhat Openshift Cloud Platform\n\n"
|
27
|
+
|
28
|
+
begin
|
29
|
+
command = ARGV.shift
|
30
|
+
cmdArgs = ["os-#{command.downcase}"] + ARGV
|
31
|
+
cmd = cmdArgs.join(' ')
|
32
|
+
exec( cmd )
|
33
|
+
rescue Exception => e
|
34
|
+
print e
|
35
|
+
exec( "os-help" )
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
|
40
|
+
|
41
|
+
|
42
|
+
|
@@ -0,0 +1,190 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Copyright 2010 Red Hat, Inc.
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person
|
5
|
+
# obtaining a copy of this software and associated documentation files
|
6
|
+
# (the "Software"), to deal in the Software without restriction,
|
7
|
+
# including without limitation the rights to use, copy, modify, merge,
|
8
|
+
# publish, distribute, sublicense, and/or sell copies of the Software,
|
9
|
+
# and to permit persons to whom the Software is furnished to do so,
|
10
|
+
# subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
19
|
+
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
20
|
+
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
21
|
+
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
22
|
+
# SOFTWARE.
|
23
|
+
|
24
|
+
require 'openshift'
|
25
|
+
|
26
|
+
def usage
|
27
|
+
puts <<USAGE
|
28
|
+
== Synopsis
|
29
|
+
|
30
|
+
os-add-cartridge: Adds a software cartridge and loads initial configuration
|
31
|
+
into the application.
|
32
|
+
|
33
|
+
== Usage
|
34
|
+
|
35
|
+
os add-cartridge [options] APP CARTRIDGES
|
36
|
+
|
37
|
+
-u|--username USERNAME:
|
38
|
+
Redhat Login (RHN or OpenShift login with OpenShift Flex access).
|
39
|
+
|
40
|
+
-p|--password PASSWORD:
|
41
|
+
Redhat Password.
|
42
|
+
|
43
|
+
-e|--environment ID:
|
44
|
+
The ID of the environment that is hosting the application. This is an optional
|
45
|
+
argument to disambiguate the application name.
|
46
|
+
|
47
|
+
-h|--help:
|
48
|
+
Prints this message
|
49
|
+
|
50
|
+
APP: The application name or application GUID
|
51
|
+
|
52
|
+
CARTRIDGES: Comma seperated list of cartridges to add to the application
|
53
|
+
USAGE
|
54
|
+
end
|
55
|
+
|
56
|
+
opts = GetoptLong.new(
|
57
|
+
["--username", "-u", GetoptLong::REQUIRED_ARGUMENT],
|
58
|
+
["--password", "-p", GetoptLong::REQUIRED_ARGUMENT],
|
59
|
+
["--environment", "-e", GetoptLong::REQUIRED_ARGUMENT],
|
60
|
+
["--debug", GetoptLong::NO_ARGUMENT],
|
61
|
+
["--help", "-h", GetoptLong::NO_ARGUMENT],
|
62
|
+
["--sso", GetoptLong::REQUIRED_ARGUMENT],
|
63
|
+
["--target", "-t", GetoptLong::REQUIRED_ARGUMENT]
|
64
|
+
)
|
65
|
+
args = {}
|
66
|
+
begin
|
67
|
+
opts.each{ |k,v| args[k]=v }
|
68
|
+
rescue GetoptLong::Error => e
|
69
|
+
usage
|
70
|
+
exit -100
|
71
|
+
end
|
72
|
+
|
73
|
+
flex_server = conf('flex_server')
|
74
|
+
app_name = ARGV.shift
|
75
|
+
environment_id = args['--environment']
|
76
|
+
@debug = true if args['--debug']
|
77
|
+
carts = ARGV.shift
|
78
|
+
|
79
|
+
if args['--help'] or app_name.nil? or app_name == "" or carts.nil? or carts == ""
|
80
|
+
usage
|
81
|
+
exit -101
|
82
|
+
end
|
83
|
+
|
84
|
+
args['--target'] = conf('default_target') || 'flex' if args['--target'].nil? or args['--target']==""
|
85
|
+
debug args['--target']
|
86
|
+
|
87
|
+
if args['--target'] == 'flex'
|
88
|
+
cookie = args['--sso']
|
89
|
+
if !cookie
|
90
|
+
username = args['--username'] || conf("username") || Openshift::IO.prompt("Redhat username",[],Openshift::Validation.method(:check_login))
|
91
|
+
password = args['--password'] || Openshift::IO.prompt("Redhat password",nil,nil,true,false)
|
92
|
+
csay("Logging into Openshift Flex as #{username}\n",:message)
|
93
|
+
cookie=Openshift.login(@http,username,password)
|
94
|
+
end
|
95
|
+
|
96
|
+
candidates=nil
|
97
|
+
begin
|
98
|
+
environment_info = "--environment #{environment_id}" if environment_id
|
99
|
+
debug "Invoking os-inspect-application --sso \"#{cookie}\" --porcelin #{environment_info} #{app_name}"
|
100
|
+
candidates = JSON.parse(`os-inspect-application --sso \"#{cookie}\" --porcelin #{environment_info} #{app_name}`)
|
101
|
+
rescue JSON::ParserError => e
|
102
|
+
debug e.message
|
103
|
+
csay("Unable to load application data from server\n.",:error)
|
104
|
+
exit -400
|
105
|
+
end
|
106
|
+
|
107
|
+
if candidates.size == 0
|
108
|
+
csay("No application found with specified name or guid.\n",:error)
|
109
|
+
usage
|
110
|
+
exit -200
|
111
|
+
end
|
112
|
+
|
113
|
+
if candidates.size > 1
|
114
|
+
csay("Ambiguous application. Please consider specifing environment id and/or application guid.\n",:warn)
|
115
|
+
usage
|
116
|
+
exit -201
|
117
|
+
end
|
118
|
+
|
119
|
+
environment = candidates[0]["environment"]
|
120
|
+
app = candidates[0]["application"]
|
121
|
+
|
122
|
+
cart_data = nil
|
123
|
+
begin
|
124
|
+
debug "Invoking os-list-cartridges --sso \"#{cookie}\" --porcelin --environment #{environment["id"]} #{app["guid"]}"
|
125
|
+
cart_data = JSON.parse(`os-list-cartridges --sso "#{cookie}" --porcelin --environment #{environment['id']} #{app['guid']}`)
|
126
|
+
rescue JSON::ParserError => e
|
127
|
+
debug e.message
|
128
|
+
csay("Unable to retrieve a list of cartridges from the server\n.",:error)
|
129
|
+
exit -400
|
130
|
+
end
|
131
|
+
|
132
|
+
avail = cart_data['available']
|
133
|
+
installed = cart_data['installed']
|
134
|
+
|
135
|
+
debug "hi 1\n"
|
136
|
+
|
137
|
+
carts_to_install = []
|
138
|
+
new_carts = carts.split(",")
|
139
|
+
new_carts.each{ |ncart|
|
140
|
+
cart_obj = nil
|
141
|
+
avail.each{ |cart|
|
142
|
+
if cart["name"] == ncart
|
143
|
+
cart_obj = cart
|
144
|
+
break
|
145
|
+
end
|
146
|
+
}
|
147
|
+
if cart_obj
|
148
|
+
debug "Adding cart:"
|
149
|
+
debug cart_obj
|
150
|
+
carts_to_install += [cart_obj]
|
151
|
+
else
|
152
|
+
csay("Unknown cartridge #{ncart}. Please verify the name against the list of available cartridges\n",:warn)
|
153
|
+
end
|
154
|
+
}
|
155
|
+
|
156
|
+
say("Configuring dependencies for application ")
|
157
|
+
csay("#{app['name']} ",:emphasis)
|
158
|
+
say("... ")
|
159
|
+
uri = URI.parse("https://#{environment['dns']}:4242/applications/#{app['guid']}/cartridges")
|
160
|
+
response = Openshift::Rest.put(@http, uri, { "cartridges" => JSON.generate(carts_to_install+installed) },
|
161
|
+
nil, {'user' => environment['username'], 'password' => environment['password']})
|
162
|
+
case response
|
163
|
+
when Net::HTTPSuccess
|
164
|
+
csay("[OK]",:conf)
|
165
|
+
else
|
166
|
+
debug "HTTP code: #{response.code}"
|
167
|
+
debug response.body
|
168
|
+
csay("[ERROR]",:error)
|
169
|
+
messages = JSON.parse(response.body)
|
170
|
+
csay("Unable to set application cartridges due to error. Message: #{messages['messages'][0]['description']}",:error)
|
171
|
+
exit -301
|
172
|
+
end
|
173
|
+
|
174
|
+
say("Committing changes to git... ")
|
175
|
+
uri = URI.parse("https://#{environment['dns']}:4242/applications/#{app['guid']}/tree/.vostok/revisions")
|
176
|
+
response = Openshift::Rest.post(@http, uri, {"untracked" => "true"}, nil, {'user' => environment['username'], 'password' => environment['password']})
|
177
|
+
case response
|
178
|
+
when Net::HTTPSuccess
|
179
|
+
csay("[OK]",:conf)
|
180
|
+
else
|
181
|
+
debug "HTTP code: #{response.code}"
|
182
|
+
debug response.body
|
183
|
+
csay("[ERROR]",:error)
|
184
|
+
messages = JSON.parse(response.body)
|
185
|
+
csay("Unable to commit configuration file changes. Message: #{messages['messages'][0]['description']}",:error)
|
186
|
+
exit -301
|
187
|
+
end
|
188
|
+
else
|
189
|
+
csay("Application dependencies can only be added for the Openshift Flex application.\n",:red)
|
190
|
+
end
|
@@ -0,0 +1,175 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Copyright 2010 Red Hat, Inc.
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person
|
5
|
+
# obtaining a copy of this software and associated documentation files
|
6
|
+
# (the "Software"), to deal in the Software without restriction,
|
7
|
+
# including without limitation the rights to use, copy, modify, merge,
|
8
|
+
# publish, distribute, sublicense, and/or sell copies of the Software,
|
9
|
+
# and to permit persons to whom the Software is furnished to do so,
|
10
|
+
# subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
19
|
+
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
20
|
+
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
21
|
+
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
22
|
+
# SOFTWARE.
|
23
|
+
|
24
|
+
require 'openshift'
|
25
|
+
|
26
|
+
def usage
|
27
|
+
puts <<USAGE
|
28
|
+
== Synopsis
|
29
|
+
|
30
|
+
os-clone-application: Clone the application repository into a new directory.
|
31
|
+
|
32
|
+
== Usage
|
33
|
+
|
34
|
+
os clone-application [options] APP [DIR]
|
35
|
+
|
36
|
+
-u|--username USERNAME:
|
37
|
+
Redhat Login (RHN or OpenShift login).
|
38
|
+
|
39
|
+
-p|--password PASSWORD:
|
40
|
+
Redhat Password.
|
41
|
+
|
42
|
+
-t|--target flex|express
|
43
|
+
Choose the cloud platform to clone the application from.
|
44
|
+
|
45
|
+
-e|--environment ID:
|
46
|
+
The ID of the environment that is hosting the application. This is an optional
|
47
|
+
argument to disambiguate the application name. This argument only applies
|
48
|
+
to Openshift Flex environments
|
49
|
+
|
50
|
+
-h|--help:
|
51
|
+
Prints this message
|
52
|
+
|
53
|
+
APP: The application name or application GUID
|
54
|
+
|
55
|
+
DIR: Directory to clone application into
|
56
|
+
USAGE
|
57
|
+
end
|
58
|
+
|
59
|
+
opts = GetoptLong.new(
|
60
|
+
["--username", "-u", GetoptLong::REQUIRED_ARGUMENT],
|
61
|
+
["--password", "-p", GetoptLong::REQUIRED_ARGUMENT],
|
62
|
+
["--environment", "-e", GetoptLong::REQUIRED_ARGUMENT],
|
63
|
+
["--help", "-h", GetoptLong::NO_ARGUMENT],
|
64
|
+
["--debug", GetoptLong::NO_ARGUMENT],
|
65
|
+
["--sso", GetoptLong::REQUIRED_ARGUMENT],
|
66
|
+
["--target", "-t", GetoptLong::REQUIRED_ARGUMENT]
|
67
|
+
)
|
68
|
+
|
69
|
+
args = {}
|
70
|
+
begin
|
71
|
+
opts.each{ |k,v| args[k]=v }
|
72
|
+
rescue GetoptLong::Error => e
|
73
|
+
usage
|
74
|
+
exit -100
|
75
|
+
end
|
76
|
+
|
77
|
+
app_name = ARGV.shift
|
78
|
+
clone_dir = ARGV.shift
|
79
|
+
@debug = true if args['--debug']
|
80
|
+
|
81
|
+
if args['--help'] or app_name.nil? or app_name == ""
|
82
|
+
usage
|
83
|
+
exit -101
|
84
|
+
end
|
85
|
+
|
86
|
+
args['--target'] = conf('default_target') || 'flex' if args['--target'].nil? or args['--target']==""
|
87
|
+
debug args['--target']
|
88
|
+
|
89
|
+
if args['--target'] == 'flex'
|
90
|
+
flex_server = conf('flex_server')
|
91
|
+
environment_id = args['--environment']
|
92
|
+
cookie = args['--sso']
|
93
|
+
|
94
|
+
if !cookie
|
95
|
+
username = args['--username'] || conf("username") || Openshift::IO.prompt("Redhat username",[],Openshift::Validation.method(:check_login))
|
96
|
+
password = args['--password'] || Openshift::IO.prompt("Redhat password",nil,nil,true,false)
|
97
|
+
csay("Logging into Openshift Flex as #{username}\n",:message)
|
98
|
+
cookie=Openshift.login(@http,username,password)
|
99
|
+
end
|
100
|
+
|
101
|
+
candidates=nil
|
102
|
+
begin
|
103
|
+
environment_info = "--environment #{environment_id}" if environment_id
|
104
|
+
debug "Invoking os-inspect-application --sso \"#{cookie}\" --porcelin #{environment_info} #{app_name}"
|
105
|
+
candidates = JSON.parse(`os-inspect-application --sso \"#{cookie}\" --porcelin #{environment_info} #{app_name}`)
|
106
|
+
rescue JSON::ParserError => e
|
107
|
+
debug e.message
|
108
|
+
csay("Unable to load application data from server\n.",:error)
|
109
|
+
exit -400
|
110
|
+
end
|
111
|
+
|
112
|
+
if candidates.size == 0
|
113
|
+
csay("No application found with specified name or guid.\n",:error)
|
114
|
+
usage
|
115
|
+
exit -200
|
116
|
+
end
|
117
|
+
|
118
|
+
if candidates.size > 1
|
119
|
+
csay("Ambiguous application. Please consider specifing environment id and/or application guid.\n",:error)
|
120
|
+
usage
|
121
|
+
exit -201
|
122
|
+
end
|
123
|
+
|
124
|
+
environment = candidates[0]["environment"]
|
125
|
+
app = candidates[0]["application"]
|
126
|
+
|
127
|
+
clone_dir = app['name'] if clone_dir.nil? or clone_dir == ""
|
128
|
+
|
129
|
+
if not File.readable?(@libra_kfile)
|
130
|
+
csay("Generating OpenShift Express ssh key to #{@libra_kfile}",:message)
|
131
|
+
debug "Invoking ssh-keygen -t rsa -f '#{@libra_kfile}'"
|
132
|
+
system("ssh-keygen -t rsa -f '#{@libra_kfile}'")
|
133
|
+
end
|
134
|
+
ssh_key = File.open(@libra_kpfile).gets.chomp.split(' ')[1]
|
135
|
+
|
136
|
+
csay("\nRetrieving environment SSH keys... ")
|
137
|
+
uri = URI.parse("https://#{environment['dns']}:4242/security/keys")
|
138
|
+
response = Openshift::Rest.get(@http, uri, nil, nil, {'user' => environment['username'], 'password' => environment['password']})
|
139
|
+
case response
|
140
|
+
when Net::HTTPSuccess
|
141
|
+
csay("[OK]",:conf)
|
142
|
+
else
|
143
|
+
debug "HTTP code: #{response.code}"
|
144
|
+
debug response.body
|
145
|
+
csay("[ERROR]",:error)
|
146
|
+
csay("Unable to retrieve environment ssh-keys. Message: #{data['error']}",:error)
|
147
|
+
exit -301
|
148
|
+
end
|
149
|
+
|
150
|
+
data = nil
|
151
|
+
data = JSON.parse(response.body)
|
152
|
+
keys = data['keys']
|
153
|
+
if not keys.index(ssh_key)
|
154
|
+
csay("\nUploading ssh-key to environment... ")
|
155
|
+
uri = URI.parse("https://#{environment['dns']}:4242/security/keys")
|
156
|
+
response = Openshift::Rest.post(@http, uri, {'type'=>'ssh-rsa','identifier'=>'', 'key'=>ssh_key}, nil, {'user' => environment['username'], 'password' => environment['password']})
|
157
|
+
case response
|
158
|
+
when Net::HTTPSuccess
|
159
|
+
csay("[OK]",:conf)
|
160
|
+
else
|
161
|
+
debug "HTTP code: #{response.code}"
|
162
|
+
debug response.body
|
163
|
+
csay("[ERROR]",:error)
|
164
|
+
csay("Unable to update ssh keys on environment. Please use environment admin password when prompted below",:error)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
csay("Cloning application ")
|
169
|
+
csay("#{app['name']} ",:emphasis)
|
170
|
+
csay("to directory ")
|
171
|
+
csay("#{clone_dir}",:emphasis)
|
172
|
+
Openshift::Git.clone("ssh://admin@#{environment['dns']}/mnt/glusterfs/web-apps/#{app['guid']}/repository",clone_dir,'flex')
|
173
|
+
else
|
174
|
+
csay("This feature is currently not implemented for Openshift Express applications.\n",:red)
|
175
|
+
end
|
@@ -0,0 +1,306 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Copyright 2010 Red Hat, Inc.
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person
|
5
|
+
# obtaining a copy of this software and associated documentation files
|
6
|
+
# (the "Software"), to deal in the Software without restriction,
|
7
|
+
# including without limitation the rights to use, copy, modify, merge,
|
8
|
+
# publish, distribute, sublicense, and/or sell copies of the Software,
|
9
|
+
# and to permit persons to whom the Software is furnished to do so,
|
10
|
+
# subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
19
|
+
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
20
|
+
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
21
|
+
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
22
|
+
# SOFTWARE.
|
23
|
+
|
24
|
+
require 'openshift'
|
25
|
+
|
26
|
+
def usage
|
27
|
+
puts <<USAGE
|
28
|
+
== Synopsis
|
29
|
+
|
30
|
+
os-create-application: Creates a new application on an exisitng environemnt.
|
31
|
+
|
32
|
+
== Usage
|
33
|
+
|
34
|
+
os create-application [options] [NAME] [CHECKOUT_DIR]
|
35
|
+
|
36
|
+
-u|--username
|
37
|
+
Redhat Login (RHN or OpenShift login with OpenShift Express access)
|
38
|
+
|
39
|
+
-p|--password
|
40
|
+
Redhat Password
|
41
|
+
|
42
|
+
-t|--target flex|express
|
43
|
+
Choose the cloud platform to create the application on.
|
44
|
+
|
45
|
+
-v|--version
|
46
|
+
Version string for application (alpha numeric, default: 1.0)
|
47
|
+
|
48
|
+
-m|--template TEMPLATE
|
49
|
+
Sets up basic cartridges for the application.
|
50
|
+
Flex: #{Openshift::Flex.templates.keys.join(", ")}
|
51
|
+
|
52
|
+
-c|--environment CLUSTER_ID:
|
53
|
+
The ID of the environment that will host the application.
|
54
|
+
|
55
|
+
--import-archive FILE
|
56
|
+
Import an existing VPM file or compressed application artifacts.
|
57
|
+
|
58
|
+
-n|--no-git
|
59
|
+
Disables git clone of application files.
|
60
|
+
|
61
|
+
-h|--help
|
62
|
+
Prints this message
|
63
|
+
|
64
|
+
NAME: The name of the new application
|
65
|
+
CHECKOUT_DIR: The directory to clone the application into
|
66
|
+
USAGE
|
67
|
+
end
|
68
|
+
|
69
|
+
def create_flex_environment(args,cookie)
|
70
|
+
args.delete('--target')
|
71
|
+
args.delete('--username')
|
72
|
+
args.delete('--password')
|
73
|
+
args.delete('--environment')
|
74
|
+
args.delete('--sso')
|
75
|
+
args = JSON.generate(args)
|
76
|
+
args.gsub!(/(["\\])/, '\\\\\1')
|
77
|
+
exec( "os-create-environment --target flex --sso \"#{cookie}\" --new-application \"#{args}\"" )
|
78
|
+
end
|
79
|
+
|
80
|
+
begin
|
81
|
+
opts = GetoptLong.new(
|
82
|
+
["--username", "-u", GetoptLong::REQUIRED_ARGUMENT],
|
83
|
+
["--password", "-p", GetoptLong::REQUIRED_ARGUMENT],
|
84
|
+
["--sso", GetoptLong::REQUIRED_ARGUMENT],
|
85
|
+
["--environment", "-e", GetoptLong::REQUIRED_ARGUMENT],
|
86
|
+
["--target", "-t", GetoptLong::REQUIRED_ARGUMENT],
|
87
|
+
["--version", "-v", GetoptLong::REQUIRED_ARGUMENT],
|
88
|
+
["--template", "-m", GetoptLong::REQUIRED_ARGUMENT],
|
89
|
+
["--no-git", "-n", GetoptLong::NO_ARGUMENT],
|
90
|
+
["--import-archive", "-a", GetoptLong::REQUIRED_ARGUMENT],
|
91
|
+
["--debug", GetoptLong::NO_ARGUMENT],
|
92
|
+
["--help", "-h", GetoptLong::NO_ARGUMENT]
|
93
|
+
)
|
94
|
+
rescue Exception => e
|
95
|
+
puts e.message
|
96
|
+
end
|
97
|
+
|
98
|
+
args = {}
|
99
|
+
begin
|
100
|
+
opts.each{ |k,v| args[k]=v }
|
101
|
+
rescue GetoptLong::Error => e
|
102
|
+
usage
|
103
|
+
exit -100
|
104
|
+
end
|
105
|
+
|
106
|
+
if args['--help']
|
107
|
+
usage
|
108
|
+
exit
|
109
|
+
end
|
110
|
+
|
111
|
+
app_name = ARGV.shift
|
112
|
+
clone_dir = ARGV.shift
|
113
|
+
@debug = true if args['--debug']
|
114
|
+
debug "Application name: #{app_name}, Clone dir: #{clone_dir}"
|
115
|
+
|
116
|
+
args['--target'] = conf('default_target') || 'flex' if args['--target'].nil? or args['--target']==""
|
117
|
+
debug "Target platform #{args['--target']}"
|
118
|
+
|
119
|
+
if args['--target'] == 'flex'
|
120
|
+
flex_server = conf('flex_server')
|
121
|
+
cookie = args['--sso']
|
122
|
+
if !cookie
|
123
|
+
username = args['--username'] || conf("username") || Openshift::IO.prompt("Redhat username",[],Openshift::Validation.method(:check_login))
|
124
|
+
password = args['--password'] || Openshift::IO.prompt("Redhat password",nil,nil,true,false)
|
125
|
+
csay("Logging into Openshift Flex as #{username}\n",:message)
|
126
|
+
cookie=Openshift.login(@http,username,password)
|
127
|
+
end
|
128
|
+
|
129
|
+
environment_id = args['--environment']
|
130
|
+
environments = JSON.parse(`os-list-environments --sso "#{cookie}" --porcelin`)
|
131
|
+
if not environment_id
|
132
|
+
if environments.size == 0
|
133
|
+
csay("You have no existing environments, this wizard will help you create a cloud and Flex environment to host your applications\n", :message)
|
134
|
+
create_flex_environment(args,cookie)
|
135
|
+
end
|
136
|
+
|
137
|
+
menu = environments + [{'id'=>"n", 'name'=>'New envionment'}]
|
138
|
+
csay("Select an envionment to host the new application or select 'n' to create a new envionment", :message)
|
139
|
+
Openshift::Formatter.table(["Environment Id","Name","Cloud", "DNS", "Load balancer", "Location", "State", "# Nodes"],
|
140
|
+
['id','name','cloud-account-name', 'dns', 'load-balancer-address','location','cluster-status','num-nodes'],
|
141
|
+
[16,15,20,40,20,15,10,10],
|
142
|
+
menu)
|
143
|
+
environment_id = Openshift::IO.prompt("Environment Id", menu.map{|c| c['id'].to_s})
|
144
|
+
end
|
145
|
+
create_flex_environment(args,cookie) if environment_id.downcase == 'n'
|
146
|
+
environment = environments.find_all{|c| c['id'].to_s == environment_id.to_s}[0]
|
147
|
+
environment_dns = environment['dns']
|
148
|
+
|
149
|
+
ssh_key = Openshift::SSH::gen_ssh_keys(@libra_kfile,@libra_kpfile)
|
150
|
+
Openshift::SSH::setup_ssh_config(conf('domain'))
|
151
|
+
csay("\nRetrieving environment SSH keys... ")
|
152
|
+
uri = URI.parse("https://#{environment['dns']}:4242/security/keys")
|
153
|
+
response = Openshift::Rest.get(@http, uri, nil, nil, {'user' => environment['username'], 'password' => environment['password']})
|
154
|
+
case response
|
155
|
+
when Net::HTTPSuccess
|
156
|
+
csay("[OK]",:conf)
|
157
|
+
else
|
158
|
+
debug "HTTP code: #{response.code}"
|
159
|
+
debug response.body
|
160
|
+
csay("[ERROR]",:error)
|
161
|
+
csay("Please verify your cloud credentials and try again.\n",:red)
|
162
|
+
exit -301
|
163
|
+
end
|
164
|
+
|
165
|
+
data = JSON.parse(response.body)
|
166
|
+
keys = data['keys']
|
167
|
+
if not keys.index(ssh_key)
|
168
|
+
csay("Uploading SSH key to environment... ")
|
169
|
+
uri = URI.parse("https://#{environment['dns']}:4242/security/keys")
|
170
|
+
response = Openshift::Rest.post(@http, uri, {'type'=>'ssh-rsa','identifier'=>'', 'key'=>ssh_key}, nil, {'user' => environment['username'], 'password' => environment['password']})
|
171
|
+
case response
|
172
|
+
when Net::HTTPSuccess
|
173
|
+
csay("[OK]",:conf)
|
174
|
+
else
|
175
|
+
debug "HTTP code: #{response.code}"
|
176
|
+
debug response.body
|
177
|
+
csay("[ERROR]",:error)
|
178
|
+
csay("Unable to update ssh keys on environment.",:error)
|
179
|
+
exit -301
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
response = nil
|
184
|
+
vpm_imported = false
|
185
|
+
if args['--import-archive'] and (args['--import-archive'] =~ /vpm$/)
|
186
|
+
file_name = args['--import-archive']
|
187
|
+
csay("Importing application vpm ")
|
188
|
+
csay("#{file_name} ", :emphasis)
|
189
|
+
csay("... ")
|
190
|
+
uri = URI.parse("https://#{environment_dns}:4242/applications")
|
191
|
+
response = Openshift::Rest.postFile(@http, uri, nil, {"package"=>file_name}, nil, {'user' => environment['username'], 'password' => environment['password']})
|
192
|
+
case response
|
193
|
+
when Net::HTTPSuccess
|
194
|
+
csay("[OK]",:conf)
|
195
|
+
else
|
196
|
+
debug "HTTP code: #{response.code}"
|
197
|
+
debug response.body
|
198
|
+
csay("[ERROR]",:error)
|
199
|
+
csay("Unable to upload VPM archive",:error)
|
200
|
+
exit -301
|
201
|
+
end
|
202
|
+
vpm_imported = true
|
203
|
+
else
|
204
|
+
if not Openshift::Validation.check_field(app_name,"application name",8)
|
205
|
+
app_name = Openshift::IO.prompt("Application name",[],lambda{|a| Openshift::Validation.check_field(a,"application name",8)})
|
206
|
+
end
|
207
|
+
app_version = args['--version'] || "1.0"
|
208
|
+
csay("Creating application ")
|
209
|
+
csay("#{app_name} ", :emphasis)
|
210
|
+
csay("Version:#{app_version})... ")
|
211
|
+
uri = URI.parse("https://#{environment_dns}:4242/applications")
|
212
|
+
response = Openshift::Rest.post(@http, uri, {"name" => app_name, "version" => app_version}, nil, {'user' => environment['username'], 'password' => environment['password']})
|
213
|
+
case response
|
214
|
+
when Net::HTTPSuccess
|
215
|
+
csay("[OK]",:conf)
|
216
|
+
else
|
217
|
+
debug "HTTP code: #{response.code}"
|
218
|
+
debug response.body
|
219
|
+
csay("[ERROR]",:error)
|
220
|
+
csay("Unable to create new application",:error)
|
221
|
+
exit -301
|
222
|
+
end
|
223
|
+
end
|
224
|
+
data = JSON.parse(response.body)
|
225
|
+
app = data['application']
|
226
|
+
|
227
|
+
if not vpm_imported and args['--import-archive']
|
228
|
+
#some other type of archive
|
229
|
+
file_name = args['--import-archive']
|
230
|
+
csay("Uploading archive ")
|
231
|
+
csay("#{file_name} ",:emphasis)
|
232
|
+
csay("to server... ")
|
233
|
+
uri = URI.parse("https://#{environment_dns}:4242/applications/#{app['guid']}/tree/")
|
234
|
+
response = Openshift::Rest.postFile(@http, uri,{"operation"=>"extract"},{"archive"=>file_name},
|
235
|
+
nil, {'user' => environment['username'], 'password' => environment['password']})
|
236
|
+
case response
|
237
|
+
when Net::HTTPSuccess
|
238
|
+
csay("[OK]",:conf)
|
239
|
+
else
|
240
|
+
debug "HTTP code: #{response.code}"
|
241
|
+
debug response.body
|
242
|
+
csay("[ERROR]",:error)
|
243
|
+
csay("Unable to create upload archive.",:error)
|
244
|
+
exit -301
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
if not vpm_imported
|
249
|
+
template = args['--template'] || Openshift::IO.prompt("Choose an application template",Openshift::Flex.templates.keys)
|
250
|
+
carts=Openshift::Flex.templates[template]
|
251
|
+
csay("Retrieving list of available cartridges... ")
|
252
|
+
cart_data = nil
|
253
|
+
begin
|
254
|
+
cmd = "os-list-cartridges --sso \"#{cookie}\" --porcelin --environment #{environment["id"]} #{app["guid"]}"
|
255
|
+
debug cmd
|
256
|
+
cart_data = JSON.parse(`#{cmd}`)
|
257
|
+
csay("[OK]",:conf)
|
258
|
+
rescue Exception => e
|
259
|
+
debug cart_data
|
260
|
+
debug e.message
|
261
|
+
csay("[ERROR]",:error)
|
262
|
+
csay("Unable to retrieve available cartridges",:error)
|
263
|
+
exit -400
|
264
|
+
end
|
265
|
+
avail = cart_data['available']
|
266
|
+
carts_to_install=[]
|
267
|
+
avail.each{ |cart|
|
268
|
+
carts.each{ |req|
|
269
|
+
if cart["name"].index(req) == 0
|
270
|
+
carts_to_install += [cart["name"]]
|
271
|
+
end
|
272
|
+
}
|
273
|
+
}
|
274
|
+
csay("Installing cartridges: #{carts_to_install.join(",")}")
|
275
|
+
system( "os-add-cartridge --sso \"#{cookie}\" --environment #{environment['id']} #{app['guid']} #{carts_to_install.join(",")}" )
|
276
|
+
else
|
277
|
+
system("Ignoring template argument since VPM archive includes dependency information",:warn) if args["--template"]
|
278
|
+
end
|
279
|
+
|
280
|
+
if not args['--no-git']
|
281
|
+
if not vpm_imported and Openshift::Git.git_repo? and Openshift::IO.prompt("A git repository has been detected. Import this application? [Yn]",['Y','y','N','n']).downcase == 'y'
|
282
|
+
csay("Adding GIT remote 'flex' to existing repository",:message)
|
283
|
+
Openshift::Git.add_remote("ssh://admin@#{environment_dns}/mnt/glusterfs/web-apps/#{app['guid']}/repository","flex")
|
284
|
+
Openshift::Git.pull("flex")
|
285
|
+
else
|
286
|
+
clone_dir = app['name'] if clone_dir.nil? or clone_dir == ""
|
287
|
+
csay("Cloning application ")
|
288
|
+
csay("#{app['name']} ",:emphasis)
|
289
|
+
csay("to directory ")
|
290
|
+
csay("#{clone_dir}",:emphasis)
|
291
|
+
Openshift::Git.clone("ssh://admin@#{environment_dns}/mnt/glusterfs/web-apps/#{app['guid']}/repository",app['name'],'origin')
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
if args['--porcelin']
|
296
|
+
print JSON.generate(app)
|
297
|
+
else
|
298
|
+
csay("Application created",:message)
|
299
|
+
Openshift::Formatter.table(["Application GUID","Application name", "Version", "State"],
|
300
|
+
['guid','name','version','status'],
|
301
|
+
[39,20,7,10],
|
302
|
+
[app])
|
303
|
+
end
|
304
|
+
else #express
|
305
|
+
csay("This feature is currently not implemented for Openshift Express applications.\n",:red)
|
306
|
+
end
|