wco_models 3.1.0.201 → 3.1.0.203
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/assets/stylesheets/wco/application.scss +11 -1
- data/app/assets/stylesheets/wco/main.scss +6 -2
- data/app/controllers/wco/invoices_controller.rb +1 -0
- data/app/controllers/wco/leadsets_controller.rb +8 -1
- data/app/controllers/wco/prices_controller.rb +10 -3
- data/app/models/do/dns_record.rb-txt +15 -0
- data/app/models/wco/leadset.rb +3 -3
- data/app/models/wco/leadset_appliance_tmpl.rb +15 -0
- data/app/models/wco/log.rb +8 -3
- data/app/models/wco/price.rb +1 -1
- data/app/models/wco/profile.rb +3 -2
- data/app/models/wco_email/message_stub.rb +1 -0
- data/app/models/wco_hosting/appliance.rb +13 -11
- data/app/models/wco_hosting/appliance_tmpl.rb +2 -1
- data/app/models/wco_hosting/domain.rb +1 -1
- data/app/models/wco_hosting/serverhost.rb +71 -92
- data/app/models/wco_hosting/{subdomain.rb → subdomain.rb-bk} +4 -0
- data/app/views/wco/leadsets/_form.haml +29 -9
- data/app/views/wco/leadsets/show.haml +77 -73
- data/app/views/wco/prices/_form_mini.haml +18 -0
- data/app/views/wco/prices/_form_table.haml +50 -0
- data/app/views/wco/prices/new.haml +22 -0
- data/app/views/wco/products/index.haml +1 -1
- data/app/views/wco/profiles/_form.haml +6 -0
- data/app/views/wco/profiles/edit.haml +1 -1
- data/app/views/wco/profiles/index.haml +1 -0
- data/app/views/wco_hosting/serverhosts/_list.haml +15 -0
- metadata +9 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 33c64aaf74ef19b78f3ad77b966b57e8c078af95a21960acef1d7a31b2513b43
|
4
|
+
data.tar.gz: b2a5a688f5872b582c73cd3b16d4aae7c4ec709bfe46f4136fca93bfd98a2526
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: baebd3f21a934e5b8a4ce0adf1e6e615b67d7cfbc77225db40fdcc3b30835ae802132af1c0b2ae954b7db1eaf47a11f303eff9b14838808f4177bc22f03bbb48
|
7
|
+
data.tar.gz: 6424f8a5fada86870743887674767e7c4ca39ee7ead9d60130da21954061ed7cdbe9843ad0b4b33653df3e32fd826a1cc4839b8474cf5d77b161f6b33a0724ee
|
@@ -34,10 +34,20 @@ $enable-important-utilities: false;
|
|
34
34
|
/* F */
|
35
35
|
|
36
36
|
.field {
|
37
|
+
border-bottom: 1px solid gray;
|
38
|
+
border-left: 1px solid gray;
|
39
|
+
|
40
|
+
// border-top: 2px solid white;
|
41
|
+
// border-left: 2px solid white;
|
42
|
+
|
37
43
|
display: flex;
|
44
|
+
|
45
|
+
margin-top: 1em;
|
38
46
|
margin-bottom: 0.5em;
|
39
47
|
|
40
|
-
|
48
|
+
padding: 0.5em;
|
49
|
+
|
50
|
+
input[type=text] {
|
41
51
|
flex-grow: 1;
|
42
52
|
}
|
43
53
|
|
@@ -22,6 +22,9 @@ textarea {
|
|
22
22
|
color: blue;
|
23
23
|
}
|
24
24
|
|
25
|
+
.border-left {
|
26
|
+
border-left: 1px solid red !important;
|
27
|
+
}
|
25
28
|
.border-right {
|
26
29
|
border-right: 1px solid red !important;
|
27
30
|
}
|
@@ -144,18 +147,19 @@ textarea.monospace {
|
|
144
147
|
|
145
148
|
.header {
|
146
149
|
display: flex;
|
150
|
+
justify-content: center;
|
147
151
|
|
148
152
|
> * {
|
149
153
|
padding-right: 0.2em;
|
150
154
|
}
|
151
155
|
|
152
|
-
|
156
|
+
.title {
|
153
157
|
display: flex;
|
154
158
|
}
|
155
159
|
}
|
156
160
|
|
157
161
|
.hide, .hidden {
|
158
|
-
display: none;
|
162
|
+
display: none !important;
|
159
163
|
}
|
160
164
|
|
161
165
|
|
@@ -63,6 +63,10 @@ class Wco::LeadsetsController < Wco::ApplicationController
|
|
63
63
|
@leads = @leadset.leads.page( params[:leads_page] ).per( current_profile.per_page )
|
64
64
|
@subscriptions = @leadset.subscriptions
|
65
65
|
@invoices = @leadset.invoices
|
66
|
+
|
67
|
+
@prices = @leadset.appliance_tmpls
|
68
|
+
## _TODO: can remove
|
69
|
+
@all_prices = Wco::Price.all
|
66
70
|
end
|
67
71
|
|
68
72
|
def update
|
@@ -83,8 +87,11 @@ class Wco::LeadsetsController < Wco::ApplicationController
|
|
83
87
|
private
|
84
88
|
|
85
89
|
def set_lists
|
86
|
-
@
|
90
|
+
@appliance_tmpls_list = WcoHosting::ApplianceTmpl.all
|
91
|
+
@appliance_tmpl_prices_list = Wco::Price.all
|
92
|
+
@serverhosts = WcoHosting::Serverhost.all
|
87
93
|
@serverhosts_list = WcoHosting::Serverhost.list
|
94
|
+
@tags = Wco::Tag.all
|
88
95
|
@tags_list = Wco::Tag.list
|
89
96
|
@leads_list = Wco::Lead.all.map { |lead| [ lead.email, lead.id ] }
|
90
97
|
@templates_list = WcoEmail::EmailTemplate.all.map { |t| [ t.slug, t.id ] }
|
@@ -7,6 +7,8 @@ class Wco::PricesController < Wco::ApplicationController
|
|
7
7
|
|
8
8
|
@price.interval = nil if !params[:price][:interval].present?
|
9
9
|
@product = params[:price][:product_type].constantize.find @price.product_id
|
10
|
+
@price.product = @product
|
11
|
+
|
10
12
|
stripe_product = Stripe::Product.retrieve( @product.product_id )
|
11
13
|
price_hash = {
|
12
14
|
product: stripe_product.id,
|
@@ -17,11 +19,9 @@ class Wco::PricesController < Wco::ApplicationController
|
|
17
19
|
price_hash[:recurring] = { interval: @price.interval }
|
18
20
|
end
|
19
21
|
stripe_price = Stripe::Price.create( price_hash )
|
20
|
-
# flash_notice 'Created stripe price.'
|
21
22
|
flash_notice stripe_price
|
22
|
-
|
23
|
-
@price.product = @product
|
24
23
|
@price.price_id = stripe_price[:id]
|
24
|
+
|
25
25
|
if @price.save
|
26
26
|
flash_notice @price
|
27
27
|
else
|
@@ -47,6 +47,13 @@ class Wco::PricesController < Wco::ApplicationController
|
|
47
47
|
redirect_to request.referrer || root_path
|
48
48
|
end
|
49
49
|
|
50
|
+
def new
|
51
|
+
@price = Wco::Price.new
|
52
|
+
authorize! :new, @price
|
53
|
+
|
54
|
+
@products_list = Wco::Product.list + WcoHosting::ApplianceTmpl.list
|
55
|
+
end
|
56
|
+
|
50
57
|
## delete and the create, instead
|
51
58
|
# def update
|
52
59
|
# end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
|
2
|
+
From: https://docs.digitalocean.com/reference/api/digitalocean/#tag/Domain-Records/operation/domains_list_records
|
3
|
+
|
4
|
+
new:
|
5
|
+
|
6
|
+
POST /v2/domains/$DOMAIN_NAME/records
|
7
|
+
|
8
|
+
{
|
9
|
+
type: 'A',
|
10
|
+
name: 'subdomain',
|
11
|
+
data: '127.0.0.1',
|
12
|
+
ttl: 3600,
|
13
|
+
}
|
14
|
+
|
15
|
+
DELETE /v2/domains/$DOMAIN_NAME/records/$DOMAIN_RECORD_ID
|
data/app/models/wco/leadset.rb
CHANGED
@@ -34,13 +34,13 @@ class Wco::Leadset
|
|
34
34
|
validates :email, uniqueness: { allow_nil: true } # presence: true
|
35
35
|
|
36
36
|
|
37
|
-
has_many :appliances,
|
38
|
-
has_many :
|
37
|
+
has_many :appliances, class_name: '::WcoHosting::Appliance', inverse_of: :leadset
|
38
|
+
has_many :appliance_tmpls, class_name: 'Wco::Price', inverse_of: :leadset
|
39
39
|
|
40
40
|
has_many :environments, class_name: '::WcoHosting::Environment', inverse_of: :leadset
|
41
41
|
has_many :invoices, class_name: 'Wco::Invoice'
|
42
42
|
has_many :leads, class_name: 'Wco::Lead'
|
43
|
-
has_many :subdomains, class_name: 'WcoHosting::Subdomain'
|
43
|
+
# has_many :subdomains, class_name: 'WcoHosting::Subdomain'
|
44
44
|
|
45
45
|
has_many :profiles, class_name: 'Wco::Profile', inverse_of: :leadset
|
46
46
|
has_many :subscriptions, class_name: 'Wco::Subscription', inverse_of: :leadset
|
@@ -0,0 +1,15 @@
|
|
1
|
+
|
2
|
+
class Wco::LeadsetApplianceTmpl
|
3
|
+
include Mongoid::Document
|
4
|
+
include Mongoid::Timestamps
|
5
|
+
include Mongoid::Paranoia
|
6
|
+
store_in collection: 'wco_leadset_appliance_tmpls'
|
7
|
+
|
8
|
+
belongs_to :leadset, class_name: 'Wco::Leadset'
|
9
|
+
belongs_to :appliance_tmpl, class_name: 'WcoHosting::ApplianceTmpl'
|
10
|
+
has_one :price, class_name: 'Wco::Price'
|
11
|
+
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
|
data/app/models/wco/log.rb
CHANGED
@@ -13,10 +13,15 @@ class Wco::Log
|
|
13
13
|
|
14
14
|
has_and_belongs_to_many :tags
|
15
15
|
|
16
|
+
def self.puts message, obj: nil
|
17
|
+
create( message: message.to_s, obj: obj )
|
18
|
+
p message
|
19
|
+
end
|
20
|
+
|
16
21
|
def self.puts! message, label, obj: nil
|
17
|
-
create( message: message, label: label, obj: obj )
|
18
|
-
|
19
|
-
|
22
|
+
create( message: message.to_s, label: label.to_s, obj: obj )
|
23
|
+
p "+++ +++ #{label}:"
|
24
|
+
p message.inspect
|
20
25
|
end
|
21
26
|
|
22
27
|
def to_s
|
data/app/models/wco/price.rb
CHANGED
@@ -8,7 +8,7 @@ class Wco::Price
|
|
8
8
|
## Wco::Product, WcoHosting::ApplianceTmpl
|
9
9
|
belongs_to :product, polymorphic: true
|
10
10
|
|
11
|
-
belongs_to :
|
11
|
+
belongs_to :leadset, class_name: 'Wco::Leadset'
|
12
12
|
|
13
13
|
has_many :subscriptions, class_name: 'Wco::Subscription', inverse_of: :price, foreign_key: :wco_price_id
|
14
14
|
|
data/app/models/wco/profile.rb
CHANGED
@@ -11,17 +11,18 @@ class Wco::Profile
|
|
11
11
|
|
12
12
|
|
13
13
|
field :per_page, type: :integer, default: 25
|
14
|
+
field :show_n_thumbs, type: :integer, default: 8
|
15
|
+
|
14
16
|
|
15
17
|
field :schwab_access_token, type: :string
|
16
18
|
field :schwab_refresh_token, type: :string
|
17
19
|
field :schwab_id_token, type: :string
|
18
20
|
|
19
|
-
field :show_n_thumbs, type: :integer, default: 8
|
20
21
|
|
21
22
|
has_many :reports, class_name: 'Wco::Report'
|
22
23
|
has_many :stocks, class_name: 'Iro::Stock'
|
23
24
|
|
24
|
-
belongs_to :leadset,
|
25
|
+
belongs_to :leadset, class_name: 'Wco::Leadset', inverse_of: :profile
|
25
26
|
has_many :newsitems, class_name: 'Wco::Newsitem'
|
26
27
|
has_and_belongs_to_many :shared_galleries, class_name: 'Wco::Gallery', inverse_of: :shared_profiles
|
27
28
|
|
@@ -24,6 +24,7 @@ class WcoEmail::MessageStub
|
|
24
24
|
STATUSES = [ STATUS_PENDING, STATUS_PROCESSED, STATUS_FAILED ]
|
25
25
|
field :status, default: STATUS_PENDING
|
26
26
|
scope :pending, ->{ where( status: STATUS_PENDING ) }
|
27
|
+
scope :failed, ->{ where( status: STATUS_FAILED ) }
|
27
28
|
|
28
29
|
field :bucket # 'ish-ses' (current), 'ish-ses-2024'
|
29
30
|
|
@@ -6,23 +6,23 @@ class WcoHosting::Appliance
|
|
6
6
|
include Wco::Utils
|
7
7
|
store_in collection: 'wco_appliances'
|
8
8
|
|
9
|
-
|
10
|
-
|
9
|
+
# field :slug, type: String
|
10
|
+
def slug
|
11
|
+
"#{subdomain}_#{domain.name.gsub('.', '_')}"
|
12
|
+
end
|
13
|
+
|
14
|
+
has_many :logs, class_name: 'Wco::Log', inverse_of: :obj
|
15
|
+
has_many :files, class_name: 'WcoHosting::File'
|
11
16
|
|
12
17
|
field :rc_json, type: Object, default: '{}'
|
13
18
|
def rc
|
14
19
|
OpenStruct.new JSON.parse rc_json
|
15
20
|
end
|
16
21
|
|
17
|
-
|
18
|
-
belongs_to :subscription, class_name: 'Wco::Subscription' # , inverse_of: :appliance
|
19
|
-
|
20
|
-
# field :service_name
|
21
|
-
# before_validation :set_service_name, on: :create, unless: ->{ service_name }
|
22
|
-
# def set_service_name
|
23
|
-
# self[:service_name] = host.gsub(".", "_")
|
24
|
-
# end
|
22
|
+
field :port
|
25
23
|
|
24
|
+
belongs_to :leadset, class_name: 'Wco::Leadset', inverse_of: :appliances
|
25
|
+
belongs_to :subscription, class_name: 'Wco::Subscription', optional: true # , inverse_of: :appliance
|
26
26
|
|
27
27
|
belongs_to :environment, class_name: 'WcoHosting::Environment', inverse_of: :appliances, optional: true
|
28
28
|
def environment_name
|
@@ -45,13 +45,15 @@ class WcoHosting::Appliance
|
|
45
45
|
|
46
46
|
belongs_to :serverhost, class_name: 'WcoHosting::Serverhost', optional: true
|
47
47
|
|
48
|
-
field :port
|
49
48
|
|
50
49
|
STATE_PENDING = 'pending'
|
51
50
|
STATE_LIVE = 'live'
|
52
51
|
STATE_TERMINATED = 'terminated'
|
53
52
|
field :state, default: STATE_PENDING
|
54
53
|
|
54
|
+
field :stdout, default: ''
|
55
|
+
field :stderr, default: ''
|
56
|
+
|
55
57
|
def to_s
|
56
58
|
appliance_tmpl # kind
|
57
59
|
end
|
@@ -76,8 +76,9 @@ class WcoHosting::ApplianceTmpl
|
|
76
76
|
end
|
77
77
|
|
78
78
|
has_many :appliances, class_name: 'WcoHosting::Appliance'
|
79
|
+
has_many :leadsets, class_name: 'Wco::LeadsetApplianceTmpl', inverse_of: :appliance_tmpl
|
79
80
|
has_many :subscriptions, as: :product, class_name: 'Wco::Subscription'
|
80
|
-
has_many :prices,
|
81
|
+
has_many :prices, as: :product, class_name: 'Wco::Price'
|
81
82
|
has_and_belongs_to_many :task_tmpls, class_name: 'WcoHosting::TaskTmpl'
|
82
83
|
|
83
84
|
field :product_id # stripe
|
@@ -8,7 +8,7 @@ class WcoHosting::Domain
|
|
8
8
|
field :name
|
9
9
|
validates :name, presence: true, uniqueness: true
|
10
10
|
|
11
|
-
has_many :
|
11
|
+
has_many :appliances, class_name: 'WcoHosting::Appliance'
|
12
12
|
|
13
13
|
STATUS_ACTIVE = 'active'
|
14
14
|
STATUS_INACTIVE = 'inactive'
|
@@ -27,34 +27,31 @@ class WcoHosting::Serverhost
|
|
27
27
|
# field :ssh_username
|
28
28
|
# field :ssh_key
|
29
29
|
|
30
|
+
field :do_id, type: :string
|
31
|
+
|
30
32
|
has_many :appliances, class_name: 'WcoHosting::Appliance'
|
31
33
|
has_many :files, class_name: 'WcoHosting::File'
|
32
34
|
|
33
|
-
def
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
add_nginx_site( app )
|
40
|
-
# load_database( app )
|
35
|
+
def self.do_list_keys
|
36
|
+
out = HTTParty.get( "https://api.digitalocean.com/v2/account/keys",
|
37
|
+
headers: { 'Authorization' => "Bearer #{DO_READER_TOKEN}" },
|
38
|
+
:debug_output => $stdout,
|
39
|
+
);
|
40
|
+
end
|
41
41
|
|
42
|
-
|
42
|
+
def self.list
|
43
|
+
[[nil,nil]] + all.map { |s| [s.name, s.id] }
|
44
|
+
# all.map { |s| [s.name, s.id] }
|
43
45
|
end
|
44
46
|
|
45
|
-
def
|
47
|
+
def add_docker_service app
|
46
48
|
@obj = app
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
data: app.serverhost.public_ip,
|
54
|
-
)
|
55
|
-
client.domain_records.create(record, for_domain: app.domain )
|
56
|
-
|
57
|
-
Wco::Log.puts! record, 'created subdomain?', obj: @obj
|
49
|
+
cmd =<<~AOL
|
50
|
+
cd /Users/piousbox/projects/ansible
|
51
|
+
. zenv/bin/activate
|
52
|
+
ansible-playbook -i inventory/do.yml --limit #{self.name} playbooks/hosted-packagedapp.yml --extra-vars '{"appliance_slug": "#{app.slug}", "codebase_zip": "#{app.tmpl.volume_zip_url}", "next_port": "#{self.next_port}"}'
|
53
|
+
AOL
|
54
|
+
do_exec cmd
|
58
55
|
end
|
59
56
|
|
60
57
|
def add_nginx_site app
|
@@ -79,87 +76,69 @@ class WcoHosting::Serverhost
|
|
79
76
|
do_exec cmd
|
80
77
|
end
|
81
78
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
#
|
90
|
-
rendered_str = ac.render_to_string("wco_hosting/docker-compose/dc-any")
|
91
|
-
Wco::Log.puts! rendered_str, 'add_docker_service rendered_str', obj: @obj
|
92
|
-
|
93
|
-
file = Tempfile.new('prefix')
|
94
|
-
file.write rendered_str
|
95
|
-
file.close
|
96
|
-
# puts! file.path, 'file.path'
|
97
|
-
|
98
|
-
cmd = "scp #{file.path} #{ssh_host}:#{WORKDIR}/dc-#{app.service_name}.yml "
|
99
|
-
do_exec cmd
|
100
|
-
|
101
|
-
cmd = "ssh #{ssh_host} 'cd #{WORKDIR} ; \
|
102
|
-
docker compose -f dc-#{app.service_name}.yml up -d #{app.service_name} ; \
|
103
|
-
echo ok #add_docker_service ' "
|
104
|
-
do_exec cmd
|
79
|
+
=begin
|
80
|
+
def create_appliance app
|
81
|
+
# puts! app, 'Serverhost#create_appliance'
|
82
|
+
create_subdomain( app )
|
83
|
+
create_volume( app )
|
84
|
+
add_docker_service( app )
|
85
|
+
add_nginx_site( app )
|
86
|
+
# load_database( app )
|
105
87
|
end
|
88
|
+
=end
|
106
89
|
|
107
|
-
def
|
90
|
+
def create_subdomain app
|
108
91
|
@obj = app
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
# puts! file.path, 'file.path'
|
120
|
-
|
121
|
-
cmd = "scp #{file.path} #{ssh_host}:#{WORKDIR}/scripts/create_volume"
|
122
|
-
do_exec cmd
|
123
|
-
|
124
|
-
cmd = "ssh #{ssh_host} 'chmod a+x #{WORKDIR}/scripts/create_volume ; \
|
125
|
-
#{WORKDIR}/wco_hosting/scripts/create_volume ' "
|
126
|
-
do_exec cmd
|
92
|
+
Wco::Log.puts! @obj, 'Creating subdomain...', obj: @obj
|
93
|
+
client = DropletKit::Client.new(access_token: DO_TOKEN_1)
|
94
|
+
record = DropletKit::DomainRecord.new(
|
95
|
+
type: 'A',
|
96
|
+
name: app.subdomain,
|
97
|
+
data: app.serverhost.public_ip,
|
98
|
+
)
|
99
|
+
client.domain_records.create(record, for_domain: app.domain )
|
100
|
+
Wco::Log.puts! record, 'Created subdomain.', obj: @obj
|
101
|
+
# WcoHosting::Subdomain.create!( domain: app.domain, name: app.subdomain )
|
127
102
|
end
|
128
103
|
|
129
|
-
def
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
104
|
+
def do_create_server!
|
105
|
+
out = HTTParty.post( "https://api.digitalocean.com/v2/droplets", body: {
|
106
|
+
name: name,
|
107
|
+
size: "s-1vcpu-2gb",
|
108
|
+
region: "sfo2",
|
109
|
+
image: "ubuntu-22-04-x64",
|
110
|
+
ssh_keys: [ 40460634 ], # 2np, "71:9a:7e:9a:54:55:af:d0:16:47:5c:57:a8:c3:f0:2b"
|
111
|
+
vpc_uuid: "b9f748b6-4649-4506-a457-b70d2b57b313",
|
112
|
+
}.to_json,
|
113
|
+
headers: { 'Content-Type' => 'application/json',
|
114
|
+
'Authorization' => "Bearer #{DO_DROPLET_TOKEN}" },
|
115
|
+
:debug_output => $stdout,
|
116
|
+
);
|
117
|
+
puts! out, '#create_do_server()'
|
118
|
+
out = out.parsed_response
|
119
|
+
self.do_id = out['droplet']['id']
|
120
|
+
self.save
|
121
|
+
|
122
|
+
do_project_id = '4dad5c55-1a11-4c2b-9e14-1cd69513d940' # WcoHosting DO project id
|
123
|
+
out = HTTParty.post( "https://api.digitalocean.com/v2/projects/#{do_project_id}/resources", body: {
|
124
|
+
resources: [ "do:droplet:#{out['droplet']['id']}" ],
|
125
|
+
}.to_json,
|
126
|
+
headers: { 'Content-Type' => 'application/json',
|
127
|
+
'Authorization' => "Bearer #{DO_DROPLET_TOKEN}" },
|
128
|
+
:debug_output => $stdout,
|
129
|
+
);
|
130
|
+
puts! out, 'assign droplet to a project'
|
149
131
|
end
|
150
132
|
|
151
133
|
def do_exec cmd
|
152
134
|
Wco::Log.puts! cmd, '#do_exec', obj: @obj
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
Wco::Log.puts! stdout, 'stdout', obj: @obj
|
157
|
-
Wco::Log.puts! stderr, 'stderr', obj: @obj
|
158
|
-
Wco::Log.puts! status, 'status', obj: @obj
|
135
|
+
IO.popen(cmd).each do |line|
|
136
|
+
Wco::Log.puts line, obj: @obj
|
137
|
+
end
|
159
138
|
end
|
160
139
|
|
161
|
-
def
|
162
|
-
|
163
|
-
# all.map { |s| [s.name, s.id] }
|
140
|
+
def to_s
|
141
|
+
"<Serverhost name=#{name} next_port=#{next_port} ssh_host=#{ssh_host} />"
|
164
142
|
end
|
143
|
+
|
165
144
|
end
|
@@ -3,32 +3,52 @@
|
|
3
3
|
|
4
4
|
= form_for leadset, :as => :leadset, :url => url do |f|
|
5
5
|
|
6
|
-
.
|
6
|
+
.field
|
7
7
|
= f.label :company_url
|
8
8
|
= f.text_field :company_url
|
9
9
|
|
10
|
-
.
|
10
|
+
.field
|
11
11
|
= f.label :email
|
12
12
|
= f.text_field :email
|
13
13
|
.field
|
14
14
|
%label mangle_subject
|
15
15
|
= f.check_box :mangle_subject
|
16
16
|
|
17
|
-
.
|
17
|
+
.field
|
18
18
|
= f.label :next_invoice_number
|
19
19
|
= f.text_field :next_invoice_number
|
20
20
|
|
21
|
+
.field
|
22
|
+
%label tags
|
23
|
+
.d-flex.flex-wrap
|
24
|
+
- @tags.each do |tag|
|
25
|
+
.descr
|
26
|
+
= check_box_tag 'leadset[tag_ids][]', tag.id, leadset.tags.include?(tag)
|
27
|
+
%label= tag
|
28
|
+
|
29
|
+
.header
|
30
|
+
%h5.title Hosting
|
31
|
+
|
21
32
|
.field
|
22
33
|
%label serverhosts
|
23
|
-
|
34
|
+
.d-flex.flex-wrap
|
35
|
+
- @serverhosts.each do |opt|
|
36
|
+
.descr
|
37
|
+
= check_box_tag 'leadset[serverhost_ids][]', opt.id, leadset.serverhost_ids.include?(opt.id)
|
38
|
+
%label= opt.name
|
24
39
|
|
25
|
-
|
26
|
-
|
27
|
-
|
40
|
+
.field
|
41
|
+
%label Stripe customer_id
|
42
|
+
= f.text_field :customer_id
|
28
43
|
|
29
44
|
.field
|
30
|
-
%label
|
31
|
-
|
45
|
+
%label appliance tmpl prices
|
46
|
+
.d-flex.flex-wrap
|
47
|
+
- @appliance_tmpl_prices_list.each do |price|
|
48
|
+
.descr
|
49
|
+
= check_box_tag 'leadset[appliance_tmpl_ids][]', price.id, leadset.appliance_tmpls.include?(price)
|
50
|
+
%label= price.product.name
|
51
|
+
|
32
52
|
|
33
53
|
.actions
|
34
54
|
= f.submit
|
@@ -5,86 +5,90 @@
|
|
5
5
|
%h2.title
|
6
6
|
Leadset `#{@leadset.company_url}`
|
7
7
|
= link_to '[~]', edit_leadset_path( @leadset )
|
8
|
+
.row
|
9
|
+
.col-6.border-right
|
10
|
+
%ul
|
11
|
+
%li <b>Email:</b> #{@leadset.email}
|
12
|
+
%li <b>company_url</b>: #{@leadset.company_url}
|
13
|
+
%li <b>customer_id</b>: #{@leadset.customer_id}
|
14
|
+
-# tags
|
15
|
+
.col-6
|
16
|
+
Tags:
|
17
|
+
= render '/wco/tags/index_chips', tags: @leadset.tags
|
8
18
|
|
9
|
-
%ul
|
10
|
-
%li <b>Email:</b> #{@leadset.email}
|
11
|
-
%li <b>company_url</b>: #{@leadset.company_url}
|
12
|
-
%li <b>customer_id</b>: #{@leadset.customer_id}
|
13
19
|
%hr
|
20
|
+
.row
|
21
|
+
-# serverhosts
|
22
|
+
.col-6.border-right
|
23
|
+
= render 'wco_hosting/serverhosts/list', serverhosts: @leadset.serverhosts
|
24
|
+
.col-6
|
25
|
+
|
14
26
|
|
15
|
-
|
16
|
-
.
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
%
|
21
|
-
|
22
|
-
%td Amount Cents
|
23
|
-
%td Interval
|
24
|
-
- @appliance_tmpls.each do |tmpl|
|
25
|
-
%tr
|
26
|
-
- price = @leadset.appliance_tmpl_prices.where( product: tmpl ).first
|
27
|
-
- price ||= Wco::Price.new({ product: tmpl, appliance_tmpl_leadset: @leadset })
|
28
|
-
- url = price.new_record? ? wco.prices_path : wco.price_path(price)
|
29
|
-
- if !price.new_record?
|
30
|
-
%td
|
31
|
-
= button_to 'x', wco.price_path(price), method: :delete, data: { confirm: 'Are you sure?' }
|
32
|
-
- else
|
33
|
-
%td
|
34
|
-
= form_for price, url: url do |f|
|
35
|
-
= hidden_field_tag 'price[product_id]', price.product_id
|
36
|
-
= hidden_field_tag 'price[product_type]', price.product_type
|
37
|
-
= hidden_field_tag 'price[appliance_tmpl_leadset_id]', @leadset.id
|
38
|
-
%td
|
39
|
-
%b= tmpl
|
40
|
-
%td
|
41
|
-
= f.number_field :amount_cents
|
42
|
-
%td
|
43
|
-
= f.select :interval, options_for_select( Wco::Price::INTERVALS, selected: price.interval ), class: 'select2'
|
44
|
-
= f.submit '>'
|
45
|
-
|
46
|
-
%br
|
47
|
-
.gray= price.price_id || 'nil'
|
27
|
+
%hr
|
28
|
+
.row
|
29
|
+
-# appliance templates (prices)
|
30
|
+
.col-md-6.border-right
|
31
|
+
.header
|
32
|
+
%h5.title Appliance Tmpls (prices) (#{@leadset.appliance_tmpls.length})
|
33
|
+
= render 'wco/prices/form_table'
|
48
34
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
35
|
+
-# environments
|
36
|
+
.col-md-6
|
37
|
+
- if defined?( wco_hosting )
|
38
|
+
.header
|
39
|
+
%h5.title Environments (#{@leadset.environments.length}) #{link_to '[+]', wco_hosting.new_environment_path({ leadset_id: @leadset.id }) }
|
40
|
+
%ul
|
41
|
+
- @leadset.environments.each do |env|
|
42
|
+
%li= env
|
43
|
+
%hr
|
44
|
+
.row
|
45
|
+
-# appliances
|
46
|
+
.col-md-6.border-right
|
47
|
+
.header
|
48
|
+
%h5.title Appliances (#{@leadset.appliances.length})
|
63
49
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
50
|
+
-# subscriptions
|
51
|
+
.col-md-6
|
52
|
+
.header
|
53
|
+
%h5.title.collapse-expand#subscriptionsList
|
54
|
+
Subscriptions (#{@subscriptions.length})
|
55
|
+
= link_to '[+wco]', new_subscription_path({ customer_id: @leadset.customer_id })
|
56
|
+
%table.bordered
|
57
|
+
%thead
|
58
|
+
%tr
|
59
|
+
%th Name
|
60
|
+
%th Price
|
61
|
+
- @subscriptions.each do |i|
|
62
|
+
%tr
|
63
|
+
%td= i.product.name
|
64
|
+
%td= i.price
|
70
65
|
|
71
|
-
|
66
|
+
%hr
|
67
|
+
.row
|
68
|
+
-# invoices
|
69
|
+
.col-md-12
|
70
|
+
.header
|
71
|
+
%h5.title.collapse-expand#invoicesList
|
72
|
+
Invoices (#{@leadset.invoices.length})
|
73
|
+
= link_to '[+stripe]', new_invoice_stripe_path({ leadset_id: @leadset.id })
|
74
|
+
= link_to '[+pdf]', new_invoice_pdf_path({ leadset_id: @leadset.id })
|
72
75
|
|
73
|
-
|
76
|
+
= render '/wco/invoices/index_list', invoices: @invoices
|
74
77
|
|
75
|
-
|
76
|
-
%label Create invoice for month
|
77
|
-
= text_field_tag 'month_on', nil, placeholder: 'YYYY-MM-DD'
|
78
|
-
%label (replace ?)
|
79
|
-
= check_box_tag 'replace'
|
80
|
-
= submit_tag 'Go >', data: { confirm: 'Are you sure?' }
|
81
|
-
%hr
|
78
|
+
%p Next invoice number: #{@leadset.next_invoice_number}
|
82
79
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
80
|
+
= form_tag create_monthly_invoice_for_leadset_path({ leadset_id: @leadset.id }) do
|
81
|
+
%label Create invoice for month
|
82
|
+
= text_field_tag 'month_on', nil, placeholder: 'YYYY-MM-DD'
|
83
|
+
%label (replace ?)
|
84
|
+
= check_box_tag 'replace'
|
85
|
+
= submit_tag 'Go >', data: { confirm: 'Are you sure?' }
|
86
|
+
|
87
|
+
%hr
|
88
|
+
.row
|
89
|
+
-# leads
|
90
|
+
.col-12
|
91
|
+
.header
|
92
|
+
%h5.title.collapse-expand#leads Leads
|
93
|
+
= render '/wco/leads/index', leads: @leads
|
90
94
|
|
@@ -0,0 +1,18 @@
|
|
1
|
+
|
2
|
+
-# - url = price.new_record? ? prices_path : price_path( price )
|
3
|
+
.prices--form
|
4
|
+
|
5
|
+
= form_for price, as: :price, html: { class: 'flex-row' } do |f|
|
6
|
+
= hidden_field_tag 'price[product_id]', price.product_id
|
7
|
+
= hidden_field_tag 'price[product_type]', price.product_type
|
8
|
+
|
9
|
+
.field
|
10
|
+
%label amount cents
|
11
|
+
= f.number_field :amount_cents
|
12
|
+
|
13
|
+
.field
|
14
|
+
%label interval
|
15
|
+
= f.select :interval, options_for_select( Wco::Price::INTERVALS, selected: price.interval ), class: 'select2'
|
16
|
+
|
17
|
+
.actions
|
18
|
+
= f.submit '>'
|
@@ -0,0 +1,50 @@
|
|
1
|
+
|
2
|
+
.prices--form-table
|
3
|
+
|
4
|
+
-# %label New price (app tmpl leadset):
|
5
|
+
|
6
|
+
%table.bordered
|
7
|
+
%thead
|
8
|
+
%tr
|
9
|
+
%th
|
10
|
+
%th tmpl
|
11
|
+
%th price
|
12
|
+
%th interval
|
13
|
+
%th
|
14
|
+
%tbody
|
15
|
+
- @appliance_tmpls_list.each do |tmpl|
|
16
|
+
- price = @leadset.appliance_tmpls.where( product: tmpl ).first
|
17
|
+
- price ||= Wco::Price.new({ product: tmpl, leadset: @leadset })
|
18
|
+
- url = price.new_record? ? wco.prices_path : wco.price_path(price)
|
19
|
+
- if !price.new_record?
|
20
|
+
%tr
|
21
|
+
%td
|
22
|
+
%td
|
23
|
+
%b= tmpl
|
24
|
+
%td
|
25
|
+
= price.amount_cents
|
26
|
+
cents
|
27
|
+
%td
|
28
|
+
= price.interval
|
29
|
+
%td
|
30
|
+
= button_to 'x', wco.price_path(price), method: :delete, data: { confirm: 'Are you sure?' }
|
31
|
+
- else
|
32
|
+
= form_for price, url: url do |f|
|
33
|
+
%tr
|
34
|
+
%td
|
35
|
+
.d-flex.flex-column.hide
|
36
|
+
product_id
|
37
|
+
= text_field_tag 'price[product_id]', price.product_id
|
38
|
+
product_type
|
39
|
+
= text_field_tag 'price[product_type]', price.product_type
|
40
|
+
leadset_id
|
41
|
+
= text_field_tag 'price[leadset_id]', @leadset.id
|
42
|
+
%td
|
43
|
+
%b= tmpl
|
44
|
+
%td
|
45
|
+
= f.number_field :amount_cents
|
46
|
+
%td
|
47
|
+
= f.select :interval, options_for_select( Wco::Price::INTERVALS, selected: price.interval ), class: 'select2'
|
48
|
+
%td
|
49
|
+
= f.submit '>'
|
50
|
+
|
@@ -0,0 +1,22 @@
|
|
1
|
+
|
2
|
+
.maxwidth
|
3
|
+
.header
|
4
|
+
%h5.title New Price
|
5
|
+
|
6
|
+
- price = @price
|
7
|
+
= form_for price, as: :price do |f|
|
8
|
+
.field
|
9
|
+
%label Product
|
10
|
+
= f.select :product_id, options_for_select(@products_list, selected: price.product_id)
|
11
|
+
|
12
|
+
.field
|
13
|
+
%label amount cents
|
14
|
+
= f.number_field :amount_cents
|
15
|
+
|
16
|
+
.field
|
17
|
+
%label interval
|
18
|
+
= f.select :interval, options_for_select( Wco::Price::INTERVALS, selected: price.interval ), class: 'select2'
|
19
|
+
|
20
|
+
.actions
|
21
|
+
= f.submit 'Create'
|
22
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
|
2
|
+
.serverhosts--list
|
3
|
+
- if !defined?( wco_hosting )
|
4
|
+
.header
|
5
|
+
%h5.title wco_hosting is not included
|
6
|
+
- else
|
7
|
+
.header
|
8
|
+
%h5.title
|
9
|
+
Serverhosts for `#{@leadset}`
|
10
|
+
= link_to '[+]', wco_hosting.new_serverhost_path({ leadset_id: @leadset.id })
|
11
|
+
%ul
|
12
|
+
- serverhosts.each do |s|
|
13
|
+
%li
|
14
|
+
= link_to '[~]', wco_hosting.edit_serverhost_path(s)
|
15
|
+
= s
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wco_models
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.1.0.
|
4
|
+
version: 3.1.0.203
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Victor Pudeyev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-
|
11
|
+
date: 2025-04-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ahoy_matey
|
@@ -459,6 +459,7 @@ files:
|
|
459
459
|
- app/models/ability.rb
|
460
460
|
- app/models/ahoy/event.rb
|
461
461
|
- app/models/ahoy/visit.rb
|
462
|
+
- app/models/do/dns_record.rb-txt
|
462
463
|
- app/models/iro/alert.rb
|
463
464
|
- app/models/iro/datapoint.rb
|
464
465
|
- app/models/iro/date.rb
|
@@ -475,6 +476,7 @@ files:
|
|
475
476
|
- app/models/wco/invoice.rb
|
476
477
|
- app/models/wco/lead.rb
|
477
478
|
- app/models/wco/leadset.rb
|
479
|
+
- app/models/wco/leadset_appliance_tmpl.rb
|
478
480
|
- app/models/wco/log.rb
|
479
481
|
- app/models/wco/newsitem.rb
|
480
482
|
- app/models/wco/obfuscated_redirect.rb
|
@@ -516,7 +518,7 @@ files:
|
|
516
518
|
- app/models/wco_hosting/file.rb
|
517
519
|
- app/models/wco_hosting/runner.rb
|
518
520
|
- app/models/wco_hosting/serverhost.rb
|
519
|
-
- app/models/wco_hosting/subdomain.rb
|
521
|
+
- app/models/wco_hosting/subdomain.rb-bk
|
520
522
|
- app/models/wco_hosting/task.rb
|
521
523
|
- app/models/wco_hosting/task_tmpl.rb
|
522
524
|
- app/views/layouts/wco/application.haml
|
@@ -618,6 +620,9 @@ files:
|
|
618
620
|
- app/views/wco/photos/show.haml
|
619
621
|
- app/views/wco/photos/without_gallery.haml
|
620
622
|
- app/views/wco/prices/_form.haml
|
623
|
+
- app/views/wco/prices/_form_mini.haml
|
624
|
+
- app/views/wco/prices/_form_table.haml
|
625
|
+
- app/views/wco/prices/new.haml
|
621
626
|
- app/views/wco/products/_form.haml
|
622
627
|
- app/views/wco/products/_header.haml
|
623
628
|
- app/views/wco/products/_index.haml
|
@@ -714,6 +719,7 @@ files:
|
|
714
719
|
- app/views/wco_hosting/ecs_task_definitions/hw1.json
|
715
720
|
- app/views/wco_hosting/scripts/create_volume.erb
|
716
721
|
- app/views/wco_hosting/scripts/nginx_site.conf.erb
|
722
|
+
- app/views/wco_hosting/serverhosts/_list.haml
|
717
723
|
- config/initializers/00_s3.rb
|
718
724
|
- config/initializers/00_s3.rb-example
|
719
725
|
- config/initializers/08_integrations.rb
|