rails-gke 0.6.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +13 -0
- data/.rspec +3 -0
- data/.rubocop.yml +191 -0
- data/.ruby-version +1 -0
- data/.travis.yml +6 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +7 -0
- data/Gemfile.lock +34 -0
- data/LICENSE.txt +67 -0
- data/README.md +256 -0
- data/Rakefile +15 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/config/initializers/rails-gke.rb +9 -0
- data/deployment.yml +46 -0
- data/exe/create_yml +4 -0
- data/exe/rails_gke_init +60 -0
- data/exe/rails_gke_init_task +18 -0
- data/ingress.yml +17 -0
- data/lib/rails/gke.rb +284 -0
- data/lib/rails/gke/initialize.rb +8 -0
- data/lib/rails/gke/initialize/initialize.rb +604 -0
- data/lib/rails/gke/version.rb +5 -0
- data/rails-gke.gemspec +29 -0
- data/rails-gke.rb +11 -0
- data/secret.yml +10 -0
- data/service.yml +14 -0
- data/yank_all.rb +25 -0
- metadata +77 -0
data/Rakefile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require "rspec/core/rake_task"
|
3
|
+
require "yaml"
|
4
|
+
require "erb"
|
5
|
+
require "logger"
|
6
|
+
require "rails/gke"
|
7
|
+
|
8
|
+
desc "Generate gke.rake file in lib/tasks directory"
|
9
|
+
task :gen_task do
|
10
|
+
puts Rails::Gke::Initialize.create_task
|
11
|
+
end
|
12
|
+
|
13
|
+
RSpec::Core::RakeTask.new(:spec)
|
14
|
+
|
15
|
+
task :default => :spec
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "rails/gke"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
Rails::Gke.configure do |config|
|
2
|
+
config.project_id = "elsoul2"
|
3
|
+
config.app = "grpc-td-cluster"
|
4
|
+
config.network = "default"
|
5
|
+
config.machine_type = "custom-1-6656"
|
6
|
+
config.zone = "us-central1-a"
|
7
|
+
config.domain = "el-soul.com"
|
8
|
+
config.google_application_credentials = "./config/credentials.json"
|
9
|
+
end
|
data/deployment.yml
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
## This is example deployment.yml generated by command
|
2
|
+
apiVersion: extensions/v1beta1
|
3
|
+
kind: Deployment
|
4
|
+
metadata:
|
5
|
+
name: rails-gke-deployment
|
6
|
+
spec:
|
7
|
+
replicas: 3
|
8
|
+
template:
|
9
|
+
metadata:
|
10
|
+
labels:
|
11
|
+
app: rails-gke
|
12
|
+
spec:
|
13
|
+
containers:
|
14
|
+
- name: rails-gke
|
15
|
+
image: asia.gcr.io/el-soul/rails-gke:0.0.1 #You need to update this version. e.g 0.0.2
|
16
|
+
ports:
|
17
|
+
- containerPort: 3000
|
18
|
+
protocol: TCP
|
19
|
+
livenessProbe:
|
20
|
+
httpGet:
|
21
|
+
path: /
|
22
|
+
port: 3000
|
23
|
+
initialDelaySeconds: 30
|
24
|
+
timeoutSeconds: 1
|
25
|
+
readinessProbe:
|
26
|
+
httpGet:
|
27
|
+
path: /
|
28
|
+
port: 3000
|
29
|
+
initialDelaySeconds: 30
|
30
|
+
timeoutSeconds: 1
|
31
|
+
env: # Set env file from here. Do not forget to edit secret.yml when you add here.
|
32
|
+
- name: DB_HOST
|
33
|
+
valueFrom:
|
34
|
+
secretKeyRef:
|
35
|
+
name: rails-gke-secret
|
36
|
+
key: db_host
|
37
|
+
- name: DB_USER
|
38
|
+
valueFrom:
|
39
|
+
secretKeyRef:
|
40
|
+
name: rails-gke-secret
|
41
|
+
key: db_user
|
42
|
+
- name: DB_PW
|
43
|
+
valueFrom:
|
44
|
+
secretKeyRef:
|
45
|
+
name: rails-gke-secret
|
46
|
+
key: db_pw
|
data/exe/create_yml
ADDED
data/exe/rails_gke_init
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require "rails/gke"
|
3
|
+
|
4
|
+
project = {}
|
5
|
+
config_path = "./config/initializers/rails-gke.rb"
|
6
|
+
if File.exist? config_path
|
7
|
+
puts "This process will Overwrite `#{config_path}` file. OK / Enter"
|
8
|
+
confirm = gets.chomp
|
9
|
+
exit unless confirm == ""
|
10
|
+
end
|
11
|
+
|
12
|
+
begin
|
13
|
+
puts "Google Cloud PROJECT_ID: (default: elsoul2)"
|
14
|
+
project[:project_id] = gets.chomp
|
15
|
+
project[:project_id] == "" ? project[:project_id] = "elsoul2" : true
|
16
|
+
puts "Your APP name: (default: grpc-td-cluster)"
|
17
|
+
project[:app] = gets.chomp
|
18
|
+
project[:app] == "" ? project[:app] = "grpc-td-cluster" : true
|
19
|
+
puts "VPC Network Name: (default: default)"
|
20
|
+
project[:network] = gets.chomp
|
21
|
+
project[:network] == "" ? project[:network] = "default" : true
|
22
|
+
puts "Instance MachineType: (default: custom-1-6656)"
|
23
|
+
project[:machine_type] = gets.chomp
|
24
|
+
project[:machine_type] == "" ? project[:machine_type] = "custom-1-6656" : true
|
25
|
+
puts "Zone: (default: us-central1-a)"
|
26
|
+
project[:zone] = gets.chomp
|
27
|
+
project[:zone] == "" ? project[:zone] = "us-central1-a" : true
|
28
|
+
puts "Domain: (default: el-soul.com)"
|
29
|
+
project[:domain] = gets.chomp
|
30
|
+
project[:domain] == "" ? project[:domain] = "el-soul.com" : true
|
31
|
+
puts "Google Application Credentials Path: (default: ./config/credentials.json)"
|
32
|
+
project[:google_application_credentials] = gets.chomp
|
33
|
+
project[:google_application_credentials] == "" ? project[:google_application_credentials] = "./config/credentials.json" : true
|
34
|
+
|
35
|
+
puts project
|
36
|
+
puts "Enter to finish set up!"
|
37
|
+
confirm = gets.chomp
|
38
|
+
raise "Retry" unless confirm == ""
|
39
|
+
rescue
|
40
|
+
retry
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
FileUtils.mkdir_p "config/initializers" unless File.directory? "config/initializers"
|
45
|
+
path = "config/initializers/rails-gke.rb"
|
46
|
+
File.open(path, "w") do |f|
|
47
|
+
f.write <<~EOS
|
48
|
+
Rails::Gke.configure do |config|
|
49
|
+
config.project_id = "#{project[:project_id]}"
|
50
|
+
config.app = "#{project[:app]}"
|
51
|
+
config.network = "#{project[:network]}"
|
52
|
+
config.machine_type = "#{project[:machine_type]}"
|
53
|
+
config.zone = "#{project[:zone]}"
|
54
|
+
config.domain = "#{project[:domain]}"
|
55
|
+
config.google_application_credentials = "#{project[:google_application_credentials]}"
|
56
|
+
end
|
57
|
+
EOS
|
58
|
+
end
|
59
|
+
puts "You Are All Set!!"
|
60
|
+
puts "config at ./config/initializers/rails-gke.rb"
|
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require "rails/gke"
|
3
|
+
config_path = "./app/tasks/gke.rb"
|
4
|
+
if File.exist? config_path
|
5
|
+
puts "This process will Overwrite `#{config_path}` file. OK / Enter"
|
6
|
+
confirm = gets.chomp
|
7
|
+
exit unless confirm == ""
|
8
|
+
end
|
9
|
+
puts "Which Framework: \n 1. SOULS \n 2. RAILS \n Enter Number: "
|
10
|
+
fw = gets.chomp.to_i
|
11
|
+
case fw
|
12
|
+
when 1
|
13
|
+
puts "created `app/tasks/gke.rb` !"
|
14
|
+
puts Rails::Gke::Initialize.create_souls_task
|
15
|
+
else
|
16
|
+
puts "created `lib/tasks/gke.rb` !"
|
17
|
+
puts Rails::Gke::Initialize.create_rails_task
|
18
|
+
end
|
data/ingress.yml
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
## This is example ingress.yml generated by command
|
2
|
+
apiVersion: extensions/v1beta1
|
3
|
+
kind: Ingress
|
4
|
+
metadata:
|
5
|
+
name: https-rails-gke
|
6
|
+
annotations:
|
7
|
+
kubernetes.io/ingress.global-static-ip-name: https-rails-gke
|
8
|
+
networking.gke.io/managed-certificates: rails-gke-secret
|
9
|
+
spec:
|
10
|
+
rules:
|
11
|
+
- host:
|
12
|
+
http:
|
13
|
+
paths:
|
14
|
+
- backend:
|
15
|
+
serviceName: rails-gke-service
|
16
|
+
servicePort: 80
|
17
|
+
|
data/lib/rails/gke.rb
ADDED
@@ -0,0 +1,284 @@
|
|
1
|
+
require "rails/gke/version"
|
2
|
+
require "rails/gke/initialize"
|
3
|
+
|
4
|
+
module Rails
|
5
|
+
module Gke
|
6
|
+
class Error < StandardError; end
|
7
|
+
class << self
|
8
|
+
attr_accessor :configuration
|
9
|
+
|
10
|
+
def delete_forwarding_rule forwarding_rule_name: "grpc-gke-forwarding-rule"
|
11
|
+
system "gcloud compute -q forwarding-rules delete #{forwarding_rule_name} --global"
|
12
|
+
end
|
13
|
+
|
14
|
+
def create_forwarding_rule forwarding_rule_name: "grpc-gke-forwarding-rule", proxy_name: "grpc-gke-proxy", port: 8000
|
15
|
+
system "gcloud compute -q forwarding-rules create #{forwarding_rule_name} \
|
16
|
+
--global \
|
17
|
+
--load-balancing-scheme=INTERNAL_SELF_MANAGED \
|
18
|
+
--address=0.0.0.0 \
|
19
|
+
--target-grpc-proxy=#{proxy_name} \
|
20
|
+
--ports #{port} \
|
21
|
+
--network #{Rails::Gke.configuration.network}"
|
22
|
+
end
|
23
|
+
|
24
|
+
def delete_target_grpc_proxy proxy_name: "grpc-gke-proxy"
|
25
|
+
system "gcloud compute -q target-grpc-proxies delete #{proxy_name}"
|
26
|
+
end
|
27
|
+
|
28
|
+
def create_target_grpc_proxy proxy_name: "grpc-gke-proxy", url_map_name: "grpc-gke-url-map"
|
29
|
+
system "gcloud compute -q target-grpc-proxies create #{proxy_name} \
|
30
|
+
--url-map #{url_map_name} \
|
31
|
+
--validate-for-proxyless"
|
32
|
+
end
|
33
|
+
|
34
|
+
def create_path_matcher url_map_name: "grpc-gke-url-map", service_name: "grpc-gke-helloworld-service", path_matcher_name: "grpc-gke-path-matcher", hostname: "helloworld-gke", port: "8000"
|
35
|
+
system "gcloud compute -q url-maps add-path-matcher #{url_map_name} \
|
36
|
+
--default-service #{service_name} \
|
37
|
+
--path-matcher-name #{path_matcher_name} \
|
38
|
+
--new-hosts #{hostname}:#{port}"
|
39
|
+
end
|
40
|
+
|
41
|
+
def delete_url_map url_map_name: "grpc-gke-url-map"
|
42
|
+
system "gcloud compute -q url-maps delete #{url_map_name}"
|
43
|
+
end
|
44
|
+
|
45
|
+
def create_url_map url_map_name: "grpc-gke-url-map", service_name: "grpc-gke-helloworld-service"
|
46
|
+
system "gcloud compute -q url-maps create #{url_map_name} \
|
47
|
+
--default-service #{service_name}"
|
48
|
+
end
|
49
|
+
|
50
|
+
def add_backend_service service_name: "grpc-gke-helloworld-service", zone: "us-central1-a", neg_name: ""
|
51
|
+
system "gcloud compute -q backend-services add-backend #{service_name} \
|
52
|
+
--global \
|
53
|
+
--network-endpoint-group #{neg_name} \
|
54
|
+
--network-endpoint-group-zone #{zone} \
|
55
|
+
--balancing-mode RATE \
|
56
|
+
--max-rate-per-endpoint 5"
|
57
|
+
end
|
58
|
+
|
59
|
+
def delete_backend_service service_name: "grpc-gke-helloworld-service"
|
60
|
+
system "gcloud compute -q backend-services delete #{service_name} --global"
|
61
|
+
end
|
62
|
+
|
63
|
+
def create_backend_service service_name: "grpc-gke-helloworld-service", health_check_name: "grpc-gke-helloworld-hc"
|
64
|
+
system "gcloud compute -q backend-services create #{service_name} \
|
65
|
+
--global \
|
66
|
+
--load-balancing-scheme=INTERNAL_SELF_MANAGED \
|
67
|
+
--protocol=GRPC \
|
68
|
+
--health-checks #{health_check_name}"
|
69
|
+
end
|
70
|
+
|
71
|
+
def delete_firewall_rule firewall_rule_name: "grpc-gke-allow-health-checks"
|
72
|
+
system "gcloud compute -q firewall-rules delete #{firewall_rule_name}"
|
73
|
+
end
|
74
|
+
|
75
|
+
def create_firewall_rule firewall_rule_name: "grpc-gke-allow-health-checks"
|
76
|
+
system "gcloud compute -q firewall-rules create #{firewall_rule_name} \
|
77
|
+
--network #{Rails::Gke.configuration.network} \
|
78
|
+
--action allow \
|
79
|
+
--direction INGRESS \
|
80
|
+
--source-ranges 35.191.0.0/16,130.211.0.0/22 \
|
81
|
+
--target-tags allow-health-checks \
|
82
|
+
--rules tcp:50051"
|
83
|
+
end
|
84
|
+
|
85
|
+
def delete_health_check health_check_name: "grpc-gke-helloworld-hc"
|
86
|
+
system "gcloud compute -q health-checks delete #{health_check_name}"
|
87
|
+
end
|
88
|
+
|
89
|
+
def create_health_check health_check_name: "grpc-gke-helloworld-hc"
|
90
|
+
system "gcloud compute -q health-checks create grpc #{health_check_name} --use-serving-port"
|
91
|
+
end
|
92
|
+
|
93
|
+
def create_network
|
94
|
+
return "Error: Please Set Rails::Gke.configuration" if Rails::Gke.configuration.nil?
|
95
|
+
system("gcloud compute networks create #{Rails::Gke.configuration.network}")
|
96
|
+
end
|
97
|
+
|
98
|
+
def get_network_group_list
|
99
|
+
system "gcloud compute network-endpoint-groups list"
|
100
|
+
end
|
101
|
+
|
102
|
+
def create_network_group
|
103
|
+
app = Rails::Gke.configuration.app
|
104
|
+
network = Rails::Gke.configuration.network
|
105
|
+
sub_network = Rails::Gke.configuration.network
|
106
|
+
system("gcloud compute network-endpoint-groups create #{app} \
|
107
|
+
--default-port=0 \
|
108
|
+
--network #{network} \
|
109
|
+
--subnet #{sub_network} \
|
110
|
+
--global")
|
111
|
+
end
|
112
|
+
|
113
|
+
def set_network_group_list_env
|
114
|
+
app = Rails::Gke.configuration.app
|
115
|
+
system "NEG_NAME=$(gcloud compute network-endpoint-groups list | grep #{app} | awk '{print $1}')"
|
116
|
+
`echo $NEG_NAME`
|
117
|
+
end
|
118
|
+
|
119
|
+
def delete_network_group_list neg_name: ""
|
120
|
+
system "gcloud compute network-endpoint-groups delete #{neg_name} --zone #{Rails::Gke.configuration.zone} -q"
|
121
|
+
end
|
122
|
+
|
123
|
+
def delete_cluster cluster_name: "grpc-td-cluster"
|
124
|
+
system "gcloud container clusters delete #{cluster_name} --zone #{Rails::Gke.configuration.zone} -q"
|
125
|
+
end
|
126
|
+
|
127
|
+
def create_cluster
|
128
|
+
app = Rails::Gke.configuration.app
|
129
|
+
network = Rails::Gke.configuration.network
|
130
|
+
sub_network = Rails::Gke.configuration.network
|
131
|
+
machine_type = Rails::Gke.configuration.machine_type
|
132
|
+
zone = Rails::Gke.configuration.zone
|
133
|
+
system("gcloud container clusters create #{app} \
|
134
|
+
--network #{network} \
|
135
|
+
--subnetwork #{sub_network} \
|
136
|
+
--zone #{zone} \
|
137
|
+
--scopes=https://www.googleapis.com/auth/cloud-platform \
|
138
|
+
--machine-type #{machine_type} \
|
139
|
+
--enable-autorepair \
|
140
|
+
--enable-ip-alias \
|
141
|
+
--num-nodes 2 \
|
142
|
+
--enable-autoscaling \
|
143
|
+
--min-nodes 1 \
|
144
|
+
--max-nodes 4 \
|
145
|
+
--tags=allow-health-checks")
|
146
|
+
end
|
147
|
+
|
148
|
+
def resize_cluster pool_name: "default-pool", node_num: 1
|
149
|
+
app = Rails::Gke.configuration.app
|
150
|
+
zone = Rails::Gke.configuration.zone
|
151
|
+
system "gcloud container clusters resize #{app} --node-pool #{pool_name} --num-nodes #{node_num} --zone #{zone}"
|
152
|
+
end
|
153
|
+
|
154
|
+
def create_namespace
|
155
|
+
app = Rails::Gke.configuration.app
|
156
|
+
system("kubectl create namespace #{app}")
|
157
|
+
end
|
158
|
+
|
159
|
+
def create_ip
|
160
|
+
ip_name = Rails::Gke.configuration.app.to_s + "-ip"
|
161
|
+
system("gcloud compute addresses create #{ip_name} --global")
|
162
|
+
end
|
163
|
+
|
164
|
+
def apply_deployment
|
165
|
+
app = Rails::Gke.configuration.app
|
166
|
+
system("kubectl apply -f deployment.yml --namespace=#{app}")
|
167
|
+
end
|
168
|
+
|
169
|
+
def apply_secret
|
170
|
+
app = Rails::Gke.configuration.app
|
171
|
+
system("kubectl apply -f secret.yml --namespace=#{app}")
|
172
|
+
end
|
173
|
+
|
174
|
+
def apply_service
|
175
|
+
app = Rails::Gke.configuration.app
|
176
|
+
system("kubectl apply -f service.yml --namespace=#{app}")
|
177
|
+
end
|
178
|
+
|
179
|
+
def apply_ingress
|
180
|
+
app = Rails::Gke.configuration.app
|
181
|
+
system("kubectl apply -f ingress.yml --namespace=#{app}")
|
182
|
+
end
|
183
|
+
|
184
|
+
def delete_deployment
|
185
|
+
app = Rails::Gke.configuration.app
|
186
|
+
system("kubectl delete -f deployment.yml --namespace=#{app}")
|
187
|
+
end
|
188
|
+
|
189
|
+
def delete_secret
|
190
|
+
app = Rails::Gke.configuration.app
|
191
|
+
system("kubectl delete -f secret.yml --namespace=#{app}")
|
192
|
+
end
|
193
|
+
|
194
|
+
def delete_service
|
195
|
+
app = Rails::Gke.configuration.app
|
196
|
+
system("kubectl delete -f service.yml --namespace=#{app}")
|
197
|
+
end
|
198
|
+
|
199
|
+
def delete_ingress
|
200
|
+
app = Rails::Gke.configuration.app
|
201
|
+
system("kubectl delete -f ingress.yml --namespace=#{app}")
|
202
|
+
end
|
203
|
+
|
204
|
+
def update_container version: "latest"
|
205
|
+
app = Rails::Gke.configuration.app
|
206
|
+
project_id = Rails::Gke.configuration.project_id
|
207
|
+
system("docker build . -t #{app}:#{version}")
|
208
|
+
system("docker tag #{app}:#{version} asia.gcr.io/#{project_id}/#{app}:#{version}")
|
209
|
+
system("docker push asia.gcr.io/#{project_id}/#{app}:#{version}")
|
210
|
+
end
|
211
|
+
|
212
|
+
def get_pods
|
213
|
+
app = Rails::Gke.configuration.app
|
214
|
+
system("kubectl get pods --namespace=#{app}")
|
215
|
+
end
|
216
|
+
|
217
|
+
def get_svc
|
218
|
+
app = Rails::Gke.configuration.app
|
219
|
+
system("kubectl get svc --namespace=#{app}")
|
220
|
+
end
|
221
|
+
|
222
|
+
def get_ingress
|
223
|
+
app = Rails::Gke.configuration.app
|
224
|
+
system("kubectl get ingress --namespace=#{app}")
|
225
|
+
end
|
226
|
+
|
227
|
+
def run_test
|
228
|
+
app = Rails::Gke.configuration.app
|
229
|
+
system("docker rm -f web")
|
230
|
+
system("docker build . -t #{app}:latest")
|
231
|
+
system("docker run --name web -it --env-file $PWD/.local_env -p 3000:3000 #{app}:latest")
|
232
|
+
end
|
233
|
+
|
234
|
+
def get_clusters
|
235
|
+
system("kubectl config get-clusters")
|
236
|
+
end
|
237
|
+
|
238
|
+
def get_current_cluster
|
239
|
+
system("kubectl config current-context")
|
240
|
+
end
|
241
|
+
|
242
|
+
def use_context cluster:
|
243
|
+
system("kubectl config use-context #{cluster}")
|
244
|
+
end
|
245
|
+
|
246
|
+
def get_credentials
|
247
|
+
app = Rails::Gke.configuration.app
|
248
|
+
zone = Rails::Gke.configuration.zone
|
249
|
+
system("gcloud container clusters get-credentials #{app} -cluster --zone #{zone}")
|
250
|
+
end
|
251
|
+
|
252
|
+
def create_ssl
|
253
|
+
system("gcloud compute ssl-certificates create #{Rails::Gke.configuration.app}-ssl --domains=#{Rails::Gke.configuration.domain} --global")
|
254
|
+
end
|
255
|
+
|
256
|
+
def update_proxy
|
257
|
+
system("gcloud compute target-https-proxies update TARGET_PROXY_NAME \
|
258
|
+
--ssl-certificates SSL_CERTIFICATE_LIST \
|
259
|
+
--global-ssl-certificates \
|
260
|
+
--global")
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
def self.configure
|
265
|
+
self.configuration ||= Configuration.new
|
266
|
+
yield(configuration)
|
267
|
+
end
|
268
|
+
|
269
|
+
class Configuration
|
270
|
+
attr_accessor :project_id, :app, :network, :machine_type, :zone, :domain, :google_application_credentials, :channel
|
271
|
+
|
272
|
+
def initialize
|
273
|
+
@project_id = nil
|
274
|
+
@app = nil
|
275
|
+
@network = nil
|
276
|
+
@machine_type = nil
|
277
|
+
@zone = nil
|
278
|
+
@domain = nil
|
279
|
+
@google_application_credentials = nil
|
280
|
+
@channel = nil
|
281
|
+
end
|
282
|
+
end
|
283
|
+
end
|
284
|
+
end
|