четверг, 29 октября 2015 г.

[jira,conf] Прикручиваем mail server с SSL через JNDI к Confluence 5.5 и ниже (Jira)

1) Останавливаем Конфлу/jira
2) Перемещаем (НЕ КОПИРУЕМ) файл mail-x.x.x.jar из <confluence-install>/confluence/WEB-INF/lib в <confluence-install>/lib.
3) В /opt/atlassian/confluence/conf/server.xml

Добавляем раздел Resource перед </Context>

 <Resource name="mail/YandexSMTPSession"
        auth="Container"
        type="javax.mail.Session"
        mail.smtp.host="smtp.yandex.ru"
        mail.smtp.port="465"
        mail.smtp.auth="true"
        mail.smtp.user="xxxx@yandex.ru"
        password="lhk6kDH7s"
        mail.smtp.starttls.enable="true"
        mail.smtp.socketFactory.class="javax.net.ssl.SSLSocketFactory"
    />

4) Рестартуем Конфлу
5) Дальше в web интерфейсе Conflu настраиваем в разделе mail server SMTP mail server.

В поле JNDI LOCATION указываем java:comp/env/mail/YandexSMTPSession

Для jira может понадобиться импортировать SSl сертификат. Проще всего поставить плагин JIRA SSL Add-on. Тогда в настройках-система появится SSL Configure

Если без SSL Add-on:
сохраняем сертификат сайта (DER).
импортируем его в трастед кейстор (это файл cacerts) ./keytool -import -alias jira -file /home/shinta/tmp/jira.cer -keystore /opt/atlassian/bitbucket/4.2.1/jre/lib/security/cacerts
добавляем в /jira/bin/setenv.sh к аргументам java -Djavax.net.ssl.trustStore=/opt/atlassian/bitb ucket/4.2.1/jre/lib/security/cacerts

пятница, 8 мая 2015 г.

Asterisk+Dundi

Насчет ключей - можно обойтись без них. т.е просто не использовать поля "inkey =" и
"outkey =" в dundi.conf

cd /var/lib/asterisk/keys/ /usr/src/astgenkey -n aster4

создает ключи public/private, их следует сложить в /var/lib/asterisk/keys/ и /usr/share/asterisk/keys/

Обмениваемся  ключами  между астерами (ложим в /var/lib/asterisk/keys/ и /usr/share/asterisk/keys/) которые будут работать через Dundi

По идее дальним астерам нужны только pub ключи, но у меня не заработало только с ними. Разбираться сильно не стал, т.к система внутренняя.


scp aster4.pub root@192.168.3.52:/var/lib/asterisk/keys/
scp aster4.key root@192.168.3.52:/usr/share/asterisk/keys/
scp aster1.pub root@192.168.3.56:/var/lib/asterisk/keys/
scp aster1.key root@192.168.3.56:/usr/share/asterisk/keys/

файлы ключей должны принадлежать asterisk:asterisk

Перезагружаем в консоли астера module reload res_crypto.so (заодно он покажет, если есть какие то проблемы)

Затем  module reload pbx_dundi.so

проверяем, что ключи загрузились 

aster1*CLI> keys show
Key Name           Type     Status           Sum
------------------ -------- ---------------- --------------------------------
aster2             PUBLIC   [Loaded]         7379e2a11d5a8f8f4209b3fdc7febb20
freeworlddialup    PUBLIC   [Loaded]         5efd552d73309f29212331a75f3c701e
aster1             PUBLIC   [Loaded]         0ed4a73ac18fb141bbdd7f797542146d
aster1             PRIVATE  [Loaded]         9c5777e70e49a4e8e6a42ea67b5a6883
iaxtel             PUBLIC   [Loaded]         d919b3ef03eb4dc54c8fee86bfeeada1
aster2             PRIVATE  [Loaded]         da214b9a7dccf9c6ff28cbf2e38e9fed
aster4             PUBLIC   [Loaded]         7e1a1b95eea77dacbfc42b813dd26ba1


Проверяем, что обмен данными идет

dundi query 00:0c:29:8a:a9:f1@extensions


В sip.conf в секции [general] прописываем
regcontext=RegisteredDevices


Поднимаем sip trunk между астерисками 

в sip.conf 

aster4:
[dundi_to_asterisk1]
host=192.168.3.52
type=peer
secret=secret
context=local
disallow=all
allow=ulaw
allow=alaw
qualify=yes
defaultuser=dundi_to_asterisk4


aster1:
[dundi_to_asterisk4]
host=192.168.3.56
type=peer
secret=secret
context=local
disallow=all
allow=ulaw
allow=alaw
qualify=yes
canreinvite=no
nat=yes
defaultuser=dundi_to_asterisk1

Правим dundi.conf
Здесь мы настраиваем dundi пиры и создаем mapping'и. Один mapping можно использовать для любоко кол-ва данди пиров. Лукап происходит корректно, если номер зарегистрирован только на одном из астерисков.

aster4:
[general]
department=Your Department
organization=Your Company, Inc.
locality=Your City
stateprov=ST
country=US
email=your@email.com
phone=+12565551212
bindaddr=192.168.3.56
port=4520
entityid=00:0c:29:8a:a9:f1 ; MAC belong to this system
cachetime=5
ttl=2
autokill=yes

[mappings]
extensions => RegisteredDevices,0,SIP,dundi_to_asterisk2/${NUMBER},nopartial


[00:0c:29:c5:d6:e4] ; MAC Address of Asterisk1
model = symmetric
host = 192.168.3.52;(this is the IP address of the DUNDi Asterisk1)
inkey = aster4
outkey = aster1
include = extensions
permit = extensions
qualify = yes
order = primary

aster1:
[general]
department=Your Department
organization=Your Company, Inc.
locality=Your City
stateprov=ST
country=US
email=your@email.com
phone=+12565551212
bindaddr=192.168.3.52
port=4520
entityid=00:0c:29:c5:d6:e4
cachetime=5
ttl=2
autokill=yes

[mappings]
extensions => RegisteredDevices,0,SIP,dundi_to_asterisk1/${NUMBER},nopartial

[00:0c:29:8a:a9:f1]  ; MAC Address of Asterisk4
model = symmetric
host = 192.168.3.56;(this is the IP address of the DUNDi Asterisk4)
inkey = aster1
outkey = aster4
include = extensions
permit = extensions
qualify = yes
order = primary


В настройках dundi.conf следует иметь ввиду, что строки в mappings, это то что будет передаваться на удаленный dundi peer и именно на этом удаленном пире должны быть нужные настройки (например, context RegisteredDevices и SIP trunk dundi_to_asterisk1)


[mappings]
extensions => RegisteredDevices,0,SIP,dundi_to_asterisk1/${NUMBER},nopartial

Теперь перейдем к context'ам. Я использую конструкцию вида.

Если есть данные в dundi, то берем их. Если нет, то звоним на локальный астериск.

exten => 958898,1,Dial(${IF($[${LEN(${DUNDILOOKUP(1001,extensions,b)})}>0]?${DUNDILOOKUP(1001,extensions,b)}:"SIP/1001")},30)

exten => 1001,1,Dial(${IF($[${LEN(${DUNDILOOKUP(1001,extensions,b)})}>0]?${DUNDILOOKUP(1001,extensions,b)}:"SIP/1001")},30)

для получения направления звонка используется функция DUNDILOOKUP(1001,extensions,b)
она ищет экстеншен 1001 в маппинге extensions dundi.conf. Возвращает SIP/dundi_to_asterisk2

Это прямой аналог команды 
aster1*CLI> dundi lookup 1000@extensions
  1.     0 SIP/dundi_to_asterisk2/1000 (EXISTS)
     from 00:0c:29:de:70:6d, expires in 5 s
DUNDi lookup completed in 64 ms

Если экстеншен зарегистрирован на нескольких астерисках, то dundi lookup вернет несколько значений. Передаст при этом он только первое. Вполне так можно использовать для резервирования :)

aster2*CLI> dundi lookup 1001@extensions
  1.     0 SIP/dundi_to_asterisk1/1001 (EXISTS)
     from 00:0c:29:c5:d6:e4, expires in 5 s
  2.     0 SIP/dundi_to_asterisk4/1001 (EXISTS)
     from 00:0c:29:8a:a9:f1, expires in 5 s
DUNDi lookup completed in 89 ms




Вообщем то с этого момента можно плодить астериски с данди. Остальные настройки уже распространяются на диалплан и специфичны для конкретных конфигураций.

Пример моей тестовой конфигурации состоящей из трех астерисков:


aster1:

sip.conf

[general]
context=poumolchaniu
srvlookup=no
disallow=all
allow=ulaw
allow=g729
allow=ilbc
language=ru
trustrpid=yes
sendrpid=yes
registertimeout=20
registerattempts=10
t38pt_udptl=no
allow=h263
videosupport=yes
autocreatepeer=no
minexpiry=60
maxexpirey=3600
rtsavesysname=yes
rtptimeout=60
rtpholdtimeout=300
dtmfmode=auto
directrtpsetup=no
canreinvite=no
sdpsession=Aster1 Server
#include sipuserss.conf
#include sipgw.conf
#include siptrunk.conf
alwaysauthreject=yes
videosupport=yes
defaultexpiry=3600
regcontext=RegisteredDevices

;workaround for asteriks crash
session-timers = refuse



sipgw.conf

[dundi_to_asterisk2]
host=192.168.3.53
type=peer
secret=secret
context=local
disallow=all
allow=ulaw
allow=alaw
qualify=yes
canreinvite=no
nat=yes
defaultuser=dundi_to_asterisk1


[dundi_to_asterisk4]
host=192.168.3.56
type=peer
secret=secret
context=local
disallow=all
allow=ulaw
allow=alaw
qualify=yes
canreinvite=no
nat=yes
defaultuser=dundi_to_asterisk1

sipusers.conf

[1000]
type=friend
accountcode=outgoing
host=dynamic
qualify=yes
callerid=""<958877>
language=ru
username=1000
disallow=all
allow=gsm
allow=g729
allow=ulaw
allow=h263
context=tolkogorod+zona+mezhgorod+mezhdunarodka
nat=yes
busylevel=2
call-limit=1
dtmfmode = rfc2833

[1001]
type=friend
accountcode=outgoing
host=dynamic
qualify=yes
callerid=""<958898>
language=ru
username=1001
disallow=all
allow=gsm
allow=g729
allow=ulaw
allow=h263
context=tolkogorod+zona+mezhgorod+mezhdunarodka
nat=yes
busylevel=2
call-limit=1
dtmfmode = rfc2833


dundi.conf
[general]
department=Your Department
organization=Your Company, Inc.
locality=Your City
stateprov=ST
country=US
email=your@email.com
phone=+12565551212
bindaddr=192.168.3.52
port=4520
entityid=00:0c:29:c5:d6:e4
cachetime=5
ttl=2
autokill=yes

[mappings]
extensions => RegisteredDevices,0,SIP,dundi_to_asterisk1/${NUMBER},nopartial

[00:0c:29:de:70:6d] ; MAC Address of Asterisk2
model = symmetric
host = 192.168.3.53;(this is the IP address of the DUNDi Asterisk2)
inkey = aster1
outkey = aster2
include = extensions
permit = extensions
qualify = yes
order = primary

[00:0c:29:8a:a9:f1]  ; MAC Address of Asterisk4
model = symmetric
host = 192.168.3.56;(this is the IP address of the DUNDi Asterisk4)
inkey = aster1
outkey = aster4
include = extensions
permit = extensions
qualify = yes
order = primary

extensions.conf

[RegisteredDevices]

[tolkogorod+zona+mezhgorod+mezhdunarodka]
Include => local
Include => CallerIDoutCiscofon
Include => specslugbi
Include => gorod
Include => zona
Include => mezhgorod
Include => mezhdunarodka


[local]
#include extensionslookup.conf


extensionslookup.conf
exten => 958877,1,Dial(${IF($[${LEN(${DUNDILOOKUP(1000,extensions,b)})}>0]?${DUNDILOOKUP(1000,extensions,b)}:"SIP/1000")},30)
exten => 958898,1,Dial(${IF($[${LEN(${DUNDILOOKUP(1001,extensions,b)})}>0]?${DUNDILOOKUP(1001,extensions,b)}:"SIP/1001")},30)
exten => 1000,1,Dial(${IF($[${LEN(${DUNDILOOKUP(1000,extensions,b)})}>0]?${DUNDILOOKUP(1000,extensions,b)}:"SIP/1000")},30)
exten => 1001,1,Dial(${IF($[${LEN(${DUNDILOOKUP(1001,extensions,b)})}>0]?${DUNDILOOKUP(1001,extensions,b)}:"SIP/1001")},30)


aster2

sip.conf

[general]
srvlookup=no
NAT=yes
bindport=5060
allowguest=no
canreinvite=no
regcontext=RegisteredDevices

[1000]
type=friend
context=LocalSets
host=dynamic
disallow=all
allow=gsm
canreinvite=no
qualify=yes
defaultuser=1000
fromuser=1000
callerid=""<958877>

[dundi_to_asterisk1]
host=192.168.3.52
type=peer
secret=secret
context=LocalSets
disallow=all
allow=ulaw
allow=alaw
qualify=yes
defaultuser=dundi_to_asterisk2

dundi.conf
[general]
department=Your Department
organization=Your Company, Inc.
locality=Your City
stateprov=ST
country=US
email=your@email.com
phone=+12565551212
bindaddr=192.168.3.53
port=4520
entityid=00:0c:29:de:70:6d
cachetime=5
ttl=2
autokill=yes

[mappings]
extensions => RegisteredDevices,0,SIP,dundi_to_asterisk2/${NUMBER},nopartial


[00:0c:29:c5:d6:e4] ; MAC Address of Asterisk1
model = symmetric
host = 192.168.3.52;(this is the IP address of the DUNDi Asterisk1)
inkey = aster2
outkey = aster1
include = extensions
permit = extensions
qualify = yes
order = primary

extensions.conf
[general]
static=yes
writeprotect=no
autofallthrough=no
clearglobalvars=no
priorityjumping=no


[RegisteredDevices]
;exten => 1000,1,NoOp()

[lookup]
exten => 958877,1,Dial(${IF($[${LEN(${DUNDILOOKUP(1000,extensions,b)})}>0]?${DUNDILOOKUP(1000,extensions,b)}:"SIP/1000")},30)
exten => 958898,1,Dial(${IF($[${LEN(${DUNDILOOKUP(1001,extensions,b)})}>0]?${DUNDILOOKUP(1001,extensions,b)}:"SIP/1001")},30)
exten => 1000,1,Dial(${IF($[${LEN(${DUNDILOOKUP(1000,extensions,b)})}>0]?${DUNDILOOKUP(1000,extensions,b)}:"SIP/1000")},30)
exten => 1001,1,Dial(${IF($[${LEN(${DUNDILOOKUP(1001,extensions,b)})}>0]?${DUNDILOOKUP(1001,extensions,b)}:"SIP/1001")},30)


[LocalSets]
include => lookup

aster4
sip.conf
[general]
srvlookup=no
NAT=yes
bindport=5060
allowguest=no
canreinvite=no
regcontext=RegisteredDevices



[1002]
type=friend
context=LocalSets
host=dynamic
disallow=all
allow=gsm
canreinvite=no
qualify=yes
defaultuser=1002
fromuser=1002
callerid=""<958877>

[dundi_to_asterisk1]
host=192.168.3.52
type=peer
secret=secret
context=DUNDi_Incoming
disallow=all
allow=ulaw
allow=alaw
qualify=yes
defaultuser=dundi_to_asterisk4

dundi.conf
[general]
department=Your Department
organization=Your Company, Inc.
locality=Your City
stateprov=ST
country=US
email=your@email.com
phone=+12565551212
bindaddr=192.168.3.56
port=4520
entityid=00:0c:29:8a:a9:f1
cachetime=5
ttl=2
autokill=yes

[mappings]
extensions => RegisteredDevices,0,SIP,dundi_to_asterisk4/${NUMBER},nopartial


[00:0c:29:c5:d6:e4] ; MAC Address of Asterisk1
model = symmetric
host = 192.168.3.52;(this is the IP address of the DUNDi Asterisk1)
inkey = aster4
outkey = aster1
include = extensions
permit = extensions
qualify = yes
order = primary

extensions.conf
[general]
static=yes
writeprotect=no
autofallthrough=no
clearglobalvars=no
priorityjumping=no


[RegisteredDevices]

[DUNDi_Incoming]
exten => 1002,1,Dial(${IF($[${LEN(${DUNDILOOKUP(1002,extensions,b)})}>0]?${DUNDILOOKUP(1002,extensions,b)}:"SIP/1002")},30)




[jira] Продвинутая обработка входящих писем (incomming mail handlers)

Натолкнулся на прикольную церновскую разработку.

https://wikis.web.cern.ch/wikis/display/JMH/JIRA+Advanced+Mail+Handler

Плагин для Jira. Скачиваем и устанавливаем через Upload Plug-in из Manage add-ons

Настраиваем Incomming mail в System, добавляем Mail Handler там же. В качестве Handler указываем advancedCreateOrCommentHandler

Плагин позволяет добавлять в тему писем таги в виде  #TAG-NAME=tag-value или #TAG-NAME=tag-value1,tag-value2,tag-value3. По ним задачам будут навешиваться или изменяться поля и компоненты.

Например включаем в тему письма таг,
#PROJECT=GNOM
#ASSIGNEE=vasya
#BUG#NEWFEATURE  - issue type
#BLOCKER#CRITICAL - priority
#COMPONENT=sloniki
#EST=1h
#DUE=2015-11-01

Ну а дальше полет фантазии: можно правилами в почтовике (MTA ) настроить добавление тегов по фильтрам, можно писать руками при отправке.


четверг, 7 мая 2015 г.

Vim

Доступные синтаксы


/usr/share/vim/vim73/syntax


установить синтакс в vim
:set filetype=название

Запустить команды оболочки из Vim, используя команду ':!'
например, :!ls

Доступ ко всем возможностям оболочки, запустите :sh или :bash

Открытие файлового менеджера в vim
:Vex или :E

кодировка
:set encoding=

vim -c :E  - запустить вим с выполнением команды :E


Команды в vim



:E - file explorer

!ls -la - выполнение команды в шеле
:split filename  - разделить экран и открыть второй файл (ctrl-w - переход между окнами)
:vsplit filename
colorschemes ложить в .vim/colors


настройки в /home/.vim.rc


 colorscheme sexy-railscasts
 set fileencodings=utf-8,koi8-r,cp1251
 set fileformats=unix,dos,mac
set number   #номера строк
set pastetoggle=<F2>   #биндим на f2 включение и отключение paste, чтобы vim не коверкал строки при вставке из буфера.

set foldenable
set foldmethod=manual

#меняем foldmethod по нажатию f4
map <F4>  <esc>:call SWITCHFOLD()<cr> "{{{   
 function SWITCHFOLD()
 if &foldmethod=="marker"
 set foldmethod=syntax
 return
 endif
 if &foldmethod=="syntax"
 set foldmethod=indent
 return
 endif
 if &foldmethod=="indent"
 set foldmethod=manual
 return
 endif
 if &foldmethod=="manual"
 set foldmethod=marker
 return
 endif

 endfunction



earlier 4m
вернетеся на 4 минуты, т.е. состояние текста которое было 4 минут назад "earlier".

е двинуться вперед во времени:
:later 45s
интервал составит 45 секунд.

отмена 5ти внесенных изменений:
:undo 5

просмотреть дерево undo:
:undolist





понедельник, 20 апреля 2015 г.

Установка passenger для apache + настройка proxy_pass (Ruby on Rails)

Установка


https://www.phusionpassenger.com/documentation/Users%20guide%20Apache.html

Способов установки дофига (см. ссылку выше). Я ставил из rubygems

gem install passenger
потом запускаем
passenger-install-apache2-module
Следуем его указаниям и ставим недостающие зависимости.

Далее в конфиг apache прописываем (меняем пути на свои)

 LoadModule passenger_module /usr/local/rvm/gems/ruby-2.2.1/gems/passenger-5.0.6/buildout/apache2/mod_passenger.so
<IfModule mod_passenger.c>
PassengerRoot /usr/local/rvm/gems/ruby-2.2.1/gems/passenger-5.0.6
PassengerDefaultRuby /usr/local/rvm/gems/ruby-2.2.1/wrappers/ruby
</IfModule>

Затем рестартуем apache

Проверить, что passenger работает можно командой passenger-memory-stats


Настройки в rails

/config/environments/production.rb

config.action_controller.relative_url_root = '/srv/www/rails/staff_locator/'

Настройки в apache

Принимаем запрос на 80м порту с определенным URI  (/staff и /locator) и перенаправляем его на другой URI (у меня там слушает Ruby on Rails).

На 80м порту живет другое веб-приложение на PERL'e

Добавил в vhost для основного сервиса проброс до rails
<VirtualHost *:80>
.
.
.
 #FOR RAILS PROXY PASS - START
 #point to different document root for rails application
 Alias "/srv/www/rails/staff_locator/" "/srv/www/rails/staff_locator/public/"

 #making permissions for rails assets folder and location
 <Directory "/srv/www/rails/staff_locator/public/assets">
 AllowOverride all
 Order allow,deny
 Allow from all
 </Directory>

#Это чтобы находил папку assets с стилями и картинками. Думаю, что это костыль и правильно надо реализовывать как то по другому. <Location /assets>
 Order allow,deny
 Allow from 192.168.0.0/16
</Location>

 <Location /staff>
 Order allow,deny
 Allow from 192.168.0.0/16
 </Location>

 <Location /locator>
 Order allow,deny
 Allow from 192.168.0.0/16
 </Location>

 #disable Forward-proxy
 ProxyRequests off

 #proxy access security
 <Proxy "*">
   Order deny,allow
   Allow from 192.168.0.0/16
 </Proxy>

 ProxyPassMatch "^/staff(.*)" "http://localhost:8080/staff$1"
 ProxyPassMatch "^/locator(.*)" "http://localhost:8080/locator$1"
ProxyPassMatch "^/assets(.*)" "http://localhost:8080/assets$1"

 #FOR RAILS PROXY PASS -END

Создал  ror.conf

 <VirtualHost *:8080>
       ServerName xxx.ru
       # !!! Be sure to point DocumentRoot to 'public'!
       #DocumentRoot /ror/test/public
       DocumentRoot /srv/www/rails/staff_locator/public
 <Directory /srv/www/rails/staff_locator/public>
 # This relaxes Apache security settings.
          AllowOverride all
          Order allow,deny
          Allow from all
          # Multiews must be turned off.
          Options -MultiViews
          # Uncomment this if you're on Apache >= 2.4:
          #Require all granted
    </Directory>
    </VirtualHost>