1#!/usr/bin/ruby
2# frozen_string_literal: true
3
4require "date"
5require "dhall"
6require "em-hiredis"
7require "pg/em/connection_pool"
8require "em-http"
9require "em_promise"
10require "json"
11require "optparse"
12require "ruby-bandwidth-iris"
13require "securerandom"
14require "sentry-ruby"
15require "time"
16
17@verbosity = 0
18@real_data = true
19@dry_run = false
20@sources = []
21@filters = {}
22
23OptionParser.new do |opts|
24 opts.banner =
25 "Usage: porting [-vn] " \
26 "[-c CUSTOMER_ID] " \
27 "-s <bandwidth|db|fake> DHALL_CONFIG"
28
29 opts.on(
30 "-v", "--verbose",
31 "Print to terminal, run twice to not even send to customer"
32 ) do
33 @verbosity += 1
34 end
35
36 opts.on(
37 "-n", "--dry-run",
38 "Figure out what state they're in, but don't take action"
39 ) do
40 @dry_run = true
41 end
42
43 opts.on("-h", "--help", "Print this help") do
44 puts opts
45 exit
46 end
47
48 opts.on(
49 "-sSOURCE", "--source=SOURCE", "Source of ports (required, repeatable)"
50 ) do |source|
51 @sources.append source
52 end
53
54 opts.on(
55 "-cCUSTOMER_ID", "--customer-id=CUSTOMER_ID",
56 "Filter by customer ID (db source only)"
57 ) do |customer_id|
58 @filters[:customer_id] = customer_id
59 end
60end.parse!
61
62@sources = ["db", "bandwidth"] if @sources.empty?
63
64SCHEMA = "{
65 bandwidth : { account: Text, username: Text, password: Text },
66 xmpp: { jid: Text, password: Text },
67 notification: { endpoint: Text, source_number: Text },
68 pubsub: { server: Text, node: Text },
69 testing_tel: Text,
70 admin_server: Text
71}"
72
73raise "Need a Dhall config" unless ARGV[0]
74
75CONFIG = Dhall::Coder
76 .new(safe: Dhall::Coder::JSON_LIKE + [Symbol, Proc])
77 .load("#{ARGV.first} : #{SCHEMA}", transform_keys: :to_sym)
78
79require_relative "../lib/blather_notify"
80require_relative "../lib/expiring_lock"
81require_relative "../lib/form_to_h"
82require_relative "../lib/porting_step_repo"
83require_relative "../lib/port_repo"
84require_relative "../lib/postgres"
85
86Faraday.default_adapter = :em_synchrony
87BandwidthIris::Client.global_options = {
88 account_id: CONFIG[:bandwidth][:account],
89 username: CONFIG[:bandwidth][:username],
90 password: CONFIG[:bandwidth][:password]
91}
92
93@output =
94 case @verbosity
95 when 0
96 FullAutomatic.new(
97 BlatherNotify::PubSub::Address.new(**CONFIG[:pubsub]),
98 CONFIG[:notification][:endpoint],
99 CONFIG[:notification][:source_number]
100 )
101 when 1
102 ObservedAuto.new(
103 CONFIG[:notification][:endpoint],
104 CONFIG[:notification][:source_number]
105 )
106 else
107 FullManual.new
108 end
109
110PORT_SOURCES = @sources.map(&:downcase).map { |source|
111 case source
112 when "bandwidth"
113 PortRepo::Bandwidth.new(@output, dry_run: @dry_run)
114 when "db"
115 PortRepo::Db.new(@output, dry_run: @dry_run, filters: @filters)
116 when "fake"
117 PortRepo::Fake.new(@output, dry_run: @dry_run)
118 else
119 puts <<~ERR
120 Invalid port source (-s / --source): #{source}.
121 Valid options: fake, db, endstream
122 ERR
123 # EINVAL
124 exit! 22
125 end
126}
127
128EM.run do
129 REDIS = EM::Hiredis.connect
130 DB = Postgres.connect(dbname: "jmp")
131
132 BlatherNotify.start(
133 CONFIG[:xmpp][:jid],
134 CONFIG[:xmpp][:password]
135 ).then {
136 EMPromise.all(PORT_SOURCES.map(&:process))
137 }.catch { |e|
138 @output.error("ROOT", :catch, e)
139 }.then { BlatherNotify.shutdown }
140end