uffizzi_core 0.1.14 → 0.1.15

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d4aa056e4e94f8dbd93efddc149a68b583fe31090307048c1167df16b8842032
4
- data.tar.gz: f7c91d5144ebe0f7cf95cbe7f3241e85bae67ff79eac46465a5cb329b23dfac6
3
+ metadata.gz: 398869abc38d2bc2416b1589de95feb828d73abdc34a388f74339fae083332d0
4
+ data.tar.gz: a58d996964d92dd95a0bd5e4ebffab62dd84eaafcc7580bf3462cc6a58ccee46
5
5
  SHA512:
6
- metadata.gz: c21e0edc0adf7905754850aabe30d4aec880029de985d90434c70f5bd2804dd7a44d87664f5e668b5bbac049cf6fda304c297c5ab44cc68a778d00d4fdf95b56
7
- data.tar.gz: 6aa9ac0ab849cf07720a3642222d51a258252be4ad658f2f878a6a0b54ee725fe7b8f7a3f29bd42037a62be22dc268bf339baf7dc043ad3c66b7de497692f4da
6
+ metadata.gz: a70937d88e1d4733d113184b702f99226f5bee51dbed31cf8d8a9bbf2b2e93f8b702a68a72bf6fcb992f8493be910d0d1d18f0c2af90328bdda755a54405617e
7
+ data.tar.gz: cc53ee6c8d52ad74d732ea97996e84999e2f660e47b18d251695fa81f60010060955d6e9ef5e27fe7312d56faa329bf54243eb99138efa7a1e4a92907e6a8c98
@@ -9,11 +9,66 @@ class UffizziCore::Api::Cli::V1::ProjectsController < UffizziCore::Api::Cli::V1:
9
9
  #
10
10
  # @path [GET] /api/cli/v1/projects
11
11
  #
12
- # @response [object<projects: Array<object<slug: string>> >] 200 OK
12
+ # @response [object<projects: Array<object<slug: string, name: string>> >] 200 OK
13
13
  # @response 401 Not authorized
14
14
  def index
15
15
  projects = current_user.projects.active.order(updated_at: :desc)
16
16
 
17
- respond_with projects
17
+ respond_with projects, each_serializer: UffizziCore::Api::Cli::V1::ShortProjectSerializer
18
+ end
19
+
20
+ # Get a project by slug
21
+ #
22
+ # @path [GET] /api/cli/v1/projects/{slug}
23
+ #
24
+ # @response <object< project: Project>> 200 OK
25
+ # @response 404 Not Found
26
+ # @response 401 Not authorized
27
+ def show
28
+ project = current_user.projects.find_by!(slug: params[:slug])
29
+
30
+ respond_with project
31
+ end
32
+
33
+ # Create a project
34
+ #
35
+ # @path [POST] /api/cli/v1/projects
36
+ # @parameter params(required,body) [object<name: string, slug: string, description: string>]
37
+ #
38
+ # @response <object< project: Project>> 200 OK
39
+ # @response 404 Not Found
40
+ # @response 401 Not authorized
41
+ # @response [object<errors: object<password: string >>] 422 Unprocessable entity
42
+
43
+ def create
44
+ project_form = UffizziCore::Api::Cli::V1::Project::CreateForm.new(project_params)
45
+ project_form.account = current_user.organizational_account
46
+
47
+ if project_form.save
48
+ UffizziCore::ProjectService.add_users_to_project!(project_form, current_user)
49
+ end
50
+
51
+ respond_with project_form
52
+ end
53
+
54
+ # Delete a project
55
+ #
56
+ # @path [DELETE] /api/cli/v1/projects/{slug}
57
+ #
58
+ # @response 204 No content
59
+ # @response 404 Not Found
60
+ # @response 401 Not authorized
61
+
62
+ def destroy
63
+ project = current_user.organizational_account.active_projects.find_by!(slug: params[:slug])
64
+ project.disable!
65
+
66
+ head :no_content
67
+ end
68
+
69
+ private
70
+
71
+ def project_params
72
+ params.require(:project)
18
73
  end
19
74
  end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UffizziCore::Api::Cli::V1::Project::CreateForm < UffizziCore::Project
4
+ include UffizziCore::ApplicationForm
5
+
6
+ permit :name, :slug, :description
7
+ end
@@ -10,6 +10,10 @@ module UffizziCore::Rbac::UserAccessService
10
10
  true
11
11
  end
12
12
 
13
+ def admin_or_developer_access_to_account?(_user, _account)
14
+ true
15
+ end
16
+
13
17
  def admin_or_developer_access_to_project?(_user, _project)
14
18
  true
15
19
  end
@@ -1,7 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # @model
3
+ # @model Project
4
4
  # @property slug [string]
5
+ # @property name [string]
6
+ # @property description [string]
7
+ # @property created_at [date-time]
8
+ # @property secrets [string]
9
+ # @property default_compose [object<source: string>]
10
+ # @property deployments [object<id: integer, domain: string>]
5
11
 
6
12
  class UffizziCore::Project < UffizziCore::ApplicationRecord
7
13
  include AASM
@@ -23,7 +29,8 @@ class UffizziCore::Project < UffizziCore::ApplicationRecord
23
29
  has_many :compose_files, dependent: :destroy
24
30
  has_many :secrets, dependent: :destroy, as: :resource
25
31
 
26
- validates :name, presence: true, uniqueness: { scope: :account }
32
+ validates :name, presence: true, uniqueness: { scope: :account, message: 'Name already exists' }
33
+ validates :slug, presence: true, uniqueness: { message: 'Project slug already taken' }
27
34
 
28
35
  aasm(:state) do
29
36
  state :active, initial: true
@@ -4,4 +4,16 @@ class UffizziCore::Api::Cli::V1::ProjectsPolicy < UffizziCore::ApplicationPolicy
4
4
  def index?
5
5
  context.user_access_module.any_access_to_account?(context.user, context.account)
6
6
  end
7
+
8
+ def show?
9
+ context.user_access_module.any_access_to_account?(context.user, context.account)
10
+ end
11
+
12
+ def create?
13
+ context.user_access_module.admin_or_developer_access_to_account?(context.user, context.account)
14
+ end
15
+
16
+ def destroy?
17
+ context.user_access_module.admin_or_developer_access_to_account?(context.user, context.account)
18
+ end
7
19
  end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UffizziCore::Api::Cli::V1::ProjectSerializer::ComposeFileSerializer < UffizziCore::BaseSerializer
4
+ type :compose_file
5
+
6
+ attributes :source
7
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UffizziCore::Api::Cli::V1::ProjectSerializer::DeploymentSerializer < UffizziCore::BaseSerializer
4
+ type :deployment
5
+
6
+ attributes :id,
7
+ :preview_url,
8
+ :state
9
+
10
+ def preview_url
11
+ UffizziCore::DeploymentService.build_preview_url(object)
12
+ end
13
+ end
@@ -2,6 +2,33 @@
2
2
 
3
3
  class UffizziCore::Api::Cli::V1::ProjectSerializer < UffizziCore::BaseSerializer
4
4
  type :project
5
+ has_many :deployments
6
+ has_many :secrets
7
+ has_one :default_compose
5
8
 
6
- attributes :slug
9
+ attributes :name,
10
+ :slug,
11
+ :description,
12
+ :created_at
13
+
14
+ def default_compose
15
+ object.compose_files.main.first
16
+ end
17
+
18
+ def deployments
19
+ object.deployments.active.map do |deployment|
20
+ deployment.state = if UffizziCore::DeploymentService.failed?(deployment)
21
+ UffizziCore::Deployment::STATE_FAILED
22
+ else
23
+ UffizziCore::Deployment::STATE_ACTIVE
24
+ end
25
+ deployment
26
+ end
27
+ end
28
+
29
+ def secrets
30
+ return [] unless object.secrets
31
+
32
+ object.secrets.map(&:name)
33
+ end
7
34
  end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UffizziCore::Api::Cli::V1::ShortProjectSerializer < UffizziCore::BaseSerializer
4
+ type :project
5
+
6
+ attributes :name, :slug
7
+ end
@@ -8,6 +8,7 @@ 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
@@ -242,10 +243,11 @@ module UffizziCore::DeploymentService
242
243
 
243
244
  def deployment_process_status(deployment)
244
245
  containers = deployment.active_containers
245
- activity_items = containers.map { |container| container.activity_items.order_by_id.last }
246
+ activity_items = containers.map { |container| container.activity_items.order_by_id.last }.compact
246
247
  events = activity_items.map { |activity_item| activity_item.events.order_by_id.last&.state }
247
248
  events = events.flatten.uniq
248
249
 
250
+ return DEPLOYMENT_PROCESS_STATUSES[:queued] if events.empty?
249
251
  return DEPLOYMENT_PROCESS_STATUSES[:failed] if events.include?(UffizziCore::Event.state.failed)
250
252
  return DEPLOYMENT_PROCESS_STATUSES[:building] if events.include?(UffizziCore::Event.state.building)
251
253
 
@@ -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
data/config/routes.rb CHANGED
@@ -15,7 +15,7 @@ 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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module UffizziCore
4
- VERSION = '0.1.14'
4
+ VERSION = '0.1.15'
5
5
  end
@@ -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
+ "204": {
1241
+ "description": "No content"
1242
+ },
1243
+ "404": {
1244
+ "description": "Not Found"
1245
+ },
1246
+ "401": {
1247
+ "description": "Not authorized"
1248
+ }
1249
+ },
1250
+ "description": "Get a project by slug",
1251
+ "summary": "Get a project by slug",
1252
+ "x-controller": "uffizzi_core/api/cli/v1/projects",
1253
+ "x-action": "show"
1254
+ },
1255
+ "delete": {
1256
+ "tags": [
1257
+ "Project"
1258
+ ],
1259
+ "operationId": "Project-destroy",
1260
+ "parameters": [
1261
+ {
1262
+ "name": "slug",
1263
+ "description": "Scope response to slug",
1264
+ "required": true,
1265
+ "in": "path",
1266
+ "type": "string"
1267
+ }
1268
+ ],
1269
+ "responses": {
1270
+ "200": {
1271
+ "description": "OK",
1272
+ "schema": {
1273
+ "type": "object",
1274
+ "properties": {
1275
+ "project": {
1276
+ "$ref": "#/definitions/Project"
1277
+ }
1278
+ }
1279
+ }
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
- "UffizziCore_Project": {
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
  }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: uffizzi_core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.14
4
+ version: 0.1.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - Josh Thurman
@@ -736,6 +736,7 @@ files:
736
736
  - app/forms/uffizzi_core/api/cli/v1/config_file/create_form.rb
737
737
  - app/forms/uffizzi_core/api/cli/v1/deployment/create_form.rb
738
738
  - app/forms/uffizzi_core/api/cli/v1/deployment/update_form.rb
739
+ - app/forms/uffizzi_core/api/cli/v1/project/create_form.rb
739
740
  - app/forms/uffizzi_core/api/cli/v1/project/update_form.rb
740
741
  - app/forms/uffizzi_core/api/cli/v1/secret/bulk_assign_form.rb
741
742
  - app/forms/uffizzi_core/api/cli/v1/session_create_form.rb
@@ -838,6 +839,8 @@ files:
838
839
  - app/responders/uffizzi_core/json_responder.rb
839
840
  - app/serializers/uffizzi_core/api/cli/v1/account/credential_serializer.rb
840
841
  - app/serializers/uffizzi_core/api/cli/v1/project_serializer.rb
842
+ - app/serializers/uffizzi_core/api/cli/v1/project_serializer/compose_file_serializer.rb
843
+ - app/serializers/uffizzi_core/api/cli/v1/project_serializer/deployment_serializer.rb
841
844
  - app/serializers/uffizzi_core/api/cli/v1/projects/compose_file_serializer.rb
842
845
  - app/serializers/uffizzi_core/api/cli/v1/projects/deployment_serializer.rb
843
846
  - app/serializers/uffizzi_core/api/cli/v1/projects/deployment_serializer/container_serializer.rb
@@ -847,6 +850,7 @@ files:
847
850
  - app/serializers/uffizzi_core/api/cli/v1/projects/deployments/container_serializer/container_config_file_serializer.rb
848
851
  - app/serializers/uffizzi_core/api/cli/v1/projects/deployments/container_serializer/container_config_file_serializer/config_file_serializer.rb
849
852
  - app/serializers/uffizzi_core/api/cli/v1/projects/secret_serializer.rb
853
+ - app/serializers/uffizzi_core/api/cli/v1/short_project_serializer.rb
850
854
  - app/serializers/uffizzi_core/api/cli/v1/user_serializer.rb
851
855
  - app/serializers/uffizzi_core/api/cli/v1/user_serializer/account_serializer.rb
852
856
  - app/serializers/uffizzi_core/base_serializer.rb