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.
- checksums.yaml +4 -4
- data/app/contexts/uffizzi_core/account_context.rb +12 -0
- data/app/contexts/uffizzi_core/base_context.rb +1 -2
- data/app/contexts/uffizzi_core/project_context.rb +2 -2
- data/app/controllers/concerns/uffizzi_core/dependency_injection_concern.rb +6 -0
- data/app/controllers/uffizzi_core/api/cli/v1/accounts/application_controller.rb +11 -0
- data/app/controllers/uffizzi_core/api/cli/v1/{account → accounts}/credentials_controller.rb +2 -2
- data/app/controllers/uffizzi_core/api/cli/v1/accounts/projects_controller.rb +34 -0
- data/app/controllers/uffizzi_core/api/cli/v1/ci/application_controller.rb +5 -0
- data/app/controllers/uffizzi_core/api/cli/v1/ci/sessions_controller.rb +36 -0
- data/app/controllers/uffizzi_core/api/cli/v1/projects/application_controller.rb +5 -1
- data/app/controllers/uffizzi_core/api/cli/v1/projects/deployments/activity_items_controller.rb +8 -1
- data/app/controllers/uffizzi_core/api/cli/v1/projects_controller.rb +12 -26
- data/app/controllers/uffizzi_core/application_controller.rb +6 -0
- data/app/forms/uffizzi_core/api/cli/v1/deployment/create_form.rb +15 -1
- data/app/forms/uffizzi_core/api/cli/v1/deployment/update_form.rb +1 -0
- data/app/forms/uffizzi_core/api/cli/v1/template/create_form.rb +1 -1
- data/app/lib/uffizzi_core/concerns/models/account.rb +0 -1
- data/app/lib/uffizzi_core/concerns/models/project.rb +0 -1
- data/app/lib/uffizzi_core/concerns/models/user_project.rb +1 -1
- data/app/models/uffizzi_core/project.rb +1 -0
- data/app/policies/uffizzi_core/api/cli/v1/{account → accounts}/credentials_policy.rb +1 -1
- data/app/policies/uffizzi_core/api/cli/v1/accounts/projects_policy.rb +7 -0
- data/app/policies/uffizzi_core/api/cli/v1/projects_policy.rb +0 -4
- data/app/serializers/uffizzi_core/api/cli/v1/{account → accounts}/credential_serializer.rb +1 -1
- data/app/serializers/uffizzi_core/api/cli/v1/accounts/project_serializer.rb +11 -0
- data/app/serializers/uffizzi_core/api/cli/v1/project_serializer/account_serializer.rb +5 -0
- data/app/serializers/uffizzi_core/api/cli/v1/project_serializer.rb +1 -0
- data/app/serializers/uffizzi_core/api/cli/v1/short_project_serializer.rb +1 -1
- data/app/serializers/uffizzi_core/api/cli/v1/user_serializer/account_serializer.rb +1 -1
- data/app/serializers/uffizzi_core/controller/deploy_containers/container_serializer.rb +3 -8
- data/app/services/uffizzi_core/compose_file/parsers/services/healthcheck_parser_service.rb +23 -7
- data/app/services/uffizzi_core/deployment_service.rb +20 -23
- data/config/locales/en.yml +8 -2
- data/config/routes.rb +8 -3
- data/lib/uffizzi_core/version.rb +1 -1
- data/lib/uffizzi_core.rb +1 -0
- metadata +13 -9
- data/app/controllers/uffizzi_core/api/cli/v1/account/application_controller.rb +0 -7
- data/app/lib/uffizzi_core/concerns/models/invitation.rb +0 -31
- data/app/models/uffizzi_core/invitation.rb +0 -5
- 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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 169a9ec674c81b791babc5049b74c807a9150da4534980f6b6eb2188b3b12771
|
4
|
+
data.tar.gz: c3365c36312f14cf56a3d8c71b293939d667369b8a6df9da67925620127b514e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
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 =
|
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::
|
5
|
-
before_action :
|
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,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
|
data/app/controllers/uffizzi_core/api/cli/v1/projects/deployments/activity_items_controller.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
-
|
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::
|
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
|
@@ -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::
|
3
|
+
class UffizziCore::Api::Cli::V1::Accounts::CredentialSerializer < UffizziCore::BaseSerializer
|
4
4
|
attributes :id, :username, :password, :type, :state
|
5
5
|
|
6
6
|
def password
|
@@ -41,12 +41,7 @@ class UffizziCore::Controller::DeployContainers::ContainerSerializer < UffizziCo
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def tag
|
44
|
-
|
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.
|
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
|
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
|
-
|
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
|
-
|
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,
|
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
|
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
|
-
|
98
|
-
|
99
|
-
|
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
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
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
|
data/config/locales/en.yml
CHANGED
@@ -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
|
-
|
60
|
-
|
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', '
|
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
|
-
|
40
|
-
|
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
|
data/lib/uffizzi_core/version.rb
CHANGED
data/lib/uffizzi_core.rb
CHANGED
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.
|
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-
|
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/
|
711
|
-
- app/controllers/uffizzi_core/api/cli/v1/
|
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/
|
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/
|
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,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
|