uffizzi_core 0.1.9 → 0.1.12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +6 -0
- data/app/controllers/uffizzi_core/api/cli/v1/account/credentials_controller.rb +3 -3
- data/app/controllers/uffizzi_core/api/cli/v1/projects_controller.rb +68 -2
- data/app/forms/uffizzi_core/api/cli/v1/deployment/create_form.rb +1 -0
- data/app/forms/uffizzi_core/api/cli/v1/project/create_form.rb +7 -0
- data/app/lib/uffizzi_core/concerns/models/activity_item.rb +39 -0
- data/app/lib/uffizzi_core/concerns/models/credential.rb +65 -0
- data/app/lib/uffizzi_core/concerns/models/repo.rb +33 -0
- data/app/lib/uffizzi_core/rbac/user_access_service.rb +24 -0
- data/app/models/uffizzi_core/project.rb +9 -2
- data/app/policies/uffizzi_core/api/cli/v1/projects_policy.rb +12 -0
- data/app/serializers/uffizzi_core/api/cli/v1/project_serializer/compose_file_serializer.rb +7 -0
- data/app/serializers/uffizzi_core/api/cli/v1/project_serializer/deployment_serializer.rb +13 -0
- data/app/serializers/uffizzi_core/api/cli/v1/project_serializer.rb +24 -1
- data/app/serializers/uffizzi_core/api/cli/v1/projects/deployment_serializer/container_serializer.rb +2 -1
- data/app/serializers/uffizzi_core/api/cli/v1/projects/deployments/container_serializer.rb +1 -1
- data/app/serializers/uffizzi_core/api/cli/v1/short_project_serializer.rb +7 -0
- data/app/serializers/uffizzi_core/controller/deploy_containers/container_serializer.rb +16 -1
- data/app/services/uffizzi_core/compose_file/builders/container_builder_service.rb +11 -7
- data/app/services/uffizzi_core/compose_file/config_option_service.rb +4 -0
- data/app/services/uffizzi_core/compose_file/parsers/services/healthcheck_parser_service.rb +73 -0
- data/app/services/uffizzi_core/compose_file/services_options_service.rb +2 -0
- data/app/services/uffizzi_core/compose_file/template_service.rb +4 -4
- data/app/services/uffizzi_core/compose_file_service.rb +1 -1
- data/app/services/uffizzi_core/deployment_service.rb +17 -5
- data/app/services/uffizzi_core/manage_activity_items_service.rb +8 -0
- data/app/services/uffizzi_core/project_service.rb +10 -0
- data/app/services/uffizzi_core/starter_template_service.rb +200 -0
- data/app/services/uffizzi_core/user_generator_service.rb +11 -5
- data/config/locales/en.yml +2 -0
- data/config/routes.rb +11 -1
- data/db/migrate/20220419074956_add_health_check_to_containers.rb +7 -0
- data/lib/tasks/uffizzi_core_tasks.rake +1 -1
- data/lib/uffizzi_core/version.rb +1 -1
- data/swagger/v1/swagger.json +174 -2
- metadata +12 -2
@@ -8,12 +8,12 @@ module UffizziCore::DeploymentService
|
|
8
8
|
building: :building,
|
9
9
|
deploying: :deploying,
|
10
10
|
failed: :failed,
|
11
|
+
queued: :queued,
|
11
12
|
}.freeze
|
12
13
|
|
13
14
|
class << self
|
14
15
|
def create_from_compose(compose_file, project, user)
|
15
16
|
deployment_attributes = ActionController::Parameters.new(compose_file.template.payload)
|
16
|
-
|
17
17
|
deployment_form = UffizziCore::Api::Cli::V1::Deployment::CreateForm.new(deployment_attributes)
|
18
18
|
deployment_form.assign_dependences!(project, user)
|
19
19
|
deployment_form.compose_file = compose_file
|
@@ -103,8 +103,9 @@ module UffizziCore::DeploymentService
|
|
103
103
|
pull_request_payload = continuous_preview_payload['pull_request']
|
104
104
|
repo_name = pull_request_payload['repository_full_name'].split('/').last
|
105
105
|
deployment_name = name(deployment)
|
106
|
+
subdomain = "pr#{pull_request_payload['id']}-#{deployment_name}-#{repo_name}-#{project.slug}"
|
106
107
|
|
107
|
-
|
108
|
+
format_subdomain(subdomain)
|
108
109
|
end
|
109
110
|
|
110
111
|
def build_docker_continuous_preview_subdomain(deployment)
|
@@ -114,14 +115,17 @@ module UffizziCore::DeploymentService
|
|
114
115
|
repo_name = docker_payload['image'].split('/').last.gsub('_', '-')
|
115
116
|
image_tag = docker_payload['tag'].gsub('_', '-')
|
116
117
|
deployment_name = name(deployment)
|
118
|
+
subdomain = "#{image_tag}-#{deployment_name}-#{repo_name}-#{project.slug}"
|
117
119
|
|
118
|
-
|
120
|
+
format_subdomain(subdomain)
|
119
121
|
end
|
120
122
|
|
121
123
|
def build_default_subdomain(deployment)
|
122
124
|
deployment_name = name(deployment)
|
123
125
|
slug = deployment.project.slug.to_s
|
124
|
-
"#{deployment_name}
|
126
|
+
subdomain = "#{deployment_name}-#{slug}"
|
127
|
+
|
128
|
+
format_subdomain(subdomain)
|
125
129
|
end
|
126
130
|
|
127
131
|
def build_preview_url(deployment)
|
@@ -238,10 +242,11 @@ module UffizziCore::DeploymentService
|
|
238
242
|
|
239
243
|
def deployment_process_status(deployment)
|
240
244
|
containers = deployment.active_containers
|
241
|
-
activity_items = containers.map { |container| container.activity_items.order_by_id.last }
|
245
|
+
activity_items = containers.map { |container| container.activity_items.order_by_id.last }.compact
|
242
246
|
events = activity_items.map { |activity_item| activity_item.events.order_by_id.last&.state }
|
243
247
|
events = events.flatten.uniq
|
244
248
|
|
249
|
+
return DEPLOYMENT_PROCESS_STATUSES[:queued] if containers.present? && events.empty?
|
245
250
|
return DEPLOYMENT_PROCESS_STATUSES[:failed] if events.include?(UffizziCore::Event.state.failed)
|
246
251
|
return DEPLOYMENT_PROCESS_STATUSES[:building] if events.include?(UffizziCore::Event.state.building)
|
247
252
|
|
@@ -291,5 +296,12 @@ module UffizziCore::DeploymentService
|
|
291
296
|
container.variables.push(*envs)
|
292
297
|
end
|
293
298
|
end
|
299
|
+
|
300
|
+
def format_subdomain(full_subdomain_name)
|
301
|
+
subdomain_length_limit = Settings.deployment.subdomain.length_limit
|
302
|
+
return full_subdomain_name if full_subdomain_name.length <= subdomain_length_limit
|
303
|
+
|
304
|
+
full_subdomain_name.slice(0, subdomain_length_limit)
|
305
|
+
end
|
294
306
|
end
|
295
307
|
end
|
@@ -116,18 +116,26 @@ class UffizziCore::ManageActivityItemsService
|
|
116
116
|
state = pod_container[:state][pod_container_status]
|
117
117
|
reason = state&.reason
|
118
118
|
|
119
|
+
Rails.logger.info("manage_activity_items get_status dep_id=#{container.deployment.id} pod_container_status: #{pod_container_status}")
|
120
|
+
Rails.logger.info("manage_activity_items get_status dep_id=#{container.deployment.id} state: #{state}")
|
121
|
+
ap(pod_container[:state])
|
122
|
+
|
119
123
|
case pod_container_status.to_sym
|
120
124
|
when :running
|
125
|
+
Rails.logger.info("manage_activity_items get_status dep_id=#{container.deployment.id} running")
|
121
126
|
UffizziCore::Event.state.deployed
|
122
127
|
when :terminated
|
128
|
+
Rails.logger.info("manage_activity_items get_status dep_id=#{container.deployment.id} terminated")
|
123
129
|
UffizziCore::Event.state.failed
|
124
130
|
when :waiting
|
131
|
+
Rails.logger.info("manage_activity_items get_status dep_id=#{container.deployment.id} waiting")
|
125
132
|
return UffizziCore::Event.state.failed if ['CrashLoopBackOff'].include?(reason)
|
126
133
|
|
127
134
|
raise UffizziCore::Deployment::ImagePullError, @deployment.id if ['ErrImagePull', 'ImagePullBackOff'].include?(reason)
|
128
135
|
|
129
136
|
UffizziCore::Event.state.deploying
|
130
137
|
else
|
138
|
+
Rails.logger.info("manage_activity_items get_status dep_id=#{container.deployment.id} else")
|
131
139
|
UffizziCore::Event.state.deploying
|
132
140
|
end
|
133
141
|
end
|
@@ -34,5 +34,15 @@ module UffizziCore::ProjectService
|
|
34
34
|
|
35
35
|
UffizziCore::ComposeFile::ErrorsService.update_compose_errors!(compose_file, new_errors, compose_file.content)
|
36
36
|
end
|
37
|
+
|
38
|
+
def add_users_to_project!(project, current_user)
|
39
|
+
user_projects = []
|
40
|
+
|
41
|
+
current_user.organizational_account.memberships.where(role: UffizziCore::Membership.role.admin).map do |membership|
|
42
|
+
user_projects << { project: project, user: membership.user, role: UffizziCore::UserProject.role.admin }
|
43
|
+
end
|
44
|
+
|
45
|
+
UffizziCore::UserProject.create!(user_projects)
|
46
|
+
end
|
37
47
|
end
|
38
48
|
end
|
@@ -0,0 +1,200 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class UffizziCore::StarterTemplateService
|
4
|
+
class << self
|
5
|
+
def create(project, user)
|
6
|
+
voting_app_config_file = create_config_file(project, user)
|
7
|
+
create_containers(project, user, voting_app_config_file)
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def create_config_file(project, user)
|
13
|
+
starter_template_config_file = config_file_attributes
|
14
|
+
|
15
|
+
starter_template_config_file_params = ActionController::Parameters.new(starter_template_config_file)
|
16
|
+
|
17
|
+
starter_template_config_file_form = UffizziCore::Api::Cli::V1::ConfigFile::CreateForm.new(starter_template_config_file_params)
|
18
|
+
starter_template_config_file_form.project = project
|
19
|
+
starter_template_config_file_form.added_by = user
|
20
|
+
starter_template_config_file_form.creation_source = UffizziCore::ConfigFile.creation_source.system
|
21
|
+
starter_template_config_file_form.save
|
22
|
+
|
23
|
+
starter_template_config_file_form
|
24
|
+
end
|
25
|
+
|
26
|
+
def create_containers(project, user, voting_app_config_file)
|
27
|
+
starter_template_containers = {
|
28
|
+
name: 'Voting App (from base images)',
|
29
|
+
payload: {
|
30
|
+
containers_attributes: containers_attributes(voting_app_config_file),
|
31
|
+
},
|
32
|
+
}
|
33
|
+
|
34
|
+
starter_template = ActionController::Parameters.new(starter_template_containers)
|
35
|
+
|
36
|
+
starter_template_form = UffizziCore::Api::Cli::V1::Template::CreateForm.new(starter_template)
|
37
|
+
starter_template_form.creation_source = UffizziCore::Template.creation_source.system
|
38
|
+
starter_template_form.added_by = user
|
39
|
+
starter_template_form.project = project
|
40
|
+
starter_template_form.save
|
41
|
+
end
|
42
|
+
|
43
|
+
def containers_attributes(voting_app_config_file)
|
44
|
+
[
|
45
|
+
postgres_container_attributes,
|
46
|
+
nginx_container_attributes(voting_app_config_file),
|
47
|
+
redis_container_attributes,
|
48
|
+
example_worker_container_attributes,
|
49
|
+
example_result_container_attributes,
|
50
|
+
example_vote_container_attributes,
|
51
|
+
]
|
52
|
+
end
|
53
|
+
|
54
|
+
def postgres_container_attributes
|
55
|
+
{
|
56
|
+
image: 'library/postgres',
|
57
|
+
tag: '9.6',
|
58
|
+
port: nil,
|
59
|
+
public: false,
|
60
|
+
memory_limit: 250,
|
61
|
+
memory_request: 250,
|
62
|
+
receive_incoming_requests: false,
|
63
|
+
continuously_deploy: 'disabled',
|
64
|
+
secret_variables: nil,
|
65
|
+
variables: [
|
66
|
+
{
|
67
|
+
name: 'POSTGRES_USER',
|
68
|
+
value: 'postgres',
|
69
|
+
},
|
70
|
+
{
|
71
|
+
name: 'POSTGRES_PASSWORD',
|
72
|
+
value: 'postgres',
|
73
|
+
},
|
74
|
+
],
|
75
|
+
repo_attributes: repo_attributes('library/postgres'),
|
76
|
+
container_config_files_attributes: [],
|
77
|
+
}
|
78
|
+
end
|
79
|
+
|
80
|
+
def nginx_container_attributes(voting_app_config_file)
|
81
|
+
{
|
82
|
+
image: 'library/nginx',
|
83
|
+
tag: 'latest',
|
84
|
+
port: 8080,
|
85
|
+
public: true,
|
86
|
+
memory_limit: 125,
|
87
|
+
memory_request: 125,
|
88
|
+
receive_incoming_requests: true,
|
89
|
+
continuously_deploy: 'disabled',
|
90
|
+
secret_variables: nil,
|
91
|
+
variables: nil,
|
92
|
+
repo_attributes: repo_attributes('library/nginx'),
|
93
|
+
container_config_files_attributes: [{
|
94
|
+
config_file_id: voting_app_config_file.id,
|
95
|
+
mount_path: '/etc/nginx/conf.d/',
|
96
|
+
}],
|
97
|
+
}
|
98
|
+
end
|
99
|
+
|
100
|
+
def redis_container_attributes
|
101
|
+
{
|
102
|
+
image: 'library/redis',
|
103
|
+
tag: 'latest',
|
104
|
+
port: nil,
|
105
|
+
public: false,
|
106
|
+
memory_limit: 125,
|
107
|
+
memory_request: 125,
|
108
|
+
receive_incoming_requests: false,
|
109
|
+
continuously_deploy: 'disabled',
|
110
|
+
secret_variables: nil,
|
111
|
+
variables: nil,
|
112
|
+
repo_attributes: repo_attributes('library/redis'),
|
113
|
+
container_config_files_attributes: [],
|
114
|
+
}
|
115
|
+
end
|
116
|
+
|
117
|
+
def example_worker_container_attributes
|
118
|
+
{
|
119
|
+
image: 'uffizzicloud/example-worker',
|
120
|
+
tag: 'latest',
|
121
|
+
port: nil,
|
122
|
+
public: false,
|
123
|
+
memory_limit: 250,
|
124
|
+
memory_request: 250,
|
125
|
+
receive_incoming_requests: false,
|
126
|
+
continuously_deploy: 'disabled',
|
127
|
+
secret_variables: nil,
|
128
|
+
variables: nil,
|
129
|
+
repo_attributes: repo_attributes('uffizzicloud/example-worker'),
|
130
|
+
container_config_files_attributes: [],
|
131
|
+
}
|
132
|
+
end
|
133
|
+
|
134
|
+
def example_result_container_attributes
|
135
|
+
{
|
136
|
+
image: 'uffizzicloud/example-result',
|
137
|
+
tag: 'latest',
|
138
|
+
port: nil,
|
139
|
+
public: false,
|
140
|
+
memory_limit: 125,
|
141
|
+
memory_request: 125,
|
142
|
+
receive_incoming_requests: false,
|
143
|
+
continuously_deploy: 'disabled',
|
144
|
+
secret_variables: nil,
|
145
|
+
variables: nil,
|
146
|
+
repo_attributes: repo_attributes('uffizzicloud/example-result'),
|
147
|
+
container_config_files_attributes: [],
|
148
|
+
}
|
149
|
+
end
|
150
|
+
|
151
|
+
def example_vote_container_attributes
|
152
|
+
{
|
153
|
+
image: 'uffizzicloud/example-vote',
|
154
|
+
tag: 'latest',
|
155
|
+
port: nil,
|
156
|
+
public: false,
|
157
|
+
memory_limit: 250,
|
158
|
+
memory_request: 250,
|
159
|
+
receive_incoming_requests: false,
|
160
|
+
continuously_deploy: 'disabled',
|
161
|
+
secret_variables: nil,
|
162
|
+
variables: nil,
|
163
|
+
repo_attributes: repo_attributes('uffizzicloud/example-vote'),
|
164
|
+
container_config_files_attributes: [],
|
165
|
+
}
|
166
|
+
end
|
167
|
+
|
168
|
+
def config_file_attributes
|
169
|
+
{
|
170
|
+
filename: 'vote.conf',
|
171
|
+
kind: 'config_map',
|
172
|
+
payload: "server {
|
173
|
+
listen 8080;
|
174
|
+
server_name example.com;
|
175
|
+
location / {
|
176
|
+
proxy_pass http://127.0.0.1:80/;
|
177
|
+
}
|
178
|
+
location /vote/ {
|
179
|
+
proxy_pass http://127.0.0.1:8888/;
|
180
|
+
}
|
181
|
+
}",
|
182
|
+
}
|
183
|
+
end
|
184
|
+
|
185
|
+
def repo_attributes(image)
|
186
|
+
namespace, name = image.split('/')
|
187
|
+
{
|
188
|
+
namespace: namespace,
|
189
|
+
name: name,
|
190
|
+
slug: name,
|
191
|
+
type: 'UffizziCore::Repo::DockerHub',
|
192
|
+
description: '',
|
193
|
+
is_private: false,
|
194
|
+
repository_id: nil,
|
195
|
+
branch: '',
|
196
|
+
kind: nil,
|
197
|
+
}
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
@@ -6,6 +6,12 @@ class UffizziCore::UserGeneratorService
|
|
6
6
|
DEFAULT_ACCOUNT_NAME = 'default'
|
7
7
|
|
8
8
|
class << self
|
9
|
+
def safe_generate(email, password, project_name)
|
10
|
+
generate(email, password, project_name)
|
11
|
+
rescue StandardError => e
|
12
|
+
puts e.message
|
13
|
+
end
|
14
|
+
|
9
15
|
def generate(email, password, project_name)
|
10
16
|
user_attributes = build_user_attributes(email, password)
|
11
17
|
project_attributes = build_project_attributes(project_name)
|
@@ -31,19 +37,17 @@ class UffizziCore::UserGeneratorService
|
|
31
37
|
|
32
38
|
if email.present?
|
33
39
|
user_attributes[:email] = email
|
34
|
-
|
40
|
+
elsif IO::console.present?
|
35
41
|
IO::console.write("Enter User Email (default: #{DEFAULT_USER_EMAIL}): ")
|
36
42
|
user_attributes[:email] = IO::console.gets.strip.presence || DEFAULT_USER_EMAIL
|
37
43
|
end
|
38
44
|
|
39
45
|
user_attributes[:password] = if password.present?
|
40
46
|
password
|
41
|
-
|
47
|
+
elsif IO::console.present?
|
42
48
|
IO::console.getpass('Enter Password: ')
|
43
49
|
end
|
44
50
|
|
45
|
-
abort('password can\'t be blank') if user_attributes[:password].blank?
|
46
|
-
|
47
51
|
user_attributes
|
48
52
|
end
|
49
53
|
|
@@ -53,9 +57,11 @@ class UffizziCore::UserGeneratorService
|
|
53
57
|
}
|
54
58
|
if project_name.present?
|
55
59
|
project_attributes[:name] = project_name
|
56
|
-
|
60
|
+
elsif IO::console.present?
|
57
61
|
IO::console.write("Enter Project Name (default: #{DEFAULT_PROJECT_NAME}): ")
|
58
62
|
project_attributes[:name] = IO::console.gets.strip.presence || DEFAULT_PROJECT_NAME
|
63
|
+
else
|
64
|
+
project_attributes[:name] = DEFAULT_PROJECT_NAME
|
59
65
|
end
|
60
66
|
|
61
67
|
project_attributes[:slug] = prepare_project_slug(project_attributes[:name])
|
data/config/locales/en.yml
CHANGED
@@ -57,8 +57,10 @@ en:
|
|
57
57
|
continuous_preview_in_service_level: The option '%{option}' is not supported for service-level. Use 'x-uffizzi-continuous-preview' instead
|
58
58
|
file_already_exists: A compose file already exists for this project. Run 'uffizzi compose update' to update this file or 'uffizzi compose rm' to remove it. For more options, see 'uffizzi compose --help'
|
59
59
|
invalid_healthcheck_command: "Service '%{name}' defines an invalid healthcheck: when 'test' is a list the first item must be either NONE, CMD or CMD-SHELL"
|
60
|
+
invalid_time_interval: The time interval should be in the following format '{hours}h{minutes}m{seconds}s'. At least one value must be present.
|
60
61
|
string_or_array_error: "'%{option}' contains an invalid type, it should be a string, or an array"
|
61
62
|
not_implemented: "'%{option}' option is not implemented"
|
63
|
+
infinite_recursion: "Found infinite recursion for key '%{key}'"
|
62
64
|
secrets:
|
63
65
|
duplicates_exists: Secret with key %{secrets} already exist.
|
64
66
|
invalid_key_length: A secret key must be no longer than 256 characters.
|
data/config/routes.rb
CHANGED
@@ -15,13 +15,23 @@ UffizziCore::Engine.routes.draw do
|
|
15
15
|
post :google
|
16
16
|
end
|
17
17
|
|
18
|
-
resources :projects, only: ['index'], param: :slug do
|
18
|
+
resources :projects, only: ['index', 'show', 'create', 'destroy'], param: :slug do
|
19
19
|
scope module: :projects do
|
20
20
|
resource :compose_file, only: ['show', 'create', 'destroy']
|
21
21
|
resources :deployments, only: ['index', 'show', 'create', 'destroy', 'update'] do
|
22
22
|
post :deploy_containers, on: :member
|
23
23
|
scope module: :deployments do
|
24
24
|
resources :activity_items, only: ['index']
|
25
|
+
resources :containers, only: ['index'], param: :name do
|
26
|
+
scope module: :containers do
|
27
|
+
resources :logs, only: ['index']
|
28
|
+
resources :builds, only: [] do
|
29
|
+
collection do
|
30
|
+
get :logs
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
25
35
|
resources :events, only: ['index']
|
26
36
|
resources :containers, only: ['index'], param: :name do
|
27
37
|
scope module: :containers do
|
@@ -14,6 +14,6 @@ namespace :uffizzi_core do
|
|
14
14
|
|
15
15
|
desc 'Create a new user'
|
16
16
|
task create_user: :environment do
|
17
|
-
UffizziCore::UserGeneratorService.
|
17
|
+
UffizziCore::UserGeneratorService.safe_generate(ENV['UFFIZZI_USER_EMAIL'], ENV['UFFIZZI_USER_PASSWORD'], ENV['UFFIZZI_PROJECT_NAME'])
|
18
18
|
end
|
19
19
|
end
|
data/lib/uffizzi_core/version.rb
CHANGED
data/swagger/v1/swagger.json
CHANGED
@@ -80,7 +80,7 @@
|
|
80
80
|
"default": {
|
81
81
|
"description": "Create account credential",
|
82
82
|
"examples": {
|
83
|
-
"application/json": "type can be one of UffizziCore::Credential::Amazon, UffizziCore::Credential::Azure
|
83
|
+
"application/json": "type can be one of UffizziCore::Credential::Amazon, UffizziCore::Credential::Azure,\nUffizziCore::Credential::DockerHub, UffizziCore::Credential::Google, UffizziCore::Credential::GithubContainerRegistry"
|
84
84
|
}
|
85
85
|
},
|
86
86
|
"201": {
|
@@ -1134,6 +1134,9 @@
|
|
1134
1134
|
"properties": {
|
1135
1135
|
"slug": {
|
1136
1136
|
"type": "string"
|
1137
|
+
},
|
1138
|
+
"name": {
|
1139
|
+
"type": "string"
|
1137
1140
|
}
|
1138
1141
|
}
|
1139
1142
|
}
|
@@ -1149,6 +1152,143 @@
|
|
1149
1152
|
"summary": "Get projects of current user",
|
1150
1153
|
"x-controller": "uffizzi_core/api/cli/v1/projects",
|
1151
1154
|
"x-action": "index"
|
1155
|
+
},
|
1156
|
+
"post": {
|
1157
|
+
"tags": [
|
1158
|
+
"Project"
|
1159
|
+
],
|
1160
|
+
"operationId": "Project-create",
|
1161
|
+
"parameters": [
|
1162
|
+
{
|
1163
|
+
"name": "params",
|
1164
|
+
"description": "params",
|
1165
|
+
"required": true,
|
1166
|
+
"in": "body",
|
1167
|
+
"schema": {
|
1168
|
+
"type": "object",
|
1169
|
+
"properties": {
|
1170
|
+
"name": {
|
1171
|
+
"type": "string"
|
1172
|
+
},
|
1173
|
+
"slug": {
|
1174
|
+
"type": "string"
|
1175
|
+
},
|
1176
|
+
"description": {
|
1177
|
+
"type": "string"
|
1178
|
+
}
|
1179
|
+
}
|
1180
|
+
}
|
1181
|
+
}
|
1182
|
+
],
|
1183
|
+
"responses": {
|
1184
|
+
"200": {
|
1185
|
+
"description": "OK",
|
1186
|
+
"schema": {
|
1187
|
+
"type": "object",
|
1188
|
+
"properties": {
|
1189
|
+
"project": {
|
1190
|
+
"$ref": "#/definitions/Project"
|
1191
|
+
}
|
1192
|
+
}
|
1193
|
+
}
|
1194
|
+
},
|
1195
|
+
"404": {
|
1196
|
+
"description": "Not Found"
|
1197
|
+
},
|
1198
|
+
"401": {
|
1199
|
+
"description": "Not authorized"
|
1200
|
+
},
|
1201
|
+
"422": {
|
1202
|
+
"description": "Unprocessable entity",
|
1203
|
+
"schema": {
|
1204
|
+
"type": "object",
|
1205
|
+
"properties": {
|
1206
|
+
"errors": {
|
1207
|
+
"type": "object",
|
1208
|
+
"properties": {
|
1209
|
+
"password": {
|
1210
|
+
"type": "string"
|
1211
|
+
}
|
1212
|
+
}
|
1213
|
+
}
|
1214
|
+
}
|
1215
|
+
}
|
1216
|
+
}
|
1217
|
+
},
|
1218
|
+
"description": "Create a project",
|
1219
|
+
"summary": "Create a project",
|
1220
|
+
"x-controller": "uffizzi_core/api/cli/v1/projects",
|
1221
|
+
"x-action": "create"
|
1222
|
+
}
|
1223
|
+
},
|
1224
|
+
"/api/cli/v1/projects/{slug}": {
|
1225
|
+
"get": {
|
1226
|
+
"tags": [
|
1227
|
+
"Project"
|
1228
|
+
],
|
1229
|
+
"operationId": "Project-show",
|
1230
|
+
"parameters": [
|
1231
|
+
{
|
1232
|
+
"name": "slug",
|
1233
|
+
"description": "Scope response to slug",
|
1234
|
+
"required": true,
|
1235
|
+
"in": "path",
|
1236
|
+
"type": "string"
|
1237
|
+
}
|
1238
|
+
],
|
1239
|
+
"responses": {
|
1240
|
+
"200": {
|
1241
|
+
"description": "OK",
|
1242
|
+
"schema": {
|
1243
|
+
"type": "object",
|
1244
|
+
"properties": {
|
1245
|
+
"project": {
|
1246
|
+
"$ref": "#/definitions/Project"
|
1247
|
+
}
|
1248
|
+
}
|
1249
|
+
}
|
1250
|
+
},
|
1251
|
+
"404": {
|
1252
|
+
"description": "Not Found"
|
1253
|
+
},
|
1254
|
+
"401": {
|
1255
|
+
"description": "Not authorized"
|
1256
|
+
}
|
1257
|
+
},
|
1258
|
+
"description": "Get a project by slug",
|
1259
|
+
"summary": "Get a project by slug",
|
1260
|
+
"x-controller": "uffizzi_core/api/cli/v1/projects",
|
1261
|
+
"x-action": "show"
|
1262
|
+
},
|
1263
|
+
"delete": {
|
1264
|
+
"tags": [
|
1265
|
+
"Project"
|
1266
|
+
],
|
1267
|
+
"operationId": "Project-destroy",
|
1268
|
+
"parameters": [
|
1269
|
+
{
|
1270
|
+
"name": "slug",
|
1271
|
+
"description": "Scope response to slug",
|
1272
|
+
"required": true,
|
1273
|
+
"in": "path",
|
1274
|
+
"type": "string"
|
1275
|
+
}
|
1276
|
+
],
|
1277
|
+
"responses": {
|
1278
|
+
"204": {
|
1279
|
+
"description": "No content"
|
1280
|
+
},
|
1281
|
+
"404": {
|
1282
|
+
"description": "Not Found"
|
1283
|
+
},
|
1284
|
+
"401": {
|
1285
|
+
"description": "Not authorized"
|
1286
|
+
}
|
1287
|
+
},
|
1288
|
+
"description": "Delete a project",
|
1289
|
+
"summary": "Delete a project",
|
1290
|
+
"x-controller": "uffizzi_core/api/cli/v1/projects",
|
1291
|
+
"x-action": "destroy"
|
1152
1292
|
}
|
1153
1293
|
},
|
1154
1294
|
"/api/cli/v1/session": {
|
@@ -1475,11 +1615,43 @@
|
|
1475
1615
|
}
|
1476
1616
|
}
|
1477
1617
|
},
|
1478
|
-
"
|
1618
|
+
"Project": {
|
1479
1619
|
"type": "object",
|
1480
1620
|
"properties": {
|
1481
1621
|
"slug": {
|
1482
1622
|
"type": "string"
|
1623
|
+
},
|
1624
|
+
"name": {
|
1625
|
+
"type": "string"
|
1626
|
+
},
|
1627
|
+
"description": {
|
1628
|
+
"type": "string"
|
1629
|
+
},
|
1630
|
+
"created_at": {
|
1631
|
+
"type": "string",
|
1632
|
+
"format": "date-time"
|
1633
|
+
},
|
1634
|
+
"secrets": {
|
1635
|
+
"type": "string"
|
1636
|
+
},
|
1637
|
+
"default_compose": {
|
1638
|
+
"type": "object",
|
1639
|
+
"properties": {
|
1640
|
+
"source": {
|
1641
|
+
"type": "string"
|
1642
|
+
}
|
1643
|
+
}
|
1644
|
+
},
|
1645
|
+
"deployments": {
|
1646
|
+
"type": "object",
|
1647
|
+
"properties": {
|
1648
|
+
"id": {
|
1649
|
+
"type": "integer"
|
1650
|
+
},
|
1651
|
+
"domain": {
|
1652
|
+
"type": "string"
|
1653
|
+
}
|
1654
|
+
}
|
1483
1655
|
}
|
1484
1656
|
}
|
1485
1657
|
}
|