uffizzi_core 0.1.13 → 0.1.16

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.
Files changed (27) hide show
  1. checksums.yaml +4 -4
  2. data/app/clients/uffizzi_core/docker_hub_client/not_authorized_error.rb +6 -0
  3. data/app/controllers/concerns/uffizzi_core/dependency_injection_concern.rb +6 -0
  4. data/app/controllers/uffizzi_core/api/cli/v1/projects_controller.rb +57 -2
  5. data/app/forms/uffizzi_core/api/cli/v1/deployment/update_form.rb +1 -1
  6. data/app/forms/uffizzi_core/api/cli/v1/project/create_form.rb +7 -0
  7. data/app/lib/uffizzi_core/rbac/user_access_service.rb +4 -0
  8. data/app/models/uffizzi_core/project.rb +9 -2
  9. data/app/policies/uffizzi_core/api/cli/v1/projects_policy.rb +12 -0
  10. data/app/serializers/uffizzi_core/api/cli/v1/project_serializer/compose_file_serializer.rb +7 -0
  11. data/app/serializers/uffizzi_core/api/cli/v1/project_serializer/deployment_serializer.rb +13 -0
  12. data/app/serializers/uffizzi_core/api/cli/v1/project_serializer.rb +28 -1
  13. data/app/serializers/uffizzi_core/api/cli/v1/short_project_serializer.rb +7 -0
  14. data/app/serializers/uffizzi_core/controller/deploy_containers/container_serializer/container_config_file_serializer/config_file_serializer.rb +2 -2
  15. data/app/services/uffizzi_core/compose_file/services_options_service.rb +10 -2
  16. data/app/services/uffizzi_core/deployment_service.rb +6 -15
  17. data/app/services/uffizzi_core/manage_activity_items_service.rb +0 -8
  18. data/app/services/uffizzi_core/project_service.rb +10 -0
  19. data/app/services/uffizzi_core/user_generator_service.rb +11 -5
  20. data/config/routes.rb +1 -1
  21. data/lib/tasks/uffizzi_core_tasks.rake +1 -1
  22. data/lib/uffizzi_core/version.rb +1 -1
  23. data/swagger/v1/swagger.json +173 -1
  24. metadata +7 -5
  25. data/app/lib/uffizzi_core/concerns/models/activity_item.rb +0 -39
  26. data/app/lib/uffizzi_core/concerns/models/credential.rb +0 -65
  27. data/app/lib/uffizzi_core/concerns/models/repo.rb +0 -33
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7d892c859a5a90f309d59a2fd110e3e99719d62f566cda4f7cb1f0815c700f4e
4
- data.tar.gz: df8bed87726cc99d3401b129245a8bc0467d087550d3258f66f08c482f897f7e
3
+ metadata.gz: cfa4de16cbd2efbc1c9b12748807a9c283e206a490eaa4cf544eaee9e5a11733
4
+ data.tar.gz: 8d3d6a27ed932c3760669f2397deef476b57c44ec09b783de51eca3143bb7aad
5
5
  SHA512:
6
- metadata.gz: dc59d9a62a34892c5c50eb0b622e7a5e46ecd0e0cdbd826ea72fd0b27c88dc35ddd7c686b3b46b1aa16c2544374f5f96ca4588d41afb39433b8759fabba8484e
7
- data.tar.gz: 070f387c4d12a5d662c392dfa715dd536d8100aa06978c072dbaee04bec52dd9aa126b396903610dbfc187dbac5542d7c7332d1b5a7df784210b21c1a31cea20
6
+ metadata.gz: 0db9e7b5f79bf19ac9576b516e72792b3a58ff98edccea36ef1f9a4385e214d7498d5c5dc047fb989cd1c958a8ec8be32ad39d0257ab57c8b264a6fef7b85d96
7
+ data.tar.gz: a1f4c8f5a39e04357a1e9185454230b7671dffdac46f180a23310ae07f0b906912cf10fcd252fdfd1d31c7553a3074d139d504d94a916f4b2219e174771be945
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UffizziCore::DockerHubClient
4
+ class NotAuthorizedError < StandardError
5
+ end
6
+ end
@@ -7,6 +7,12 @@ module UffizziCore::DependencyInjectionConcern
7
7
  UffizziCore::UserAccessService.new(module_class(:rbac))
8
8
  end
9
9
 
10
+ def build_parser_module
11
+ return unless module_exists?(:github)
12
+
13
+ module_class(:github).new
14
+ end
15
+
10
16
  private
11
17
 
12
18
  def module_exists?(module_name)
@@ -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
@@ -5,7 +5,7 @@ class UffizziCore::Api::Cli::V1::Deployment::UpdateForm < UffizziCore::Deploymen
5
5
 
6
6
  permit containers_attributes: [
7
7
  :image,
8
- :name,
8
+ :service_name,
9
9
  :tag,
10
10
  :port,
11
11
  :public,
@@ -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
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # rubocop:disable Metrics/LineLength
3
+ # rubocop:disable Layout/LineLength
4
4
  class UffizziCore::Controller::DeployContainers::ContainerSerializer::ContainerConfigFileSerializer::ConfigFileSerializer < UffizziCore::BaseSerializer
5
- # rubocop:enable Metrics/LineLength
5
+ # rubocop:enable Layout/LineLength
6
6
 
7
7
  attributes :id, :filename, :kind, :payload
8
8
  end
@@ -2,6 +2,8 @@
2
2
 
3
3
  class UffizziCore::ComposeFile::ServicesOptionsService
4
4
  class << self
5
+ include UffizziCore::DependencyInjectionConcern
6
+
5
7
  def parse(services, global_configs_data, global_secrets_data, compose_payload)
6
8
  raise UffizziCore::ComposeFile::ParseError, I18n.t('compose.no_services') if services.nil? || services.keys.empty?
7
9
 
@@ -18,7 +20,7 @@ class UffizziCore::ComposeFile::ServicesOptionsService
18
20
 
19
21
  private
20
22
 
21
- def prepare_service_data(service_name, service_data, global_configs_data, global_secrets_data, _compose_payload)
23
+ def prepare_service_data(service_name, service_data, global_configs_data, global_secrets_data, compose_payload)
22
24
  options_data = {}
23
25
  service_data.each_pair do |key, value|
24
26
  service_key = key.to_sym
@@ -27,7 +29,7 @@ class UffizziCore::ComposeFile::ServicesOptionsService
27
29
  when :image
28
30
  UffizziCore::ComposeFile::ServicesOptions::ImageService.parse(value)
29
31
  when :build
30
- raise UffizziCore::ComposeFile::ParseError, I18n.t('compose.not_implemented', option: :build)
32
+ check_and_parse_build_option(value, compose_payload)
31
33
  when :env_file
32
34
  UffizziCore::ComposeFile::ServicesOptions::EnvFileService.parse(value)
33
35
  when :environment
@@ -51,5 +53,11 @@ class UffizziCore::ComposeFile::ServicesOptionsService
51
53
 
52
54
  options_data
53
55
  end
56
+
57
+ def check_and_parse_build_option(value, compose_payload)
58
+ raise UffizziCore::ComposeFile::ParseError, I18n.t('compose.not_implemented', option: :build) unless build_parser_module
59
+
60
+ build_parser_module.parse(value, compose_payload)
61
+ end
54
62
  end
55
63
  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
@@ -103,9 +104,8 @@ module UffizziCore::DeploymentService
103
104
  pull_request_payload = continuous_preview_payload['pull_request']
104
105
  repo_name = pull_request_payload['repository_full_name'].split('/').last
105
106
  deployment_name = name(deployment)
106
- subdomain = "pr#{pull_request_payload['id']}-#{deployment_name}-#{repo_name}-#{project.slug}"
107
107
 
108
- format_subdomain(subdomain)
108
+ "pr#{pull_request_payload['id']}-#{deployment_name}.#{repo_name}.#{project.slug}"
109
109
  end
110
110
 
111
111
  def build_docker_continuous_preview_subdomain(deployment)
@@ -115,17 +115,14 @@ module UffizziCore::DeploymentService
115
115
  repo_name = docker_payload['image'].split('/').last.gsub('_', '-')
116
116
  image_tag = docker_payload['tag'].gsub('_', '-')
117
117
  deployment_name = name(deployment)
118
- subdomain = "#{image_tag}-#{deployment_name}-#{repo_name}-#{project.slug}"
119
118
 
120
- format_subdomain(subdomain)
119
+ "#{image_tag}-#{deployment_name}.#{repo_name}.#{project.slug}"
121
120
  end
122
121
 
123
122
  def build_default_subdomain(deployment)
124
123
  deployment_name = name(deployment)
125
124
  slug = deployment.project.slug.to_s
126
- subdomain = "#{deployment_name}-#{slug}"
127
-
128
- format_subdomain(subdomain)
125
+ "#{deployment_name}.#{slug}"
129
126
  end
130
127
 
131
128
  def build_preview_url(deployment)
@@ -242,10 +239,11 @@ module UffizziCore::DeploymentService
242
239
 
243
240
  def deployment_process_status(deployment)
244
241
  containers = deployment.active_containers
245
- activity_items = containers.map { |container| container.activity_items.order_by_id.last }
242
+ activity_items = containers.map { |container| container.activity_items.order_by_id.last }.compact
246
243
  events = activity_items.map { |activity_item| activity_item.events.order_by_id.last&.state }
247
244
  events = events.flatten.uniq
248
245
 
246
+ return DEPLOYMENT_PROCESS_STATUSES[:queued] if events.empty?
249
247
  return DEPLOYMENT_PROCESS_STATUSES[:failed] if events.include?(UffizziCore::Event.state.failed)
250
248
  return DEPLOYMENT_PROCESS_STATUSES[:building] if events.include?(UffizziCore::Event.state.building)
251
249
 
@@ -295,12 +293,5 @@ module UffizziCore::DeploymentService
295
293
  container.variables.push(*envs)
296
294
  end
297
295
  end
298
-
299
- def format_subdomain(full_subdomain_name)
300
- subdomain_length_limit = Settings.deployment.subdomain.length_limit
301
- return full_subdomain_name if full_subdomain_name.length <= subdomain_length_limit
302
-
303
- full_subdomain_name.slice(0, subdomain_length_limit)
304
- end
305
296
  end
306
297
  end
@@ -116,26 +116,18 @@ 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
-
123
119
  case pod_container_status.to_sym
124
120
  when :running
125
- Rails.logger.info("manage_activity_items get_status dep_id=#{container.deployment.id} running")
126
121
  UffizziCore::Event.state.deployed
127
122
  when :terminated
128
- Rails.logger.info("manage_activity_items get_status dep_id=#{container.deployment.id} terminated")
129
123
  UffizziCore::Event.state.failed
130
124
  when :waiting
131
- Rails.logger.info("manage_activity_items get_status dep_id=#{container.deployment.id} waiting")
132
125
  return UffizziCore::Event.state.failed if ['CrashLoopBackOff'].include?(reason)
133
126
 
134
127
  raise UffizziCore::Deployment::ImagePullError, @deployment.id if ['ErrImagePull', 'ImagePullBackOff'].include?(reason)
135
128
 
136
129
  UffizziCore::Event.state.deploying
137
130
  else
138
- Rails.logger.info("manage_activity_items get_status dep_id=#{container.deployment.id} else")
139
131
  UffizziCore::Event.state.deploying
140
132
  end
141
133
  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
@@ -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 ActiveRecord::RecordInvalid => 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
- else
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
- else
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
- else
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/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
@@ -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.generate(ENV['UFFIZZI_USER_EMAIL'], ENV['UFFIZZI_USER_PASSWORD'], ENV['UFFIZZI_PROJECT_NAME'])
17
+ UffizziCore::UserGeneratorService.safe_generate(ENV['UFFIZZI_USER_EMAIL'], ENV['UFFIZZI_USER_PASSWORD'], ENV['UFFIZZI_PROJECT_NAME'])
18
18
  end
19
19
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module UffizziCore
4
- VERSION = '0.1.13'
4
+ VERSION = '0.1.16'
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.13
4
+ version: 0.1.16
5
5
  platform: ruby
6
6
  authors:
7
7
  - Josh Thurman
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2022-05-30 00:00:00.000000000 Z
12
+ date: 2022-06-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: aasm
@@ -693,6 +693,7 @@ files:
693
693
  - app/clients/uffizzi_core/controller_client.rb
694
694
  - app/clients/uffizzi_core/controller_client/request_result.rb
695
695
  - app/clients/uffizzi_core/docker_hub_client.rb
696
+ - app/clients/uffizzi_core/docker_hub_client/not_authorized_error.rb
696
697
  - app/clients/uffizzi_core/docker_hub_client/request_result.rb
697
698
  - app/clients/uffizzi_core/github_container_registry_client.rb
698
699
  - app/clients/uffizzi_core/github_container_registry_client/request_result.rb
@@ -736,6 +737,7 @@ files:
736
737
  - app/forms/uffizzi_core/api/cli/v1/config_file/create_form.rb
737
738
  - app/forms/uffizzi_core/api/cli/v1/deployment/create_form.rb
738
739
  - app/forms/uffizzi_core/api/cli/v1/deployment/update_form.rb
740
+ - app/forms/uffizzi_core/api/cli/v1/project/create_form.rb
739
741
  - app/forms/uffizzi_core/api/cli/v1/project/update_form.rb
740
742
  - app/forms/uffizzi_core/api/cli/v1/secret/bulk_assign_form.rb
741
743
  - app/forms/uffizzi_core/api/cli/v1/session_create_form.rb
@@ -757,9 +759,6 @@ files:
757
759
  - app/jobs/uffizzi_core/deployment/delete_job.rb
758
760
  - app/jobs/uffizzi_core/deployment/deploy_containers_job.rb
759
761
  - app/jobs/uffizzi_core/deployment/manage_deploy_activity_item_job.rb
760
- - app/lib/uffizzi_core/concerns/models/activity_item.rb
761
- - app/lib/uffizzi_core/concerns/models/credential.rb
762
- - app/lib/uffizzi_core/concerns/models/repo.rb
763
762
  - app/lib/uffizzi_core/rbac/user_access_service.rb
764
763
  - app/mailers/uffizzi_core/application_mailer.rb
765
764
  - app/models/concerns/uffizzi_core/hashid_concern.rb
@@ -838,6 +837,8 @@ files:
838
837
  - app/responders/uffizzi_core/json_responder.rb
839
838
  - app/serializers/uffizzi_core/api/cli/v1/account/credential_serializer.rb
840
839
  - app/serializers/uffizzi_core/api/cli/v1/project_serializer.rb
840
+ - app/serializers/uffizzi_core/api/cli/v1/project_serializer/compose_file_serializer.rb
841
+ - app/serializers/uffizzi_core/api/cli/v1/project_serializer/deployment_serializer.rb
841
842
  - app/serializers/uffizzi_core/api/cli/v1/projects/compose_file_serializer.rb
842
843
  - app/serializers/uffizzi_core/api/cli/v1/projects/deployment_serializer.rb
843
844
  - app/serializers/uffizzi_core/api/cli/v1/projects/deployment_serializer/container_serializer.rb
@@ -847,6 +848,7 @@ files:
847
848
  - app/serializers/uffizzi_core/api/cli/v1/projects/deployments/container_serializer/container_config_file_serializer.rb
848
849
  - app/serializers/uffizzi_core/api/cli/v1/projects/deployments/container_serializer/container_config_file_serializer/config_file_serializer.rb
849
850
  - app/serializers/uffizzi_core/api/cli/v1/projects/secret_serializer.rb
851
+ - app/serializers/uffizzi_core/api/cli/v1/short_project_serializer.rb
850
852
  - app/serializers/uffizzi_core/api/cli/v1/user_serializer.rb
851
853
  - app/serializers/uffizzi_core/api/cli/v1/user_serializer/account_serializer.rb
852
854
  - app/serializers/uffizzi_core/base_serializer.rb
@@ -1,39 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module UffizziCore::Concerns::Models::ActivityItem
4
- extend ActiveSupport::Concern
5
-
6
- included do
7
- include UffizziCore::ActivityItemRepo
8
-
9
- self.table_name = UffizziCore.table_names[:activity_items]
10
-
11
- belongs_to :deployment
12
- belongs_to :container
13
- belongs_to :build, optional: true
14
-
15
- has_many :events, dependent: :destroy
16
-
17
- scope :docker, -> {
18
- where(type: UffizziCore::ActivityItem::Docker.name)
19
- }
20
-
21
- scope :github, -> {
22
- where(type: UffizziCore::ActivityItem::Github.name)
23
- }
24
-
25
- def docker?
26
- type == UffizziCore::ActivityItem::Docker.name
27
- end
28
-
29
- def image
30
- [namespace, name].compact.join('/')
31
- end
32
-
33
- def full_image
34
- return "#{image}:#{tag}" if docker?
35
-
36
- ''
37
- end
38
- end
39
- end
@@ -1,65 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module UffizziCore::Concerns::Models::Credential
4
- extend ActiveSupport::Concern
5
-
6
- included do
7
- include AASM
8
- include UffizziCore::CredentialRepo
9
-
10
- self.table_name = UffizziCore.table_names[:credentials]
11
-
12
- belongs_to :account
13
-
14
- before_destroy :remove_token
15
-
16
- validates :registry_url, presence: true
17
-
18
- aasm :state, column: :state do
19
- state :not_connected, initial: true
20
- state :active
21
- state :unauthorized
22
-
23
- event :activate do
24
- transitions from: [:not_connected, :unauthorized], to: :active
25
- end
26
-
27
- event :unauthorize do
28
- transitions from: [:not_connected, :active], to: :unauthorized
29
- end
30
- end
31
-
32
- def github_container_registry?
33
- type == UffizziCore::Credential::GithubContainerRegistry.name
34
- end
35
-
36
- def docker_hub?
37
- type == UffizziCore::Credential::DockerHub.name
38
- end
39
-
40
- def azure?
41
- type == UffizziCore::Credential::Azure.name
42
- end
43
-
44
- def google?
45
- type == UffizziCore::Credential::Google.name
46
- end
47
-
48
- def amazon?
49
- type == UffizziCore::Credential::Amazon.name
50
- end
51
-
52
- private
53
-
54
- def remove_token
55
- account.projects.find_each do |project|
56
- project.deployments.find_each do |deployment|
57
- containers = deployment.containers
58
- attributes = { continuously_deploy: UffizziCore::Container::STATE_DISABLED }
59
-
60
- containers.with_docker_hub_repo.update_all(attributes) if docker_hub?
61
- end
62
- end
63
- end
64
- end
65
- end
@@ -1,33 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module UffizziCore::Concerns::Models::Repo
4
- extend ActiveSupport::Concern
5
-
6
- included do
7
- extend Enumerize
8
- include UffizziCore::RepoRepo
9
-
10
- self.table_name = UffizziCore.table_names[:repos]
11
-
12
- enumerize :kind, in: [:buildpacks18, :dockerfile, :dotnet, :gatsby, :barestatic], predicates: true
13
-
14
- belongs_to :project
15
- has_one :container, inverse_of: :repo, dependent: :destroy
16
- has_many :builds, dependent: :destroy
17
-
18
- validates :dockerfile_path, presence: true, if: :dockerfile?
19
- validates :delete_preview_after, numericality: { greater_than: 0, only_integer: true }, allow_nil: true
20
-
21
- def docker_hub?
22
- type == UffizziCore::Repo::DockerHub.name
23
- end
24
-
25
- def azure?
26
- type == UffizziCore::Repo::Azure.name
27
- end
28
-
29
- def google?
30
- type == UffizziCore::Repo::Google.name
31
- end
32
- end
33
- end