uffizzi_core 0.7.1 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/app/contexts/uffizzi_core/account_context.rb +12 -0
  3. data/app/contexts/uffizzi_core/base_context.rb +1 -2
  4. data/app/contexts/uffizzi_core/project_context.rb +2 -2
  5. data/app/controllers/concerns/uffizzi_core/dependency_injection_concern.rb +6 -0
  6. data/app/controllers/uffizzi_core/api/cli/v1/accounts/application_controller.rb +11 -0
  7. data/app/controllers/uffizzi_core/api/cli/v1/{account → accounts}/credentials_controller.rb +2 -2
  8. data/app/controllers/uffizzi_core/api/cli/v1/accounts/projects_controller.rb +34 -0
  9. data/app/controllers/uffizzi_core/api/cli/v1/ci/application_controller.rb +5 -0
  10. data/app/controllers/uffizzi_core/api/cli/v1/ci/sessions_controller.rb +36 -0
  11. data/app/controllers/uffizzi_core/api/cli/v1/projects/application_controller.rb +5 -1
  12. data/app/controllers/uffizzi_core/api/cli/v1/projects/deployments/activity_items_controller.rb +8 -1
  13. data/app/controllers/uffizzi_core/api/cli/v1/projects_controller.rb +12 -26
  14. data/app/controllers/uffizzi_core/application_controller.rb +6 -0
  15. data/app/forms/uffizzi_core/api/cli/v1/deployment/create_form.rb +15 -1
  16. data/app/forms/uffizzi_core/api/cli/v1/deployment/update_form.rb +1 -0
  17. data/app/forms/uffizzi_core/api/cli/v1/template/create_form.rb +1 -1
  18. data/app/lib/uffizzi_core/concerns/models/account.rb +0 -1
  19. data/app/lib/uffizzi_core/concerns/models/project.rb +0 -1
  20. data/app/lib/uffizzi_core/concerns/models/user_project.rb +1 -1
  21. data/app/models/uffizzi_core/project.rb +1 -0
  22. data/app/policies/uffizzi_core/api/cli/v1/{account → accounts}/credentials_policy.rb +1 -1
  23. data/app/policies/uffizzi_core/api/cli/v1/accounts/projects_policy.rb +7 -0
  24. data/app/policies/uffizzi_core/api/cli/v1/projects_policy.rb +0 -4
  25. data/app/serializers/uffizzi_core/api/cli/v1/{account → accounts}/credential_serializer.rb +1 -1
  26. data/app/serializers/uffizzi_core/api/cli/v1/accounts/project_serializer.rb +11 -0
  27. data/app/serializers/uffizzi_core/api/cli/v1/project_serializer/account_serializer.rb +5 -0
  28. data/app/serializers/uffizzi_core/api/cli/v1/project_serializer.rb +1 -0
  29. data/app/serializers/uffizzi_core/api/cli/v1/short_project_serializer.rb +1 -1
  30. data/app/serializers/uffizzi_core/api/cli/v1/user_serializer/account_serializer.rb +1 -1
  31. data/app/serializers/uffizzi_core/controller/deploy_containers/container_serializer.rb +3 -8
  32. data/app/services/uffizzi_core/compose_file/parsers/services/healthcheck_parser_service.rb +23 -7
  33. data/app/services/uffizzi_core/deployment_service.rb +20 -23
  34. data/config/locales/en.yml +8 -2
  35. data/config/routes.rb +8 -3
  36. data/lib/uffizzi_core/version.rb +1 -1
  37. data/lib/uffizzi_core.rb +1 -0
  38. metadata +13 -9
  39. data/app/controllers/uffizzi_core/api/cli/v1/account/application_controller.rb +0 -7
  40. data/app/lib/uffizzi_core/concerns/models/invitation.rb +0 -31
  41. data/app/models/uffizzi_core/invitation.rb +0 -5
  42. data/app/models/uffizzi_core/repo/github.rb +0 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 25654d45dce9f26feb5a3cca55a5891bb389216e749512b2900898bec4a8da0b
4
- data.tar.gz: cb7784c03bcffb216adc343ae30e0ef0c51e3038791da4fe0229b86179cdc8e9
3
+ metadata.gz: 169a9ec674c81b791babc5049b74c807a9150da4534980f6b6eb2188b3b12771
4
+ data.tar.gz: c3365c36312f14cf56a3d8c71b293939d667369b8a6df9da67925620127b514e
5
5
  SHA512:
6
- metadata.gz: c3b6ae9974961ae5d39e723264e6c72fa0f4dfa9f99085a6550a98af67afd6ddcbd92f98e7f815ff602bb7f6a3144d2f87ac9d61a58f228099b9dedd537ce6be
7
- data.tar.gz: 572bcfcc9d1e3396d721a83a60c703db10c0b3848031e35b63aa26065b67ceb6fc11bb5278fd6b383e4686a5885758d45d69b0a3c3314cda4f6d93fc3a81d93b
6
+ metadata.gz: f8af4f54965d0557094566deb6d3bea447ede3071891aa4bd7d00139b3795a9644fd6b8d71a346b8b6aeff113cc578bdde3f4f64e45d21bb31f5d59b531e15e9
7
+ data.tar.gz: aa2b7c6fce6745775164119324cd7298cd2382246764026c4aa4bf6ebba3f1c8c390eba3cd3a9bde9b512fb1ec3607da5fee8c376bcac79e953d9efaccd7d811
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UffizziCore::AccountContext
4
+ attr_reader :user, :user_access_module, :account, :params
5
+
6
+ def initialize(user, user_access_module, account, params)
7
+ @user = user
8
+ @user_access_module = user_access_module
9
+ @account = account
10
+ @params = params
11
+ end
12
+ end
@@ -1,12 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class UffizziCore::BaseContext
4
- attr_reader :user, :user_access_module, :params, :account
4
+ attr_reader :user, :user_access_module, :params
5
5
 
6
6
  def initialize(user, user_access_module, params)
7
7
  @user = user
8
8
  @user_access_module = user_access_module
9
- @account = user.organizational_account
10
9
  @params = params
11
10
  end
12
11
  end
@@ -3,10 +3,10 @@
3
3
  class UffizziCore::ProjectContext
4
4
  attr_reader :user, :user_access_module, :project, :account, :params
5
5
 
6
- def initialize(user, user_access_module, project, params)
6
+ def initialize(user, user_access_module, project, account, params)
7
7
  @user = user
8
8
  @user_access_module = user_access_module
9
- @account = user.organizational_account
9
+ @account = account
10
10
  @project = project
11
11
  @params = params
12
12
  end
@@ -15,6 +15,12 @@ module UffizziCore::DependencyInjectionConcern
15
15
  module_class(:volume_parser)
16
16
  end
17
17
 
18
+ def ci_session
19
+ return unless module_exists?(:ci_session)
20
+
21
+ module_class(:ci_session)
22
+ end
23
+
18
24
  def password_protection_module
19
25
  return unless module_exists?(:password_protection)
20
26
 
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UffizziCore::Api::Cli::V1::Accounts::ApplicationController < UffizziCore::Api::Cli::V1::ApplicationController
4
+ def resource_account
5
+ @resource_account ||= current_user.accounts.find(params[:account_id])
6
+ end
7
+
8
+ def policy_context
9
+ UffizziCore::AccountContext.new(current_user, user_access_module, resource_account, params)
10
+ end
11
+ end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # @resource Account/Credential
4
- class UffizziCore::Api::Cli::V1::Account::CredentialsController < UffizziCore::Api::Cli::V1::Account::ApplicationController
5
- before_action :authorize_uffizzi_core_api_cli_v1_account_credentials
4
+ class UffizziCore::Api::Cli::V1::Accounts::CredentialsController < UffizziCore::Api::Cli::V1::Accounts::ApplicationController
5
+ before_action :authorize_uffizzi_core_api_cli_v1_accounts_credentials
6
6
 
7
7
  # Get a list of accounts credential
8
8
  #
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @resource Project
4
+
5
+ class UffizziCore::Api::Cli::V1::Accounts::ProjectsController < UffizziCore::Api::Cli::V1::Accounts::ApplicationController
6
+ before_action :authorize_uffizzi_core_api_cli_v1_accounts_projects
7
+
8
+ # Create a project
9
+ #
10
+ # @path [POST] /api/cli/v1/accounts/{account_id}/projects
11
+ # @parameter params(required,body) [object<name: string, slug: string, description: string>]
12
+ #
13
+ # @response <object< project: Project>> 200 OK
14
+ # @response 404 Not Found
15
+ # @response 401 Not authorized
16
+ # @response [object<errors: object<password: string >>] 422 Unprocessable entity
17
+
18
+ def create
19
+ project_form = UffizziCore::Api::Cli::V1::Project::CreateForm.new(project_params)
20
+ project_form.account = current_user.organizational_account
21
+
22
+ if project_form.save
23
+ UffizziCore::ProjectService.add_users_to_project!(project_form, current_user)
24
+ end
25
+
26
+ respond_with project_form
27
+ end
28
+
29
+ private
30
+
31
+ def project_params
32
+ params.require(:project)
33
+ end
34
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UffizziCore::Api::Cli::V1::Ci::ApplicationController < UffizziCore::Api::Cli::V1::ApplicationController
4
+ before_action :authenticate_request!
5
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @resource Uffizzi
4
+
5
+ class UffizziCore::Api::Cli::V1::Ci::SessionsController < UffizziCore::Api::Cli::V1::Ci::ApplicationController
6
+ skip_before_action :authenticate_request!, only: [:create]
7
+
8
+ # Create session
9
+ #
10
+ # @path [POST] /api/cli/v1/github/session
11
+ #
12
+ # @parameter user(required,body) [object<token: string >]
13
+ # @response [object<account_id: string, project_slug: string>] 201 Created successfully
14
+ # @response [object<errors: object<token: string >>] 422 Unprocessable entity
15
+ def create
16
+ return render json: { errors: { title: [I18n.t('session.unsupported_login_type')] } }, status: :unprocessable_entity unless ci_session
17
+
18
+ session_data, errors = ci_session.session_data_from_ci(user_params)
19
+ return render json: { errors: errors }, status: :unprocessable_entity if errors.present?
20
+
21
+ sign_in(session_data[:user])
22
+
23
+ data = {
24
+ account_id: session_data[:account_id],
25
+ project_slug: session_data[:project_slug],
26
+ }
27
+
28
+ render json: data, status: :created
29
+ end
30
+
31
+ private
32
+
33
+ def user_params
34
+ params.require(:user).permit(:token)
35
+ end
36
+ end
@@ -5,7 +5,11 @@ class UffizziCore::Api::Cli::V1::Projects::ApplicationController < UffizziCore::
5
5
  @resource_project ||= current_user.projects.find_by!(slug: params[:project_slug])
6
6
  end
7
7
 
8
+ def resource_account
9
+ @resource_account ||= resource_project.account
10
+ end
11
+
8
12
  def policy_context
9
- UffizziCore::ProjectContext.new(current_user, user_access_module, resource_project, params)
13
+ UffizziCore::ProjectContext.new(current_user, user_access_module, resource_project, resource_account, params)
10
14
  end
11
15
  end
@@ -15,7 +15,14 @@ class UffizziCore::Api::Cli::V1::Projects::Deployments::ActivityItemsController
15
15
  # @response 401 Not authorized
16
16
  # @response 404 Not found
17
17
  def index
18
- activity_items = resource_deployment
18
+ deployment = resource_project.deployments.existed.find(params[:deployment_id])
19
+
20
+ unless deployment.active?
21
+ return render json: { errors: { title: [I18n.t('deployment.invalid_state', state: deployment.state)] } },
22
+ status: :unprocessable_entity
23
+ end
24
+
25
+ activity_items = deployment
19
26
  .activity_items
20
27
  .page(page)
21
28
  .per(per_page)
@@ -25,30 +25,7 @@ class UffizziCore::Api::Cli::V1::ProjectsController < UffizziCore::Api::Cli::V1:
25
25
  # @response 404 Not Found
26
26
  # @response 401 Not authorized
27
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
28
+ respond_with resource_project
52
29
  end
53
30
 
54
31
  # Delete a project
@@ -60,8 +37,7 @@ class UffizziCore::Api::Cli::V1::ProjectsController < UffizziCore::Api::Cli::V1:
60
37
  # @response 401 Not authorized
61
38
 
62
39
  def destroy
63
- project = current_user.organizational_account.active_projects.find_by!(slug: params[:slug])
64
- project.disable!
40
+ resource_project.disable!
65
41
 
66
42
  head :no_content
67
43
  end
@@ -71,4 +47,14 @@ class UffizziCore::Api::Cli::V1::ProjectsController < UffizziCore::Api::Cli::V1:
71
47
  def project_params
72
48
  params.require(:project)
73
49
  end
50
+
51
+ def resource_project
52
+ @resource_project ||= current_user.projects.find_by(slug: params[:slug])
53
+ end
54
+
55
+ def policy_context
56
+ account = resource_project&.account || current_user.organizational_account
57
+
58
+ UffizziCore::AccountContext.new(current_user, user_access_module, account, params)
59
+ end
74
60
  end
@@ -19,10 +19,16 @@ class UffizziCore::ApplicationController < ActionController::Base
19
19
  render_not_found(exception)
20
20
  end
21
21
 
22
+ rescue_from Pundit::NotAuthorizedError, with: :render_not_authorized
23
+
22
24
  before_action :authenticate_request!
23
25
  skip_before_action :verify_authenticity_token
24
26
  respond_to :json
25
27
 
28
+ def render_not_authorized
29
+ render json: { errors: { title: [I18n.t('session.unauthorized')] } }, status: :forbidden
30
+ end
31
+
26
32
  def policy_context
27
33
  UffizziCore::BaseContext.new(current_user, user_access_module, params)
28
34
  end
@@ -17,10 +17,10 @@ class UffizziCore::Api::Cli::V1::Deployment::CreateForm < UffizziCore::Deploymen
17
17
  :command,
18
18
  :receive_incoming_requests,
19
19
  :continuously_deploy,
20
- { healthcheck: {} },
21
20
  { variables: [:name, :value],
22
21
  secret_variables: [:name, :value],
23
22
  volumes: [:source, :target, :type, :read_only],
23
+ healthcheck: [:test, :interval, :timeout, :retries, :start_period, :disable, { test: [] }],
24
24
  repo_attributes: [
25
25
  :namespace,
26
26
  :name,
@@ -51,6 +51,7 @@ class UffizziCore::Api::Cli::V1::Deployment::CreateForm < UffizziCore::Deploymen
51
51
  validate :check_exists_ingress_container
52
52
  validate :check_max_memory_limit
53
53
  validate :check_max_memory_request
54
+ validate :check_secrets_exist_in_database
54
55
 
55
56
  def assign_dependences!(project, user)
56
57
  self.project = project
@@ -91,4 +92,17 @@ class UffizziCore::Api::Cli::V1::Deployment::CreateForm < UffizziCore::Deploymen
91
92
 
92
93
  errors.add(:containers, :max_memory_request_error, max: project.account.container_memory_limit)
93
94
  end
95
+
96
+ def check_secrets_exist_in_database
97
+ return if compose_file.nil?
98
+
99
+ existing_secrets = project.secrets.pluck('name')
100
+ compose_file.template.payload['containers_attributes']
101
+ .map { |container| container['secret_variables'].map { |secret| secret['name'] } }.flatten.uniq
102
+ .select { |secret| existing_secrets.exclude?(secret) }
103
+ .each do |secret|
104
+ error_message = I18n.t('compose.project_secret_not_found', secret: secret)
105
+ errors.add(:secret_variables, error_message)
106
+ end
107
+ end
94
108
  end
@@ -19,6 +19,7 @@ class UffizziCore::Api::Cli::V1::Deployment::UpdateForm < UffizziCore::Deploymen
19
19
  { variables: [:name, :value],
20
20
  secret_variables: [:name, :value],
21
21
  volumes: [:source, :target, :type, :read_only],
22
+ healthcheck: [:test, :interval, :timeout, :retries, :start_period, :disable, { test: [] }],
22
23
  repo_attributes: [
23
24
  :namespace,
24
25
  :name,
@@ -18,10 +18,10 @@ class UffizziCore::Api::Cli::V1::Template::CreateForm < UffizziCore::Template
18
18
  :continuously_deploy,
19
19
  :service_name,
20
20
  :name,
21
- :healthcheck,
22
21
  { variables: [:name, :value],
23
22
  secret_variables: [:name, :value],
24
23
  volumes: [:source, :target, :type, :read_only],
24
+ healthcheck: [:test, :interval, :timeout, :retries, :start_period, :disable, { test: [] }],
25
25
  repo_attributes: [
26
26
  :namespace,
27
27
  :name,
@@ -24,7 +24,6 @@ module UffizziCore::Concerns::Models::Account
24
24
  has_many :projects, dependent: :destroy
25
25
  has_many :deployments, through: :projects
26
26
  has_many :payments, dependent: :destroy
27
- has_many :invitations, as: :entityable
28
27
 
29
28
  aasm(:state) do
30
29
  state :active, initial: true
@@ -16,7 +16,6 @@ module UffizziCore::Concerns::Models::Project
16
16
  has_many :deployments, dependent: :destroy
17
17
  has_many :user_projects, dependent: :destroy
18
18
  has_many :users, through: :user_projects
19
- has_many :invitations, as: :entityable
20
19
  has_many :config_files, dependent: :destroy
21
20
  has_many :templates, dependent: :destroy
22
21
  has_many :credentials, through: :account
@@ -8,7 +8,7 @@ module UffizziCore::Concerns::Models::UserProject
8
8
 
9
9
  self.table_name = UffizziCore.table_names[:user_projects]
10
10
 
11
- enumerize :role, in: UffizziCore.user_project_roles, predicates: true
11
+ enumerize :role, in: UffizziCore.user_project_roles, predicates: true, scope: true
12
12
  validates :role, presence: true
13
13
 
14
14
  belongs_to :user
@@ -8,6 +8,7 @@
8
8
  # @property secrets [string]
9
9
  # @property default_compose [object<source: string>]
10
10
  # @property deployments [object<id: integer, domain: string>]
11
+ # @property account [object<id: integer, kind: string, state: string>]
11
12
 
12
13
  class UffizziCore::Project < UffizziCore::ApplicationRecord
13
14
  include UffizziCore::Concerns::Models::Project
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class UffizziCore::Api::Cli::V1::Account::CredentialsPolicy < UffizziCore::ApplicationPolicy
3
+ class UffizziCore::Api::Cli::V1::Accounts::CredentialsPolicy < UffizziCore::ApplicationPolicy
4
4
  def index?
5
5
  context.user_access_module.admin_access_to_account?(context.user, context.account)
6
6
  end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UffizziCore::Api::Cli::V1::Accounts::ProjectsPolicy < UffizziCore::ApplicationPolicy
4
+ def create?
5
+ context.user_access_module.admin_or_developer_access_to_account?(context.user, context.account)
6
+ end
7
+ end
@@ -9,10 +9,6 @@ class UffizziCore::Api::Cli::V1::ProjectsPolicy < UffizziCore::ApplicationPolicy
9
9
  context.user_access_module.any_access_to_account?(context.user, context.account)
10
10
  end
11
11
 
12
- def create?
13
- context.user_access_module.admin_or_developer_access_to_account?(context.user, context.account)
14
- end
15
-
16
12
  def destroy?
17
13
  context.user_access_module.admin_or_developer_access_to_account?(context.user, context.account)
18
14
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class UffizziCore::Api::Cli::V1::Account::CredentialSerializer < UffizziCore::BaseSerializer
3
+ class UffizziCore::Api::Cli::V1::Accounts::CredentialSerializer < UffizziCore::BaseSerializer
4
4
  attributes :id, :username, :password, :type, :state
5
5
 
6
6
  def password
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UffizziCore::Api::Cli::V1::Accounts::ProjectSerializer < UffizziCore::BaseSerializer
4
+ type :project
5
+
6
+ attributes :name,
7
+ :slug,
8
+ :account_id,
9
+ :description,
10
+ :created_at
11
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UffizziCore::Api::Cli::V1::ProjectSerializer::AccountSerializer < UffizziCore::BaseSerializer
4
+ attributes :id, :kind, :state, :name
5
+ end
@@ -5,6 +5,7 @@ class UffizziCore::Api::Cli::V1::ProjectSerializer < UffizziCore::BaseSerializer
5
5
  has_many :deployments
6
6
  has_many :secrets
7
7
  has_one :default_compose
8
+ belongs_to :account
8
9
 
9
10
  attributes :name,
10
11
  :slug,
@@ -3,5 +3,5 @@
3
3
  class UffizziCore::Api::Cli::V1::ShortProjectSerializer < UffizziCore::BaseSerializer
4
4
  type :project
5
5
 
6
- attributes :name, :slug
6
+ attributes :name, :slug, :account_id
7
7
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class UffizziCore::Api::Cli::V1::UserSerializer::AccountSerializer < UffizziCore::BaseSerializer
4
- attributes :id, :state
4
+ attributes :id, :kind, :state, :name
5
5
  end
@@ -41,12 +41,7 @@ class UffizziCore::Controller::DeployContainers::ContainerSerializer < UffizziCo
41
41
  end
42
42
 
43
43
  def tag
44
- case object.repo.type
45
- when UffizziCore::Repo::Github.name
46
- UffizziCore::RepoService.tag(object.repo)
47
- else
48
- object.tag
49
- end
44
+ object.tag
50
45
  end
51
46
 
52
47
  def entrypoint
@@ -58,7 +53,7 @@ class UffizziCore::Controller::DeployContainers::ContainerSerializer < UffizziCo
58
53
  end
59
54
 
60
55
  def healthcheck
61
- return {} if object.healthcheck.nil?
56
+ return {} if object.healthcheck.blank?
62
57
 
63
58
  command = object.healthcheck['test']
64
59
  new_command = if command.is_a?(Array)
@@ -68,6 +63,6 @@ class UffizziCore::Controller::DeployContainers::ContainerSerializer < UffizziCo
68
63
  command.split
69
64
  end
70
65
 
71
- object.healthcheck.merge(test: new_command)
66
+ object.healthcheck.merge('test' => new_command)
72
67
  end
73
68
  end
@@ -11,10 +11,10 @@ class UffizziCore::ComposeFile::Parsers::Services::HealthcheckParserService
11
11
 
12
12
  {
13
13
  test: command,
14
- interval: parse_time(healthcheck_data['interval']),
15
- timeout: parse_time(healthcheck_data['timeout']),
14
+ interval: parse_time(:interval, healthcheck_data['interval']),
15
+ timeout: parse_time(:timeout, healthcheck_data['timeout']),
16
16
  retries: parse_retries(healthcheck_data['retries']),
17
- start_period: parse_time(healthcheck_data['start_period']),
17
+ start_period: parse_time(:start_period, healthcheck_data['start_period']),
18
18
  disable: parse_disable_option(healthcheck_data['disable'], command),
19
19
  }
20
20
  end
@@ -28,7 +28,11 @@ class UffizziCore::ComposeFile::Parsers::Services::HealthcheckParserService
28
28
  case command
29
29
  when Array
30
30
  start_command = command.first
31
- raise UffizziCore::ComposeFile::ParseError unless REQUIRED_START_COMMANDS.include?(start_command)
31
+
32
+ unless REQUIRED_START_COMMANDS.include?(start_command)
33
+ raise UffizziCore::ComposeFile::ParseError,
34
+ I18n.t('compose.required_start_commands', available_commands: REQUIRED_START_COMMANDS.join(', '))
35
+ end
32
36
 
33
37
  command
34
38
  when String
@@ -39,10 +43,22 @@ class UffizziCore::ComposeFile::Parsers::Services::HealthcheckParserService
39
43
  end
40
44
 
41
45
  def parse_retries(value)
42
- raise UffizziCore::ComposeFile::ParseError, I18n.t('compose.invalid_integer', option: :retries) unless value.is_a?(Integer)
46
+ return if value.nil?
47
+
48
+ unless value.is_a?(Integer)
49
+ raise UffizziCore::ComposeFile::ParseError,
50
+ I18n.t('compose.invalid_retries', value: value)
51
+ end
52
+
53
+ value
43
54
  end
44
55
 
45
- def parse_time(value)
56
+ def parse_time(key, value)
57
+ return if value.nil?
58
+
59
+ error_message = I18n.t('compose.invalid_time_interval', key: key, value: value)
60
+ raise UffizziCore::ComposeFile::ParseError, error_message if value.is_a?(Integer)
61
+
46
62
  tokens = {
47
63
  's' => 1,
48
64
  'm' => 60,
@@ -58,7 +74,7 @@ class UffizziCore::ComposeFile::Parsers::Services::HealthcheckParserService
58
74
 
59
75
  acc
60
76
  rescue StandardError
61
- raise UffizziCore::ComposeFile::ParseError, I18n.t('compose.invalid_time_interval')
77
+ raise UffizziCore::ComposeFile::ParseError, error_message
62
78
  end
63
79
  end
64
80
 
@@ -20,11 +20,7 @@ class UffizziCore::DeploymentService
20
20
  deployment_form.creation_source = UffizziCore::Deployment.creation_source.compose_file_manual
21
21
  deployment_form.metadata = metadata || {}
22
22
 
23
- if deployment_form.save
24
- update_subdomain!(deployment_form)
25
-
26
- UffizziCore::Deployment::CreateJob.perform_async(deployment_form.id)
27
- end
23
+ run_deployment_creation_tasks(deployment_form) if deployment_form.save
28
24
 
29
25
  deployment_form
30
26
  end
@@ -91,27 +87,28 @@ class UffizziCore::DeploymentService
91
87
  end
92
88
 
93
89
  def build_subdomain(deployment)
94
- if deployment.continuous_preview_payload.present?
95
- continuous_preview_payload = deployment.continuous_preview_payload
90
+ return build_docker_continuous_preview_subdomain(deployment) if deployment&.continuous_preview_payload&.fetch('docker', nil).present?
96
91
 
97
- return build_pull_request_subdomain(deployment) if continuous_preview_payload['pull_request'].present?
98
- return build_docker_continuous_preview_subdomain(deployment) if continuous_preview_payload['docker'].present?
99
- end
92
+ github_metadata = deployment.metadata.dig('labels', 'github')
93
+ return build_pull_request_subdomain(deployment) if
94
+ github_metadata&.dig('pull_request', 'number').present? && github_metadata&.dig('repository').present?
100
95
 
101
96
  build_default_subdomain(deployment)
102
97
  end
103
98
 
104
99
  def build_pull_request_subdomain(deployment)
105
- project = deployment.project
106
- continuous_preview_payload = deployment.continuous_preview_payload
107
- pull_request_payload = continuous_preview_payload['pull_request']
108
- repo_name = pull_request_payload['repository_full_name'].split('/').last
109
- deployment_name = name(deployment)
110
- subdomain = "pr#{pull_request_payload['id']}-#{deployment_name}-#{repo_name}-#{project.slug}"
111
-
100
+ github_payload = deployment.metadata.dig('labels', 'github')
101
+ repo_name = github_payload['repository'].split('/').last
102
+ pull_request_number = github_payload['pull_request']['number']
103
+ subdomain = "pr-#{pull_request_number}-#{name(deployment)}-#{repo_name}-#{deployment.project.slug}"
112
104
  format_subdomain(subdomain)
113
105
  end
114
106
 
107
+ def update_subdomain!(deployment)
108
+ deployment.subdomain = build_subdomain(deployment)
109
+ deployment.save!
110
+ end
111
+
115
112
  def build_docker_continuous_preview_subdomain(deployment)
116
113
  project = deployment.project
117
114
  continuous_preview_payload = deployment.continuous_preview_payload
@@ -204,12 +201,6 @@ class UffizziCore::DeploymentService
204
201
  "deployment-#{deployment.id}"
205
202
  end
206
203
 
207
- def update_subdomain!(deployment)
208
- deployment.subdomain = build_subdomain(deployment)
209
-
210
- deployment.save!
211
- end
212
-
213
204
  def pull_request_payload_present?(deployment)
214
205
  deployment.continuous_preview_payload.present? && deployment.continuous_preview_payload['pull_request'].present?
215
206
  end
@@ -222,6 +213,12 @@ class UffizziCore::DeploymentService
222
213
 
223
214
  private
224
215
 
216
+ def run_deployment_creation_tasks(deployment)
217
+ update_subdomain!(deployment)
218
+
219
+ UffizziCore::Deployment::CreateJob.perform_async(deployment.id)
220
+ end
221
+
225
222
  def deployment_process_status(deployment)
226
223
  containers = deployment.active_containers
227
224
  activity_items = containers.map { |container| container.activity_items.order_by_id.last }.compact
@@ -56,8 +56,8 @@ en:
56
56
  project_secret_not_found: Project secret '%{secret}' not found
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
- 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.
59
+ invalid_time_interval: "Invalid time interval: '%{key}:%{value}'. The time interval should be in the following format '{hours}h{minutes}m{seconds}s'. At least one value must be present."
60
+ invalid_retries: "Invalid retries value: 'retries:%{value}'. The value should be an integer."
61
61
  string_or_array_error: "'%{option}' contains an invalid type, it should be a string, or an array"
62
62
  not_implemented: "'%{option}' option is not implemented"
63
63
  infinite_recursion: "Found infinite recursion for key '%{key}'"
@@ -67,6 +67,12 @@ en:
67
67
  volume_type_not_supported: Volumes with type '%{type}' does not supported
68
68
  named_volume_not_exists: Named volume '%{source_path}:%{target_path}' is used in service '%{service_name}' but no declaration was found in the volumes section.
69
69
  invalid_volume_destination: Invalid volume specification '%{spec}' destination can't be '/'
70
+ required_start_commands: "When 'test' is a list the first item must be one of: '%{available_commands}'"
70
71
  secrets:
71
72
  duplicates_exists: Secret with key %{secrets} already exist.
72
73
  invalid_key_length: A secret key must be no longer than 256 characters.
74
+ deployment:
75
+ invalid_state: Deployment %{state}
76
+ session:
77
+ unsupported_login_type: This type of login is not supported
78
+ unauthorized: Unauthorized
data/config/routes.rb CHANGED
@@ -7,7 +7,7 @@ UffizziCore::Engine.routes.draw do
7
7
  namespace :api, defaults: { format: :json } do
8
8
  namespace :cli do
9
9
  namespace :v1 do
10
- resources :projects, only: ['index', 'show', 'create', 'destroy'], param: :slug do
10
+ resources :projects, only: ['index', 'show', 'destroy'], param: :slug do
11
11
  scope module: :projects do
12
12
  resource :compose_file, only: ['show', 'create', 'destroy']
13
13
  resources :deployments, only: ['index', 'show', 'create', 'destroy', 'update'] do
@@ -36,8 +36,13 @@ UffizziCore::Engine.routes.draw do
36
36
  end
37
37
  resource :session, only: ['create', 'destroy']
38
38
 
39
- resource :account, only: [] do
40
- scope module: :account do
39
+ namespace :ci do
40
+ resource :session, only: ['create']
41
+ end
42
+
43
+ resources :accounts, only: [] do
44
+ scope module: :accounts do
45
+ resources :projects, only: ['create']
41
46
  resources :credentials, only: ['index', 'create', 'update', 'destroy'], param: :type do
42
47
  member do
43
48
  get :check_credential
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module UffizziCore
4
- VERSION = '0.7.1'
4
+ VERSION = '1.0.1'
5
5
  end
data/lib/uffizzi_core.rb CHANGED
@@ -60,4 +60,5 @@ module UffizziCore
60
60
  }
61
61
  mattr_accessor :user_creation_sources, default: [:system, :online_registration, :google, :sso]
62
62
  mattr_accessor :user_project_roles, default: [:admin, :developer, :viewer]
63
+ mattr_accessor :account_sources, default: [:manual]
63
64
  end
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.7.1
4
+ version: 1.0.1
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-08-23 00:00:00.000000000 Z
12
+ date: 2022-09-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: aasm
@@ -701,15 +701,19 @@ files:
701
701
  - app/clients/uffizzi_core/github_container_registry_client/request_result.rb
702
702
  - app/clients/uffizzi_core/google_registry_client.rb
703
703
  - app/clients/uffizzi_core/google_registry_client/request_result.rb
704
+ - app/contexts/uffizzi_core/account_context.rb
704
705
  - app/contexts/uffizzi_core/base_context.rb
705
706
  - app/contexts/uffizzi_core/project_context.rb
706
707
  - app/contexts/uffizzi_core/webhooks_context.rb
707
708
  - app/controllers/concerns/uffizzi_core/auth_management.rb
708
709
  - app/controllers/concerns/uffizzi_core/authorization_concern.rb
709
710
  - app/controllers/concerns/uffizzi_core/dependency_injection_concern.rb
710
- - app/controllers/uffizzi_core/api/cli/v1/account/application_controller.rb
711
- - app/controllers/uffizzi_core/api/cli/v1/account/credentials_controller.rb
711
+ - app/controllers/uffizzi_core/api/cli/v1/accounts/application_controller.rb
712
+ - app/controllers/uffizzi_core/api/cli/v1/accounts/credentials_controller.rb
713
+ - app/controllers/uffizzi_core/api/cli/v1/accounts/projects_controller.rb
712
714
  - app/controllers/uffizzi_core/api/cli/v1/application_controller.rb
715
+ - app/controllers/uffizzi_core/api/cli/v1/ci/application_controller.rb
716
+ - app/controllers/uffizzi_core/api/cli/v1/ci/sessions_controller.rb
713
717
  - app/controllers/uffizzi_core/api/cli/v1/projects/application_controller.rb
714
718
  - app/controllers/uffizzi_core/api/cli/v1/projects/compose_files_controller.rb
715
719
  - app/controllers/uffizzi_core/api/cli/v1/projects/deployments/activity_items_controller.rb
@@ -774,7 +778,6 @@ files:
774
778
  - app/lib/uffizzi_core/concerns/models/credential.rb
775
779
  - app/lib/uffizzi_core/concerns/models/deployment.rb
776
780
  - app/lib/uffizzi_core/concerns/models/event.rb
777
- - app/lib/uffizzi_core/concerns/models/invitation.rb
778
781
  - app/lib/uffizzi_core/concerns/models/membership.rb
779
782
  - app/lib/uffizzi_core/concerns/models/payment.rb
780
783
  - app/lib/uffizzi_core/concerns/models/price.rb
@@ -817,7 +820,6 @@ files:
817
820
  - app/models/uffizzi_core/database_offering.rb
818
821
  - app/models/uffizzi_core/deployment.rb
819
822
  - app/models/uffizzi_core/event.rb
820
- - app/models/uffizzi_core/invitation.rb
821
823
  - app/models/uffizzi_core/membership.rb
822
824
  - app/models/uffizzi_core/payment.rb
823
825
  - app/models/uffizzi_core/price.rb
@@ -829,7 +831,6 @@ files:
829
831
  - app/models/uffizzi_core/repo/azure.rb
830
832
  - app/models/uffizzi_core/repo/docker_hub.rb
831
833
  - app/models/uffizzi_core/repo/docker_registry.rb
832
- - app/models/uffizzi_core/repo/github.rb
833
834
  - app/models/uffizzi_core/repo/github_container_registry.rb
834
835
  - app/models/uffizzi_core/repo/google.rb
835
836
  - app/models/uffizzi_core/role.rb
@@ -837,7 +838,8 @@ files:
837
838
  - app/models/uffizzi_core/template.rb
838
839
  - app/models/uffizzi_core/user.rb
839
840
  - app/models/uffizzi_core/user_project.rb
840
- - app/policies/uffizzi_core/api/cli/v1/account/credentials_policy.rb
841
+ - app/policies/uffizzi_core/api/cli/v1/accounts/credentials_policy.rb
842
+ - app/policies/uffizzi_core/api/cli/v1/accounts/projects_policy.rb
841
843
  - app/policies/uffizzi_core/api/cli/v1/projects/compose_files_policy.rb
842
844
  - app/policies/uffizzi_core/api/cli/v1/projects/deployments/activity_items_policy.rb
843
845
  - app/policies/uffizzi_core/api/cli/v1/projects/deployments/containers_policy.rb
@@ -865,8 +867,10 @@ files:
865
867
  - app/repositories/uffizzi_core/usage_repo.rb
866
868
  - app/repositories/uffizzi_core/user_repo.rb
867
869
  - app/responders/uffizzi_core/json_responder.rb
868
- - app/serializers/uffizzi_core/api/cli/v1/account/credential_serializer.rb
870
+ - app/serializers/uffizzi_core/api/cli/v1/accounts/credential_serializer.rb
871
+ - app/serializers/uffizzi_core/api/cli/v1/accounts/project_serializer.rb
869
872
  - app/serializers/uffizzi_core/api/cli/v1/project_serializer.rb
873
+ - app/serializers/uffizzi_core/api/cli/v1/project_serializer/account_serializer.rb
870
874
  - app/serializers/uffizzi_core/api/cli/v1/project_serializer/compose_file_serializer.rb
871
875
  - app/serializers/uffizzi_core/api/cli/v1/project_serializer/deployment_serializer.rb
872
876
  - app/serializers/uffizzi_core/api/cli/v1/projects/compose_file_serializer.rb
@@ -1,7 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class UffizziCore::Api::Cli::V1::Account::ApplicationController < UffizziCore::Api::Cli::V1::ApplicationController
4
- def resource_account
5
- @resource_account ||= current_user.organizational_account
6
- end
7
- end
@@ -1,31 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module UffizziCore::Concerns::Models::Invitation
4
- extend ActiveSupport::Concern
5
-
6
- included do
7
- include AASM
8
- include UffizziCore::StateMachineConcern
9
- extend Enumerize
10
-
11
- self.table_name = UffizziCore.table_names[:invitations]
12
-
13
- enumerize :role, in: [:admin, :developer, :viewer], predicates: true
14
-
15
- belongs_to :entityable, polymorphic: true
16
- belongs_to :invited_by, class_name: UffizziCore::User.name, foreign_key: :invited_by_id
17
- belongs_to :invitee, class_name: UffizziCore::User.name, foreign_key: :invitee_id, optional: true
18
-
19
- validates :email, presence: true, 'uffizzi_core/email': true
20
- validates :token, presence: true, uniqueness: true
21
-
22
- aasm(:status) do
23
- state :pending, initial: true
24
- state :accepted
25
-
26
- event :accept do
27
- transitions from: :pending, to: :accepted
28
- end
29
- end
30
- end
31
- end
@@ -1,5 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class UffizziCore::Invitation < UffizziCore::ApplicationRecord
4
- include UffizziCore::Concerns::Models::Invitation
5
- end
@@ -1,4 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class UffizziCore::Repo::Github < UffizziCore::Repo
4
- end