uffizzi_core 0.1.14 → 0.1.15

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.
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