diff --git a/.travis.yml b/.travis.yml
index de3333cd..f2a02038 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,5 +1,5 @@
notifications:
- slack: rtcamp:MGteQ7CA6kFIsNbMIarkeWxa
+ slack: easyengine:76AI30tP8P8AcNTaWaQ9ZAT7
webhooks:
urls:
- https://webhooks.gitter.im/e/bd77a26eab56de803949
diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index c29d5aba..d990aedb 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -1,3 +1,16 @@
+v3.4.0 - Jan 6, 2015
+- Added Let's Encrypt support
+ - ee site create example.com [--wp/..] --letsencrypt
+ - ee site update example.com --letsencrypt=on/off/renew
+ - Automatic renew of certs through cron
+ - Mail notification added on certs renew
+ - Alias command: --le
+- Added HTTP/2 support
+ - ee stack install/remove/purge --nginxmainline
+- Check SSL cert status/expiry date in site info
+ - ee site info example.com
+- Update autocompletion and man page
+
v3.3.15 - Dec 9, 2015
- Upgrade wp-cli version to 0.21.1
diff --git a/config/bash_completion.d/ee_auto.rc b/config/bash_completion.d/ee_auto.rc
index 0b7011cc..14b62d95 100644
--- a/config/bash_completion.d/ee_auto.rc
+++ b/config/bash_completion.d/ee_auto.rc
@@ -74,7 +74,7 @@ _ee_complete()
# HANDLE EVERYTHING AFTER THE THIRD LEVEL NAMESPACE
"install" | "purge" | "remove" )
COMPREPLY=( $(compgen \
- -W "--pagespeed --web --admin --mail --nginx --php --mysql --postfix --wpcli --phpmyadmin --adminer --utils --all --mailscanner --hhvm --redis --phpredisadmin" \
+ -W "--pagespeed --web --admin --mail --nginx --nginxmainline --php --mysql --postfix --wpcli --phpmyadmin --adminer --utils --all --mailscanner --hhvm --redis --phpredisadmin" \
-- $cur) )
;;
"upgrade" )
@@ -165,13 +165,13 @@ _ee_complete()
"create")
COMPREPLY=( $(compgen \
- -W "--user --pass --email --html --php --mysql --wp --wpsubdir --wpsubdomain --w3tc --wpfc --wpsc --hhvm --proxy= --pagespeed --wpredis" \
+ -W "--user --pass --email --html --php --mysql --wp --wpsubdir --wpsubdomain --w3tc --wpfc --wpsc --hhvm --proxy= --pagespeed --wpredis --letsencrypt -le" \
-- $cur) )
;;
"update")
COMPREPLY=( $(compgen \
- -W "--password --php --mysql --wp --wpsubdir --wpsubdomain --w3tc --wpfc --wpsc --hhvm --hhvm=off --pagespeed --pagespeed=off --wpredis" \
+ -W "--password --php --mysql --wp --wpsubdir --wpsubdomain --w3tc --wpfc --wpsc --hhvm --hhvm=off --pagespeed --pagespeed=off --wpredis --letsencrypt --letsencrypt=off --letsencrypt=renew" \
-- $cur) )
;;
"delete")
@@ -217,9 +217,9 @@ _ee_complete()
"--wp")
if [ ${COMP_WORDS[1]} != "debug" ]; then
if [ ${COMP_WORDS[2]} == "create" ]; then
- retlist="--wp --wpsc --w3tc --wpfc --pagespeed --hhvm --user --email --pass --wpredis"
+ retlist="--wp --wpsc --w3tc --wpfc --pagespeed --hhvm --user --email --pass --wpredis --letsencrypt"
elif [ ${COMP_WORDS[2]} == "update" ]; then
- retlist="--wp --w3tc --wpfc --wpsc --pagespeed --hhvm --pagespeed=off --hhvm=off --wpredis"
+ retlist="--wp --w3tc --wpfc --wpsc --pagespeed --hhvm --pagespeed=off --hhvm=off --wpredis --letsencrypt --letsencrypt=off --letsencrypt=renew"
else
retlist=""
fi
@@ -236,9 +236,9 @@ _ee_complete()
"--wpsubdir" | "--wpsubdomain")
if [ ${COMP_WORDS[1]} != "debug" ]; then
if [ ${COMP_WORDS[2]} == "create" ]; then
- retlist="--wpsc --w3tc --wpfc --pagespeed --hhvm --user --email --pass --wpredis"
+ retlist="--wpsc --w3tc --wpfc --pagespeed --hhvm --user --email --pass --wpredis --letsencrypt"
elif [ ${COMP_WORDS[2]} == "update" ]; then
- retlist="--w3tc --wpfc --wpsc --pagespeed --hhvm --pagespeed=off --hhvm=off --wpredis"
+ retlist="--w3tc --wpfc --wpsc --pagespeed --hhvm --pagespeed=off --hhvm=off --wpredis --letsencrypt --letsencrypt=off --letsencrypt=renew"
else
retlist=""
fi
@@ -254,7 +254,7 @@ _ee_complete()
"--pagespeed" | "--hhvm" | "--wpredis" | "--w3tc" | "--wpfc" | "--wpsc" | "--wpsubdir" | "--wpsubdomain" | "--user" | "--pass" | "--email" | "--wp")
if [ ${COMP_WORDS[2]} == "create" ]; then
- retlist="--user --pass --email --wp --wpsubdir --wpsubdomain --w3tc --wpfc --wpsc --hhvm --pagespeed --experimenal --wpredis"
+ retlist="--user --pass --email --wp --wpsubdir --wpsubdomain --w3tc --wpfc --wpsc --hhvm --pagespeed --experimenal --wpredis --letsencrypt"
else
retlist=""
fi
@@ -267,7 +267,7 @@ _ee_complete()
"--pagespeed" | "--hhvm" | "--wpredis" | "--w3tc" | "--wpfc")
if [ ${COMP_WORDS[2]} == "update" ]; then
- retlist="--password --php --mysql --wp --wpsubdir --wpsubdomain --w3tc --wpfc --wpsc --hhvm --hhvm=off --pagespeed --pagespeed=off --experimenal --wpredis"
+ retlist="--password --php --mysql --wp --wpsubdir --wpsubdomain --w3tc --wpfc --wpsc --hhvm --hhvm=off --pagespeed --pagespeed=off --experimenal --wpredis --letsencrypt --letsencrypt=off --letsencrypt=renew"
else
retlist=""
fi
@@ -320,7 +320,7 @@ _ee_complete()
elif [ ${COMP_WORDS[2]} == "delete" ]; then
retlist="--db --files --force"
elif [ ${COMP_WORDS[2]} == "update" ]; then
- retlist="--password --php --mysql --wp --wpsubdir --wpsubdomain --w3tc --wpfc --wpsc --hhvm --hhvm=off --pagespeed --pagespeed=off --wpredis"
+ retlist="--password --php --mysql --wp --wpsubdir --wpsubdomain --w3tc --wpfc --wpsc --hhvm --hhvm=off --pagespeed --pagespeed=off --wpredis --letsencrypt --letsencrypt=off --letsencrypt=renew"
else
retlist=""
fi
@@ -369,7 +369,7 @@ _ee_complete()
case "$mprev" in
"--user" | "--email" | "--pass")
if [ ${COMP_WORDS[2]} == "create" ]; then
- retlist="--user --pass --email --html --php --mysql --wp --wpsubdir --wpsubdomain --w3tc --wpfc --wpsc --hhvm --pagespeed --wpredis"
+ retlist="--user --pass --email --html --php --mysql --wp --wpsubdir --wpsubdomain --w3tc --wpfc --wpsc --hhvm --pagespeed --wpredis --letsencrypt"
fi
ret="${retlist[@]/$prev}"
COMPREPLY=( $(compgen \
diff --git a/docs/ee.8 b/docs/ee.8
index 7b5d0658..d437fb81 100644
--- a/docs/ee.8
+++ b/docs/ee.8
@@ -5,15 +5,15 @@
.SH SYNOPSIS
ee [ --version | --help | info | stack | site | debug | update | clean | import_slow_log | log | secure | sync]
.TP
-ee stack [ install | remove | purge | migrate | upgrade] [ --web | --mail | --all | --nginx | --php | --mysql | --admin | --postfix | --mailscanner | --adminer | --redis | --hhvm | --phpmyadmin | --phpredisadmin | --wpcli | --utils ]
+ee stack [ install | remove | purge | migrate | upgrade] [ --web | --mail | --all | --nginx | --nginxmainline | --php | --mysql | --admin | --postfix | --mailscanner | --adminer | --redis | --hhvm | --phpmyadmin | --phpredisadmin | --wpcli | --utils ]
.TP
ee stack [ status | start | stop | reload | restart ] [--all | --nginx | --php | --mysql | --devcot | --web | --postfix | --memcache | --redis]
.TP
ee site [ list | info | show | enable | disable | edit | cd | show ] [ example.com ]
.TP
-ee site create example.com [ --html | --php | --mysql] [[--wp | --wpsubdir | --wpsubdomain ] [--wpsc | --w3tc | --wpfc | --wpredis | --hhvm | --pagespeed ]]
+ee site create example.com [ --html | --php | --mysql] [[--wp | --wpsubdir | --wpsubdomain ] [--wpsc | --w3tc | --wpfc | --wpredis | --hhvm | --pagespeed | --letsencrypt/-le]]
.TP
-ee site update example.com [ --php | --mysql] [[--wp | --wpsubdir | --wpsubdomain ] [--wpsc | --w3tc | --wpfc | --wpredis | --hhvm | --pagespeed ] [--password]]
+ee site update example.com [ --php | --mysql] [[--wp | --wpsubdir | --wpsubdomain ] [--wpsc | --w3tc | --wpfc | --wpredis | --hhvm | --pagespeed ] [--password] [--letsencrypt=on/off/renew]]
.TP
ee site delete example.com [--db | --files | --all | --no-prompt | --force/-f ]
.TP
@@ -307,12 +307,12 @@ Report bugs at
.B Harshad
.I \
.br
-.B Shital
-.I \
-.br
.B Prabuddha
.I \
.br
+.B Shital
+.I \
+.br
.B Rajdeep Sharma
.I \
.br
diff --git a/ee/cli/plugins/secure.py b/ee/cli/plugins/secure.py
index ee1f069f..b10b09a6 100644
--- a/ee/cli/plugins/secure.py
+++ b/ee/cli/plugins/secure.py
@@ -1,5 +1,6 @@
from cement.core.controller import CementBaseController, expose
from cement.core import handler, hook
+from ee.core.aptget import EEAptGet
from ee.core.shellexec import EEShellExec
from ee.core.variables import EEVariables
from ee.core.logging import Log
@@ -95,14 +96,16 @@ class EESecureController(CementBaseController):
self.app.pargs.user_input = port
if EEVariables.ee_platform_distro == 'ubuntu':
EEShellExec.cmd_exec(self, "sed -i \"s/listen.*/listen "
- "{port} default_server ssl spdy;/\" "
+ "{port} default_server ssl {http2};/\" "
"/etc/nginx/sites-available/22222"
- .format(port=self.app.pargs.user_input))
+ .format(port=self.app.pargs.user_input,http2=("http2" if
+ EEAptGet.is_installed(self,'nginx-mainline') else "spdy")))
if EEVariables.ee_platform_distro == 'debian':
EEShellExec.cmd_exec(self, "sed -i \"s/listen.*/listen "
- "{port} default_server ssl;/\" "
+ "{port} default_server ssl {http2};/\" "
"/etc/nginx/sites-available/22222"
- .format(port=self.app.pargs.user_input))
+ .format(port=self.app.pargs.user_input,http2=("http2" if
+ EEAptGet.is_installed(self,'nginx-mainline') else "spdy")))
EEGit.add(self, ["/etc/nginx"],
msg="Adding changed secure port into Git")
if not EEService.reload_service(self, 'nginx'):
diff --git a/ee/cli/plugins/site.py b/ee/cli/plugins/site.py
index 45c8709c..1be91214 100644
--- a/ee/cli/plugins/site.py
+++ b/ee/cli/plugins/site.py
@@ -1,6 +1,8 @@
# """EasyEngine site controller."""
from cement.core.controller import CementBaseController, expose
from cement.core import handler, hook
+from ee.core.cron import EECron
+from ee.core.sslutils import SSL
from ee.core.variables import EEVariables
from ee.core.domainvalidate import ValidateDomain
from ee.core.fileutils import EEFileUtils
@@ -155,11 +157,18 @@ class EESiteController(CementBaseController):
ee_site_webroot = ''
pagespeed = ("enabled" if siteinfo.is_pagespeed else "disabled")
-
+ ssl = ("enabled" if siteinfo.is_ssl else "disabled")
+ if (ssl == "enabled"):
+ sslprovider = "Lets Encrypt"
+ sslexpiry = str(SSL.getExpirationDate(self,ee_domain))
+ else:
+ sslprovider = ''
+ sslexpiry = ''
data = dict(domain=ee_domain, webroot=ee_site_webroot,
accesslog=access_log, errorlog=error_log,
dbname=ee_db_name, dbuser=ee_db_user,
dbpass=ee_db_pass, hhvm=hhvm, pagespeed=pagespeed,
+ ssl=ssl, sslprovider=sslprovider, sslexpiry= sslexpiry,
type=sitetype + " " + cachetype + " ({0})"
.format("enabled" if siteinfo.is_enabled else
"disabled"))
@@ -354,6 +363,8 @@ class EESiteCreateController(CementBaseController):
dict(help="create HHVM site", action='store_true')),
(['--pagespeed'],
dict(help="create pagespeed site", action='store_true')),
+ (['-le','--letsencrypt'],
+ dict(help="configure letsencrypt ssl for the site", action='store_true')),
(['--user'],
dict(help="provide user for wordpress site")),
(['--email'],
@@ -717,6 +728,58 @@ class EESiteCreateController(CementBaseController):
Log.error(self, "Check logs for reason "
"`tail /var/log/ee/ee.log` & Try Again!!!")
+ if self.app.pargs.letsencrypt :
+ if (not self.app.pargs.experimental):
+ if stype in ['wpsubdomain']:
+ Log.warn(self, "Wildcard domains are not supported in Lets Encrypt.\nWP SUBDOMAIN site will get SSL for primary site only.")
+
+ Log.info(self, "Letsencrypt is currently in beta phase."
+ " \nDo you wish"
+ " to enable SSl now for {0}?".format(ee_domain))
+
+ # Check prompt
+ check_prompt = input("Type \"y\" to continue [n]:")
+ if check_prompt != "Y" and check_prompt != "y":
+ data['letsencrypt'] = False
+ letsencrypt = False
+ else:
+ data['letsencrypt'] = True
+ letsencrypt = True
+ else:
+ data['letsencrypt'] = True
+ letsencrypt = True
+
+ if data['letsencrypt'] is True:
+ setupLetsEncrypt(self, ee_domain)
+ httpsRedirect(self,ee_domain)
+ Log.info(self,"Creating Cron Job for cert auto-renewal")
+ EECron.setcron_daily(self,'ee site update {0} --le=renew --min_expiry_limit 30 2> /dev/null'.format(ee_domain),'Renew '
+ 'letsencrypt SSL cert. Set by EasyEngine')
+
+ if not EEService.reload_service(self, 'nginx'):
+ Log.error(self, "service nginx reload failed. "
+ "check issues with `nginx -t` command")
+
+ Log.info(self, "Congratulations! Successfully Configured SSl for Site "
+ " https://{0}".format(ee_domain))
+
+ if (SSL.getExpirationDays(self,ee_domain)>0):
+ Log.info(self, "Your cert will expire within " + str(SSL.getExpirationDays(self,ee_domain)) + " days.")
+ else:
+ Log.warn(self, "Your cert already EXPIRED ! .PLEASE renew soon . ")
+
+ # Add nginx conf folder into GIT
+ EEGit.add(self, ["{0}/conf/nginx".format(ee_site_webroot)],
+ msg="Adding letsencrypts config of site: {0}"
+ .format(ee_domain))
+ updateSiteInfo(self, ee_domain, ssl=letsencrypt)
+
+ elif data['letsencrypt'] is False:
+ Log.info(self, "Not using Let\'s encrypt for Site "
+ " http://{0}".format(ee_domain))
+
+
+
class EESiteUpdateController(CementBaseController):
class Meta:
@@ -761,6 +824,12 @@ class EESiteUpdateController(CementBaseController):
dict(help='Use PageSpeed for site',
action='store' or 'store_const',
choices=('on', 'off'), const='on', nargs='?')),
+ (['-le','--letsencrypt'],
+ dict(help="configure letsencrypt ssl for the site",
+ action='store' or 'store_const',
+ choices=('on', 'off', 'renew'), const='on', nargs='?')),
+ (['--min_expiry_limit'],
+ dict(help="pass minimum expiry days to renew let's encrypt cert")),
(['--proxy'],
dict(help="update to proxy site", nargs='+')),
(['--experimental'],
@@ -784,7 +853,7 @@ class EESiteUpdateController(CementBaseController):
if not (pargs.php or
pargs.mysql or pargs.wp or pargs.wpsubdir or
pargs.wpsubdomain or pargs.w3tc or pargs.wpfc or
- pargs.wpsc or pargs.hhvm or pargs.pagespeed or pargs.wpredis):
+ pargs.wpsc or pargs.hhvm or pargs.pagespeed or pargs.wpredis or pargs.letsencrypt):
Log.error(self, "Please provide options to update sites.")
if pargs.all:
@@ -809,6 +878,7 @@ class EESiteUpdateController(CementBaseController):
def doupdatesite(self, pargs):
hhvm = None
pagespeed = None
+ letsencrypt = False
data = dict()
try:
@@ -826,7 +896,7 @@ class EESiteUpdateController(CementBaseController):
proxyinfo = proxyinfo.split(':')
host = proxyinfo[0].strip()
port = '80' if len(proxyinfo) < 2 else proxyinfo[1].strip()
- elif stype is None and not pargs.proxy:
+ elif stype is None and not (pargs.proxy or pargs.letsencrypt):
stype, cache = 'html', 'basic'
elif stype and pargs.proxy:
Log.error(self, "--proxy can not be used with other site types")
@@ -854,6 +924,7 @@ class EESiteUpdateController(CementBaseController):
oldcachetype = check_site.cache_type
old_hhvm = check_site.is_hhvm
old_pagespeed = check_site.is_pagespeed
+ check_ssl = check_site.is_ssl
if (pargs.password and not (pargs.html or
pargs.php or pargs.mysql or pargs.wp or
@@ -1007,6 +1078,7 @@ class EESiteUpdateController(CementBaseController):
data['pagespeed'] = False
pagespeed = False
+
if pargs.pagespeed:
if pagespeed is old_pagespeed:
if pagespeed is False:
@@ -1017,6 +1089,66 @@ class EESiteUpdateController(CementBaseController):
"site")
pargs.pagespeed = False
+ #--letsencrypt=renew code goes here
+ if pargs.letsencrypt == "renew" and not pargs.min_expiry_limit:
+ if check_ssl:
+ renewLetsEncrypt(self,ee_domain)
+ else:
+ Log.error(self,"Cannot RENEW ! SSL is not configured for given site .")
+
+ Log.info(self, "SUCCESS: Certificate was successfully renewed For"
+ " https://{0}".format(ee_domain))
+ if (SSL.getExpirationDays(self,ee_domain)>0):
+ Log.info(self, "Your cert will expire within " + str(SSL.getExpirationDays(self,ee_domain)) + " days.")
+ Log.info(self, "Expiration DATE: " + str(SSL.getExpirationDate(self,ee_domain)))
+
+ else:
+ Log.warn(self, "Your cert already EXPIRED ! .PLEASE renew soon . ")
+
+ if pargs.min_expiry_limit:
+ if not int(pargs.min_expiry_limit)>0 or not int(pargs.min_expiry_limit)< 90:
+ Log.error(self,'INVALID --min_expiry_limit argument provided. Please use range 1-89 .')
+
+ if not pargs.letsencrypt == "renew":
+ Log.error(self,'--min_expiry_limit parameter cannot be used as a standalone. Provide --le=renew')
+
+ if not check_ssl:
+ Log.error(self,"Cannot RENEW ! SSL is not configured for given site .")
+
+ expiry_days = SSL.getExpirationDays(self,ee_domain)
+ min_expiry_days = int(pargs.min_expiry_limit)
+ if (expiry_days <= min_expiry_days):
+ renewLetsEncrypt(self,ee_domain)
+ Log.info(self, "SUCCESS: Certificate was successfully renewed For"
+ " https://{0}".format(ee_domain))
+ else:
+ Log.info(self, "Not renewing SSL .")
+
+ if (SSL.getExpirationDays(self,ee_domain)>0):
+ Log.info(self, "Your cert will expire within " + str(SSL.getExpirationDays(self,ee_domain)) + " days.")
+ Log.info(self, "Expiration DATE: " + str(SSL.getExpirationDate(self,ee_domain)))
+
+ else:
+ Log.warn(self, "Your cert already EXPIRED ! .PLEASE renew soon . ")
+ return 0
+
+ if pargs.letsencrypt:
+ if pargs.letsencrypt == 'on':
+ data['letsencrypt'] = True
+ letsencrypt = True
+ elif pargs.letsencrypt == 'off':
+ data['letsencrypt'] = False
+ letsencrypt = False
+
+ if letsencrypt is check_ssl:
+ if letsencrypt is False:
+ Log.error(self, "SSl is not configured for given "
+ "site")
+ elif letsencrypt is True:
+ Log.error(self, "SSl is already configured for given "
+ "site")
+ pargs.letsencrypt = False
+
if pargs.hhvm:
if hhvm is old_hhvm:
if hhvm is False:
@@ -1044,7 +1176,7 @@ class EESiteUpdateController(CementBaseController):
data['pagespeed'] = False
pagespeed = False
- if pargs.pagespeed=="on" or pargs.hhvm=="on":
+ if pargs.pagespeed=="on" or pargs.hhvm=="on" or pargs.letsencrypt=="on":
if pargs.hhvm == "on":
if (not pargs.experimental):
Log.info(self, "HHVM is experimental feature and it may not"
@@ -1085,7 +1217,33 @@ class EESiteUpdateController(CementBaseController):
data['pagespeed'] = True
pagespeed = True
- if data['currcachetype'] != 'wpredis' and pargs.wpredis:
+ if pargs.letsencrypt == "on":
+
+ if (not pargs.experimental):
+
+ if oldsitetype in ['wpsubdomain']:
+ Log.warn(self, "Wildcard domains are not supported in Lets Encrypt.\nWP SUBDOMAIN site will get SSL for primary site only.")
+
+ Log.info(self, "Letsencrypt is currently in beta phase."
+ " \nDo you wish"
+ " to enable SSl now for {0}?".format(ee_domain))
+
+ # Check prompt
+ check_prompt = input("Type \"y\" to continue [n]:")
+ if check_prompt != "Y" and check_prompt != "y":
+ Log.info(self, "Not using letsencrypt for site")
+ data['letsencrypt'] = False
+ letsencrypt = False
+ else:
+ data['letsencrypt'] = True
+ letsencrypt = True
+ else:
+ data['letsencrypt'] = True
+ letsencrypt = True
+
+
+
+ if pargs.wpredis and data['currcachetype'] != 'wpredis':
if (not pargs.experimental):
Log.info(self, "Redis is experimental feature and it may not"
" work with all plugins of your site.\nYou can "
@@ -1113,32 +1271,32 @@ class EESiteUpdateController(CementBaseController):
data['ee_db_user'] = check_site.db_user
data['ee_db_pass'] = check_site.db_password
data['ee_db_host'] = check_site.db_host
-
- try:
- pre_run_checks(self)
- except SiteError as e:
- Log.debug(self, str(e))
- Log.error(self, "NGINX configuration check failed.")
-
data['old_pagespeed_status'] = check_site.is_pagespeed
- try:
- sitebackup(self, data)
- except Exception as e:
- Log.debug(self, str(e))
- Log.info(self, Log.FAIL + "Check logs for reason "
+ if not pargs.letsencrypt:
+ try:
+ pre_run_checks(self)
+ except SiteError as e:
+ Log.debug(self, str(e))
+ Log.error(self, "NGINX configuration check failed.")
+
+ try:
+ sitebackup(self, data)
+ except Exception as e:
+ Log.debug(self, str(e))
+ Log.info(self, Log.FAIL + "Check logs for reason "
"`tail /var/log/ee/ee.log` & Try Again!!!")
- return 1
+ return 1
- # setup NGINX configuration, and webroot
- try:
- setupdomain(self, data)
- except SiteError as e:
- Log.debug(self, str(e))
- Log.info(self, Log.FAIL + "Update site failed."
+ # setup NGINX configuration, and webroot
+ try:
+ setupdomain(self, data)
+ except SiteError as e:
+ Log.debug(self, str(e))
+ Log.info(self, Log.FAIL + "Update site failed."
"Check logs for reason"
"`tail /var/log/ee/ee.log` & Try Again!!!")
- return 1
+ return 1
if 'proxy' in data.keys() and data['proxy']:
updateSiteInfo(self, ee_domain, stype=stype, cache=cache,
@@ -1151,6 +1309,60 @@ class EESiteUpdateController(CementBaseController):
if pargs.pagespeed:
operateOnPagespeed(self, data)
+ if pargs.letsencrypt:
+ if data['letsencrypt'] is True:
+ if not os.path.isfile("{0}/conf/nginx/ssl.conf.disabled"
+ .format(ee_site_webroot)):
+ setupLetsEncrypt(self, ee_domain)
+
+ else:
+ EEFileUtils.mvfile(self, "{0}/conf/nginx/ssl.conf.disabled"
+ .format(ee_site_webroot),
+ '{0}/conf/nginx/ssl.conf'
+ .format(ee_site_webroot))
+
+ httpsRedirect(self,ee_domain)
+ Log.info(self,"Creating Cron Job for cert auto-renewal")
+ EECron.setcron_daily(self,'ee site update {0} --le=renew --min_expiry_limit 30 2> /dev/null'.format(ee_domain),'Renew'
+ ' letsencrypt SSL cert. Set by EasyEngine')
+
+ if not EEService.reload_service(self, 'nginx'):
+ Log.error(self, "service nginx reload failed. "
+ "check issues with `nginx -t` command")
+
+ Log.info(self, "Congratulations! Successfully Configured SSl for Site "
+ " https://{0}".format(ee_domain))
+
+ if (SSL.getExpirationDays(self,ee_domain)>0):
+ Log.info(self, "Your cert will expire within " + str(SSL.getExpirationDays(self,ee_domain)) + " days.")
+ else:
+ Log.warn(self, "Your cert already EXPIRED ! .PLEASE renew soon . ")
+
+ elif data['letsencrypt'] is False:
+ if os.path.isfile("{0}/conf/nginx/ssl.conf"
+ .format(ee_site_webroot)):
+ Log.info(self,'Setting Nginx configuration')
+ EEFileUtils.mvfile(self, "{0}/conf/nginx/ssl.conf"
+ .format(ee_site_webroot),
+ '{0}/conf/nginx/ssl.conf.disabled'
+ .format(ee_site_webroot))
+ httpsRedirect(self,ee_domain,False)
+ if not EEService.reload_service(self, 'nginx'):
+ Log.error(self, "service nginx reload failed. "
+ "check issues with `nginx -t` command")
+ Log.info(self,"Removing Cron Job set for cert auto-renewal")
+ EECron.remove_cron(self,'ee site update {0} --le=renew --min_expiry_limit 30 2> \/dev\/null'.format(ee_domain))
+ Log.info(self, "Successfully Disabled SSl for Site "
+ " http://{0}".format(ee_domain))
+
+
+ # Add nginx conf folder into GIT
+ EEGit.add(self, ["{0}/conf/nginx".format(ee_site_webroot)],
+ msg="Adding letsencrypts config of site: {0}"
+ .format(ee_domain))
+ updateSiteInfo(self, ee_domain, ssl=letsencrypt)
+ return 0
+
if stype == oldsitetype and cache == oldcachetype:
# Service Nginx Reload
diff --git a/ee/cli/plugins/site_functions.py b/ee/cli/plugins/site_functions.py
index 8ce33970..68b5a536 100644
--- a/ee/cli/plugins/site_functions.py
+++ b/ee/cli/plugins/site_functions.py
@@ -2,11 +2,13 @@ from ee.cli.plugins.stack import EEStackController
from ee.core.fileutils import EEFileUtils
from ee.core.mysql import *
from ee.core.shellexec import *
+from ee.core.sslutils import SSL
from ee.core.variables import EEVariables
from ee.cli.plugins.sitedb import *
from ee.core.aptget import EEAptGet
from ee.core.git import EEGit
from ee.core.logging import Log
+from ee.core.sendmail import EESendMail
from ee.core.services import EEService
import subprocess
from subprocess import CalledProcessError
@@ -676,7 +678,7 @@ def site_package_check(self, stype):
Log.debug(self, "Setting apt_packages variable for Nginx")
# Check if server has nginx-custom package
- if not EEAptGet.is_installed(self, 'nginx-custom'):
+ if not (EEAptGet.is_installed(self, 'nginx-custom') or EEAptGet.is_installed(self, 'nginx-mainline')):
# check if Server has nginx-plus installed
if EEAptGet.is_installed(self, 'nginx-plus'):
# do something
@@ -1181,3 +1183,156 @@ def operateOnPagespeed(self, data):
EEGit.add(self, ["{0}/conf/nginx".format(ee_site_webroot)],
msg="Adding Pagespeed config of site: {0}"
.format(ee_domain_name))
+
+def cloneLetsEncrypt(self):
+ letsencrypt_repo = "https://github.com/letsencrypt/letsencrypt"
+
+ try:
+ Log.info(self, "Downloading {0:20}".format("LetsEncrypt"), end=' ')
+ EEFileUtils.chdir(self, '/opt/')
+ EEShellExec.cmd_exec(self, "git clone {0}".format(letsencrypt_repo))
+ Log.info(self, "{0}".format("[" + Log.ENDC + "Done"
+ + Log.OKBLUE + "]"))
+ return True
+ except Exception as e:
+ Log.debug(self, "[{err}]".format(err=str(e.reason)))
+ Log.error(self, "Unable to download file, LetsEncrypt")
+ return False
+
+def setupLetsEncrypt(self, ee_domain_name):
+ ee_wp_email = EEVariables.ee_email
+ while not ee_wp_email:
+ try:
+ ee_wp_email = input('Enter WordPress email: ')
+ except EOFError as e:
+ Log.debug(self, "{0}".format(e))
+ raise SiteError("input wordpress username failed")
+
+ if not os.path.isdir("/opt/letsencrypt"):
+ cloneLetsEncrypt(self)
+ EEFileUtils.chdir(self, '/opt/letsencrypt')
+ EEShellExec.cmd_exec(self, "git pull")
+
+ ssl = EEShellExec.cmd_exec(self, "./letsencrypt-auto certonly --webroot -w /var/www/{0}/htdocs/ -d {0} -d www.{0} "
+ .format(ee_domain_name)
+ + "--email {0} --text --agree-tos".format(ee_wp_email))
+ if ssl:
+ Log.info(self, "Let's Encrypt successfully setup for your site")
+ Log.info(self, "Your certificate and chain have been saved at "
+ "/etc/letsencrypt/live/{0}/fullchain.pem".format(ee_domain_name))
+ Log.info(self, "Configuring Nginx SSL configuration")
+
+ try:
+ Log.info(self, "Adding /var/www/{0}/conf/nginx/ssl.conf".format(ee_domain_name))
+
+ sslconf = open("/var/www/{0}/conf/nginx/ssl.conf"
+ .format(ee_domain_name),
+ encoding='utf-8', mode='w')
+ sslconf.write("listen 443 ssl {http2};\n".format(http2=("http2" if
+ EEAptGet.is_installed(self,'nginx-mainline') else "spdy")) +
+ "ssl on;\n"
+ "ssl_certificate /etc/letsencrypt/live/{0}/fullchain.pem;\n"
+ "ssl_certificate_key /etc/letsencrypt/live/{0}/privkey.pem;\n"
+ .format(ee_domain_name))
+ sslconf.close()
+ # updateSiteInfo(self, ee_domain_name, ssl=True)
+
+ EEGit.add(self, ["/etc/letsencrypt"],
+ msg="Adding letsencrypt folder")
+
+ except IOError as e:
+ Log.debug(self, str(e))
+ Log.debug(self, "Error occured while generating "
+ "ssl.conf")
+ else:
+ Log.error(self, "Unable to setup, Let\'s Encrypt", False)
+ Log.error(self, "Please make sure that your site is pointed to \n"
+ "same server on which you are running Let\'s Encrypt Client "
+ "\n to allow it to verify the site automatically.")
+
+def renewLetsEncrypt(self, ee_domain_name):
+
+ ee_wp_email = EEVariables.ee_email
+ while not ee_wp_email:
+ try:
+ ee_wp_email = input('Enter email address: ')
+ except EOFError as e:
+ Log.debug(self, "{0}".format(e))
+ raise SiteError("Input wordpress email failed")
+
+ if not os.path.isdir("/opt/letsencrypt"):
+ cloneLetsEncrypt(self)
+ EEFileUtils.chdir(self, '/opt/letsencrypt')
+ EEShellExec.cmd_exec(self, "git pull")
+
+ Log.info(self, "Renewing SSl cert for https://{0}".format(ee_domain_name))
+
+ ssl = EEShellExec.cmd_exec(self, "./letsencrypt-auto --renew certonly --webroot -w /var/www/{0}/htdocs/ -d {0} -d www.{0} "
+ .format(ee_domain_name)
+ + "--email {0} --text --agree-tos".format(ee_wp_email))
+ mail_list = ''
+ if not ssl:
+ Log.error(self,"ERROR : Cannot RENEW SSL cert !",False)
+ if (SSL.getExpirationDays(self,ee_domain_name)>0):
+ Log.error(self, "Your current cert will expire within " + str(SSL.getExpirationDays(self,ee_domain_name)) + " days.",False)
+ else:
+ Log.error(self, "Your current cert already EXPIRED !",False)
+
+ EESendMail("easyengine@{0}".format(ee_domain_name), ee_wp_email, "[FAIL] SSL cert renewal {0}".format(ee_domain_name),
+ "Hey Hi,\n\nSSL Certificate renewal for https://{0} was unsuccessful.".format(ee_domain_name) +
+ "\nPlease check easyengine log for reason. Your SSL Expiry date : " +
+ str(SSL.getExpirationDate(self,ee_domain_name)) +
+ "\n\nFor support visit https://easyengine.io/support/ .\n\nYour's faithfully,\nEasyEngine",files=mail_list,
+ port=25, isTls=False)
+ Log.error(self, "Check logs for reason "
+ "`tail /var/log/ee/ee.log` & Try Again!!!")
+
+ EEGit.add(self, ["/etc/letsencrypt"],
+ msg="Adding letsencrypt folder")
+ EESendMail("easyengine@{0}".format(ee_domain_name), ee_wp_email, "[SUCCESS] SSL cert renewal {0}".format(ee_domain_name),
+ "Hey Hi,\n\nYour SSL Certificate has been renewed for https://{0} .".format(ee_domain_name) +
+ "\nYour SSL will Expire on : " +
+ str(SSL.getExpirationDate(self,ee_domain_name)) +
+ "\n\nYour's faithfully,\nEasyEngine",files=mail_list,
+ port=25, isTls=False)
+
+#redirect= False to disable https redirection
+def httpsRedirect(self,ee_domain_name,redirect=True):
+ if redirect:
+ if os.path.isfile("/etc/nginx/conf.d/force-ssl-{0}.conf.disabled".format(ee_domain_name)):
+ EEFileUtils.mvfile(self, "/etc/nginx/conf.d/force-ssl-{0}.conf.disabled".format(ee_domain_name),
+ "/etc/nginx/conf.d/force-ssl-{0}.conf".format(ee_domain_name))
+ else:
+ try:
+ Log.info(self, "Adding /etc/nginx/conf.d/force-ssl-{0}.conf".format(ee_domain_name))
+
+ sslconf = open("/etc/nginx/conf.d/force-ssl-{0}.conf"
+ .format(ee_domain_name),
+ encoding='utf-8', mode='w')
+ sslconf.write("server {\n"
+ "\tlisten 80;\n" +
+ "\tserver_name www.{0} {0};\n".format(ee_domain_name) +
+ "\treturn 301 https://{0}".format(ee_domain_name)+"$request_uri;\n}" )
+ sslconf.close()
+ # Nginx Configation into GIT
+ except IOError as e:
+ Log.debug(self, str(e))
+ Log.debug(self, "Error occured while generating "
+ "/etc/nginx/conf.d/force-ssl-{0}.conf".format(ee_domain_name))
+
+ Log.info(self, "Added HTTPS Force Redirection for Site "
+ " http://{0}".format(ee_domain_name))
+ EEGit.add(self,
+ ["/etc/nginx"], msg="Adding /etc/nginx/conf.d/force-ssl-{0}.conf".format(ee_domain_name))
+ else:
+ if os.path.isfile("/etc/nginx/conf.d/force-ssl-{0}.conf".format(ee_domain_name)):
+ EEFileUtils.mvfile(self, "/etc/nginx/conf.d/force-ssl-{0}.conf".format(ee_domain_name),
+ "/etc/nginx/conf.d/force-ssl-{0}.conf.disabled".format(ee_domain_name))
+ Log.info(self, "Disabled HTTPS Force Redirection for Site "
+ " http://{0}".format(ee_domain_name))
+
+
+
+
+
+
diff --git a/ee/cli/plugins/sitedb.py b/ee/cli/plugins/sitedb.py
index c81b1249..4fc3fd35 100644
--- a/ee/cli/plugins/sitedb.py
+++ b/ee/cli/plugins/sitedb.py
@@ -63,7 +63,7 @@ def updateSiteInfo(self, site, stype='', cache='', webroot='',
if q.is_enabled != enabled:
q.is_enabled = enabled
- if ssl and q.is_ssl != ssl:
+ if q.is_ssl != ssl:
q.is_ssl = ssl
if db_name and q.db_name != db_name:
diff --git a/ee/cli/plugins/stack.py b/ee/cli/plugins/stack.py
index 6564fd9f..60a3349a 100644
--- a/ee/cli/plugins/stack.py
+++ b/ee/cli/plugins/stack.py
@@ -2,6 +2,7 @@
from cement.core.controller import CementBaseController, expose
from cement.core import handler, hook
+from ee.cli.plugins.site_functions import *
from ee.core.variables import EEVariables
from ee.core.aptget import EEAptGet
from ee.core.download import EEDownload
@@ -30,6 +31,7 @@ from ee.cli.plugins.stack_services import EEStackStatusController
from ee.cli.plugins.stack_migrate import EEStackMigrateController
from ee.cli.plugins.stack_upgrade import EEStackUpgradeController
from ee.core.logging import Log
+from ee.cli.plugins.sitedb import *
def ee_stack_hook(app):
@@ -56,6 +58,8 @@ class EEStackController(CementBaseController):
dict(help='Install mail scanner stack', action='store_true')),
(['--nginx'],
dict(help='Install Nginx stack', action='store_true')),
+ (['--nginxmainline'],
+ dict(help='Install Nginx mainline stack', action='store_true')),
(['--php'],
dict(help='Install PHP stack', action='store_true')),
(['--mysql'],
@@ -168,6 +172,12 @@ class EEStackController(CementBaseController):
Log.debug(self, 'Adding ppa of Nginx')
EERepo.add_key(self, EEVariables.ee_nginx_key)
+ if set(["nginx-mainline"]).issubset(set(apt_packages)):
+ Log.info(self, "Adding repository for NGINX MAINLINE, please wait...")
+ EERepo.add(self, repo_url=EEVariables.ee_nginx_dev_repo)
+ Log.debug(self, 'Adding ppa of Nginx-mainline')
+ EERepo.add_key(self, EEVariables.ee_nginx_key)
+
if set(EEVariables.ee_php).issubset(set(apt_packages)):
Log.info(self, "Adding repository for PHP, please wait...")
# Add repository for php
@@ -223,7 +233,8 @@ class EEStackController(CementBaseController):
msg="Adding Postfix into Git")
EEService.reload_service(self, 'postfix')
- if set(EEVariables.ee_nginx).issubset(set(apt_packages)):
+ if set(EEVariables.ee_nginx).issubset(set(apt_packages)) or set(EEVariables.ee_nginx_dev)\
+ .issubset(set(apt_packages)) :
if set(["nginx-plus"]).issubset(set(apt_packages)):
# Fix for white screen death with NGINX PLUS
if not EEFileUtils.grep(self, '/etc/nginx/fastcgi_params',
@@ -233,6 +244,26 @@ class EEStackController(CementBaseController):
ee_nginx.write('fastcgi_param \tSCRIPT_FILENAME '
'\t$request_filename;\n')
+ if os.path.isfile('/etc/nginx/sites-available/22222'):
+ http2 = "http2" if EEAptGet.is_installed(self,'nginx-mainline') else "spdy"
+ if not EEShellExec.cmd_exec(self, "grep -q \'{http2}\' /etc/nginx/sites-available/22222".format(http2=http2)):
+ Log.debug(self, 'Setting http2/spdy in 22222')
+ EEShellExec.cmd_exec(self, "sed -i 's/http2\|spdy/{0}/g' /etc/nginx/sites-available/22222".format(http2))
+
+ sites = getAllsites(self)
+ if sites:
+ for site in sites:
+ site_name = site.sitename
+ siteinfo = getSiteInfo(self, site_name)
+ ssl = ("enabled" if siteinfo.is_ssl else "disabled")
+ if (ssl == "enabled"):
+ if os.path.isfile('/var/www/{0}/conf/nginx/ssl.conf'.format(site_name)):
+ http2 =("http2" if EEAptGet.is_installed(self,'nginx-mainline') else "spdy")
+ if not EEShellExec.cmd_exec(self, "grep -q \'{http2}\' /var/www/{site}/conf/nginx/ssl.conf".format(http2=http2,site=site_name)):
+ Log.debug(self, 'Modifying http2/spdy parameter in /var/www/{0}/conf/nginx/ssl.conf'.format(site_name))
+ EEShellExec.cmd_exec(self, "sed -i 's/http2\|spdy/{http2}/g' /var/www/{site}/conf/nginx/ssl.conf".format(http2=http2,site=site_name))
+
+
if not (os.path.isfile('/etc/nginx/common/wpfc.conf')):
# Change EasyEngine Version in nginx.conf file
EEFileUtils.searchreplace(self, "/etc/nginx/nginx.conf",
@@ -273,7 +304,8 @@ class EEStackController(CementBaseController):
'/etc/nginx/common')
os.makedirs('/etc/nginx/common')
- data = dict(webroot=EEVariables.ee_webroot)
+ http2 = ("http2" if set(["nginx-mainline"]).issubset(set(apt_packages)) else "spdy")
+ data = dict(webroot=EEVariables.ee_webroot,http2=http2)
Log.debug(self, 'Writting the nginx configuration to '
'file /etc/nginx/common/acl.conf')
ee_nginx = open('/etc/nginx/common/acl.conf',
@@ -339,7 +371,7 @@ class EEStackController(CementBaseController):
ee_nginx.close()
# Nginx-Plus does not have nginx package structure like this
- # So craeting directories
+ # So creating directories
if set(["nginx-plus"]).issubset(set(apt_packages)):
Log.info(self,
"Installing EasyEngine Configurations for" "NGINX PLUS")
@@ -483,6 +515,8 @@ class EEStackController(CementBaseController):
else:
self.msg = (self.msg + ["HTTP Auth User Name: easyengine"]
+ ["HTTP Auth Password : {0}".format(passwd)])
+ else:
+ EEService.restart_service(self, 'nginx')
if EEAptGet.is_installed(self,'redis-server'):
if os.path.isfile("/etc/nginx/nginx.conf") and (not
@@ -1576,7 +1610,7 @@ class EEStackController(CementBaseController):
and (not self.app.pargs.pagespeed) and
(not self.app.pargs.adminer) and (not self.app.pargs.utils) and
(not self.app.pargs.mailscanner) and (not self.app.pargs.all)
- and (not self.app.pargs.redis) and
+ and (not self.app.pargs.redis) and (not self.app.pargs.nginxmainline) and
(not self.app.pargs.phpredisadmin)):
self.app.pargs.web = True
self.app.pargs.admin = True
@@ -1634,7 +1668,7 @@ class EEStackController(CementBaseController):
Log.info(self, "Mail server is already installed")
if self.app.pargs.pagespeed:
- if not EEAptGet.is_installed(self, 'nginx-custom'):
+ if not (EEAptGet.is_installed(self, 'nginx-custom') or EEAptGet.is_installed(self, 'nginx-mainline')):
self.app.pargs.nginx = True
else:
Log.info(self, "Nginx already installed")
@@ -1649,7 +1683,7 @@ class EEStackController(CementBaseController):
if self.app.pargs.nginx:
Log.debug(self, "Setting apt_packages variable for Nginx")
- if not EEAptGet.is_installed(self, 'nginx-custom'):
+ if not (EEAptGet.is_installed(self, 'nginx-custom') or EEAptGet.is_installed(self, 'nginx-mainline')):
if not EEAptGet.is_installed(self, 'nginx-plus'):
apt_packages = apt_packages + EEVariables.ee_nginx
else:
@@ -1660,6 +1694,25 @@ class EEStackController(CementBaseController):
else:
Log.debug(self, "Nginx already installed")
Log.info(self, "Nginx already installed")
+
+ if self.app.pargs.nginxmainline:
+ if EEVariables.ee_nginx_dev_repo == None:
+ Log.error(self, "NGINX Mainline Version is not supported in wheezy")
+
+ Log.debug(self, "Setting apt_packages variable for Nginx")
+
+ if not (EEAptGet.is_installed(self, 'nginx-custom') or EEAptGet.is_installed(self, 'nginx-mainline')):
+ if not EEAptGet.is_installed(self, 'nginx-plus'):
+ apt_packages = apt_packages + EEVariables.ee_nginx_dev
+ else:
+ Log.info(self, "NGINX PLUS Detected ...")
+ apt = ["nginx-plus"] + EEVariables.ee_nginx
+ #apt_packages = apt_packages + EEVariables.ee_nginx
+ self.post_pref(apt, packages)
+ else:
+ Log.debug(self, "Nginx already installed")
+ Log.info(self, "Nginx already installed")
+
if self.app.pargs.php:
Log.debug(self, "Setting apt_packages variable for PHP")
if not EEAptGet.is_installed(self, 'php5-fpm'):
@@ -1856,7 +1909,7 @@ class EEStackController(CementBaseController):
(not self.app.pargs.adminer) and (not self.app.pargs.utils) and
(not self.app.pargs.mailscanner) and (not self.app.pargs.all) and
(not self.app.pargs.pagespeed) and (not self.app.pargs.redis) and
- (not self.app.pargs.phpredisadmin)):
+ (not self.app.pargs.phpredisadmin) and (not self.app.pargs.nginxmainline)):
self.app.pargs.web = True
self.app.pargs.admin = True
@@ -1897,8 +1950,17 @@ class EEStackController(CementBaseController):
packages = packages + ['/etc/nginx/conf.d/pagespeed.conf']
if self.app.pargs.nginx:
- Log.debug(self, "Removing apt_packages variable of Nginx")
- apt_packages = apt_packages + EEVariables.ee_nginx
+ if EEAptGet.is_installed(self, 'nginx-custom'):
+ Log.debug(self, "Removing apt_packages variable of Nginx")
+ apt_packages = apt_packages + EEVariables.ee_nginx
+ else:
+ Log.error(self,"Cannot Remove! Nginx Stable version not found.")
+ if self.app.pargs.nginxmainline:
+ if EEAptGet.is_installed(self, 'nginx-mainline'):
+ Log.debug(self, "Removing apt_packages variable of Nginx MAINLINE")
+ apt_packages = apt_packages + EEVariables.ee_nginx_dev
+ else:
+ Log.error(self,"Cannot Remove! Nginx Mainline version not found.")
if self.app.pargs.php:
Log.debug(self, "Removing apt_packages variable of PHP")
apt_packages = apt_packages + EEVariables.ee_php
@@ -1959,6 +2021,11 @@ class EEStackController(CementBaseController):
' operation : ')
if ee_prompt == 'YES' or ee_prompt == 'yes':
+
+ if (set(["nginx-mainline"]).issubset(set(apt_packages)) or
+ set(["nginx-custom"]).issubset(set(apt_packages))) :
+ EEService.stop_service(self, 'nginx')
+
if len(packages):
EEFileUtils.remove(self, packages)
EEAptGet.auto_remove(self)
@@ -1969,6 +2036,11 @@ class EEStackController(CementBaseController):
EEAptGet.remove(self, apt_packages)
EEAptGet.auto_remove(self)
+ if set(["nginx-mainline"]).issubset(set(apt_packages)):
+ Log.info(self, "Removing repository for NGINX MAINLINE,")
+ EERepo.remove(self, repo_url=EEVariables.ee_nginx_dev_repo)
+
+
Log.info(self, "Successfully removed packages")
@expose(help="Purge packages")
@@ -1986,7 +2058,7 @@ class EEStackController(CementBaseController):
(not self.app.pargs.adminer) and (not self.app.pargs.utils) and
(not self.app.pargs.mailscanner) and (not self.app.pargs.all) and
(not self.app.pargs.pagespeed) and (not self.app.pargs.redis) and
- (not self.app.pargs.phpredisadmin)):
+ (not self.app.pargs.phpredisadmin) and (not self.app.pargs.nginxmainline)):
self.app.pargs.web = True
self.app.pargs.admin = True
@@ -2027,8 +2099,17 @@ class EEStackController(CementBaseController):
packages = packages + ['/etc/nginx/conf.d/pagespeed.conf']
if self.app.pargs.nginx:
- Log.debug(self, "Purge apt_packages variable of Nginx")
- apt_packages = apt_packages + EEVariables.ee_nginx
+ if EEAptGet.is_installed(self, 'nginx-custom'):
+ Log.debug(self, "Purge apt_packages variable of Nginx")
+ apt_packages = apt_packages + EEVariables.ee_nginx
+ else:
+ Log.error(self,"Cannot Purge! Nginx Stable version not found.")
+ if self.app.pargs.nginxmainline:
+ if EEAptGet.is_installed(self, 'nginx-mainline'):
+ Log.debug(self, "Purge apt_packages variable of Nginx Mainline")
+ apt_packages = apt_packages + EEVariables.ee_nginx_dev
+ else:
+ Log.error(self,"Cannot Purge! Nginx Mainline version not found.")
if self.app.pargs.php:
Log.debug(self, "Purge apt_packages variable PHP")
apt_packages = apt_packages + EEVariables.ee_php
@@ -2088,6 +2169,11 @@ class EEStackController(CementBaseController):
'operation :')
if ee_prompt == 'YES' or ee_prompt == 'yes':
+
+ if (set(["nginx-mainline"]).issubset(set(apt_packages)) or
+ set(["nginx-custom"]).issubset(set(apt_packages))) :
+ EEService.stop_service(self, 'nginx')
+
if len(apt_packages):
Log.info(self, "Purging packages, please wait...")
EEAptGet.remove(self, apt_packages, purge=True)
@@ -2097,6 +2183,11 @@ class EEStackController(CementBaseController):
EEFileUtils.remove(self, packages)
EEAptGet.auto_remove(self)
+ if set(["nginx-mainline"]).issubset(set(apt_packages)):
+ Log.info(self, "Removing repository for NGINX MAINLINE,")
+ EERepo.remove(self, repo_url=EEVariables.ee_nginx_dev_repo)
+
+
Log.info(self, "Successfully purged packages")
def load(app):
diff --git a/ee/cli/plugins/stack_services.py b/ee/cli/plugins/stack_services.py
index 75b53646..45a947bf 100644
--- a/ee/cli/plugins/stack_services.py
+++ b/ee/cli/plugins/stack_services.py
@@ -33,7 +33,7 @@ class EEStackStatusController(CementBaseController):
self.app.pargs.postfix = True
if self.app.pargs.nginx:
- if EEAptGet.is_installed(self, 'nginx-custom'):
+ if EEAptGet.is_installed(self, 'nginx-custom') or EEAptGet.is_installed(self,'nginx-mainline'):
services = services + ['nginx']
else:
Log.info(self, "Nginx is not installed")
@@ -104,7 +104,7 @@ class EEStackStatusController(CementBaseController):
self.app.pargs.postfix = True
if self.app.pargs.nginx:
- if EEAptGet.is_installed(self, 'nginx-custom'):
+ if EEAptGet.is_installed(self, 'nginx-custom') or EEAptGet.is_installed(self,'nginx-mainline'):
services = services + ['nginx']
else:
Log.info(self, "Nginx is not installed")
@@ -175,7 +175,7 @@ class EEStackStatusController(CementBaseController):
self.app.pargs.postfix = True
if self.app.pargs.nginx:
- if EEAptGet.is_installed(self, 'nginx-custom'):
+ if EEAptGet.is_installed(self, 'nginx-custom') or EEAptGet.is_installed(self,'nginx-mainline'):
services = services + ['nginx']
else:
Log.info(self, "Nginx is not installed")
@@ -247,7 +247,7 @@ class EEStackStatusController(CementBaseController):
self.app.pargs.hhvm = True
if self.app.pargs.nginx:
- if EEAptGet.is_installed(self, 'nginx-custom'):
+ if EEAptGet.is_installed(self, 'nginx-custom') or EEAptGet.is_installed(self,'nginx-mainline'):
services = services + ['nginx']
else:
Log.info(self, "Nginx is not installed")
@@ -318,7 +318,7 @@ class EEStackStatusController(CementBaseController):
self.app.pargs.postfix = True
if self.app.pargs.nginx:
- if EEAptGet.is_installed(self, 'nginx-custom'):
+ if EEAptGet.is_installed(self, 'nginx-custom') or EEAptGet.is_installed(self,'nginx-mainline'):
services = services + ['nginx']
else:
Log.info(self, "Nginx is not installed")
diff --git a/ee/cli/templates/22222.mustache b/ee/cli/templates/22222.mustache
index 3893b90e..24c3a05b 100644
--- a/ee/cli/templates/22222.mustache
+++ b/ee/cli/templates/22222.mustache
@@ -2,7 +2,7 @@
server {
- listen 22222 default_server ssl spdy;
+ listen 22222 default_server ssl {{http2}};
access_log /var/log/nginx/22222.access.log rt_cache;
error_log /var/log/nginx/22222.error.log;
diff --git a/ee/cli/templates/locations.mustache b/ee/cli/templates/locations.mustache
index b9d9fc63..df651d7a 100644
--- a/ee/cli/templates/locations.mustache
+++ b/ee/cli/templates/locations.mustache
@@ -22,6 +22,9 @@ location ~* \.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|css|rss|atom|js|jpg|jpeg|gi
}
# Security settings for better privacy
# Deny hidden files
+location ~ /\.well-known {
+ allow all;
+}
location ~ /\. {
deny all;
access_log off;
diff --git a/ee/cli/templates/siteinfo.mustache b/ee/cli/templates/siteinfo.mustache
index 7875709d..3e8b1960 100644
--- a/ee/cli/templates/siteinfo.mustache
+++ b/ee/cli/templates/siteinfo.mustache
@@ -3,6 +3,9 @@ Information about {{domain}}:
Nginx configuration {{type}} {{enable}}
{{#pagespeed}}Pagespeed {{pagespeed}}{{/pagespeed}}
{{#hhvm}}HHVM {{hhvm}}{{/hhvm}}
+{{#ssl}}SSL {{ssl}}{{/ssl}}
+{{#sslprovider}}SSL PROVIDER {{sslprovider}}{{/sslprovider}}
+{{#sslexpiry}}SSL EXPIRY DATE {{sslexpiry}}{{/sslexpiry}}
access_log {{accesslog}}
error_log {{errorlog}}
{{#webroot}}Webroot {{webroot}}{{/webroot}}
diff --git a/ee/core/cron.py b/ee/core/cron.py
new file mode 100644
index 00000000..9c419a1f
--- /dev/null
+++ b/ee/core/cron.py
@@ -0,0 +1,32 @@
+from ee.core.shellexec import EEShellExec
+from ee.core.logging import Log
+
+"""
+Set CRON on LINUX system.
+"""
+
+class EECron():
+ def setcron_daily(self,cmd,comment='Cron set by EasyEngine',user='root',min=0,hour=12):
+ if not EEShellExec.cmd_exec(self, "crontab -l | grep -q \'{0}\'".format(cmd)):
+
+ EEShellExec.cmd_exec(self, "/bin/bash -c \"crontab -l "
+ "2> /dev/null | {{ cat; echo -e"
+ " \\\""
+ "\\n0 12 * * * "
+ "{0}".format(cmd) +
+ " # {0}".format(comment)+
+ "\\\"; } | crontab -\"")
+ Log.debug(self, "Cron set")
+
+
+
+ def remove_cron(self,cmd):
+ if EEShellExec.cmd_exec(self, "crontab -l | grep -q \'{0}\'".format(cmd)):
+ if not EEShellExec.cmd_exec(self, "/bin/bash -c "
+ "\"crontab "
+ "-l | sed '/{0}/d'"
+ "| crontab -\""
+ .format(cmd)):
+ Log.error(self, "Failed to remove crontab entry",False)
+ else:
+ Log.debug(self, "Cron not found")
diff --git a/ee/core/shellexec.py b/ee/core/shellexec.py
index f82352fd..b68076cc 100644
--- a/ee/core/shellexec.py
+++ b/ee/core/shellexec.py
@@ -29,6 +29,8 @@ class EEShellExec():
"replace"))
if proc.returncode == 0:
+ Log.debug(self, "Command Output: {0}, \nCommand Error: {1}"
+ .format(cmd_stdout, cmd_stderr))
return True
else:
Log.debug(self, "Command Output: {0}, \nCommand Error: {1}"
@@ -50,3 +52,32 @@ class EEShellExec():
except OSError as e:
Log.debug(self, "{0}{1}".format(e.errno, e.strerror))
raise CommandExecutionError
+
+
+ def cmd_exec_stdout(self, command, errormsg='', log=True):
+ """Run shell command from Python"""
+ try:
+ log and Log.debug(self, "Running command: {0}".format(command))
+
+ with subprocess.Popen([command], stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE, shell=True) as proc:
+ (cmd_stdout_bytes, cmd_stderr_bytes) = proc.communicate()
+ (cmd_stdout, cmd_stderr) = (cmd_stdout_bytes.decode('utf-8',
+ "replace"),
+ cmd_stderr_bytes.decode('utf-8',
+ "replace"))
+
+ if proc.returncode == 0:
+ Log.debug(self, "Command Output: {0}, \nCommand Error: {1}"
+ .format(cmd_stdout, cmd_stderr))
+ return cmd_stdout
+ else:
+ Log.debug(self, "Command Output: {0}, \nCommand Error: {1}"
+ .format(cmd_stdout, cmd_stderr))
+ return cmd_stdout
+ except OSError as e:
+ Log.debug(self, str(e))
+ raise CommandExecutionError
+ except Exception as e:
+ Log.debug(self, str(e))
+ raise CommandExecutionError
\ No newline at end of file
diff --git a/ee/core/sslutils.py b/ee/core/sslutils.py
new file mode 100644
index 00000000..305f4f76
--- /dev/null
+++ b/ee/core/sslutils.py
@@ -0,0 +1,41 @@
+import os
+from ee.core.shellexec import EEShellExec
+from ee.core.logging import Log
+
+
+class SSL:
+
+ def getExpirationDays(self,domain):
+ # check if exist
+ if not os.path.isfile('/etc/letsencrypt/live/{0}/cert.pem'
+ .format(domain)):
+ Log.error(self,'File Not Found : /etc/letsencrypt/live/{0}/cert.pem'
+ .format(domain),False)
+ Log.error(self, "Check logs for reason "
+ "`tail /var/log/ee/ee.log` & Try Again!!!")
+
+
+ current_date = EEShellExec.cmd_exec_stdout(self, "date -d \"now\" +%s")
+ expiration_date = EEShellExec.cmd_exec_stdout(self, "date -d \"`openssl x509 -in /etc/letsencrypt/live/{0}/cert.pem"
+ " -text -noout|grep \"Not After\"|cut -c 25-`\" +%s".format(domain))
+
+ days_left = int((int(expiration_date) - int(current_date))/ 86400)
+ if (days_left > 0):
+ return days_left
+ else:
+ # return "Certificate Already Expired ! Please Renew soon."
+ return -1
+
+ def getExpirationDate(self,domain):
+ # check if exist
+ if not os.path.isfile('/etc/letsencrypt/live/{0}/cert.pem'
+ .format(domain)):
+ Log.error(self,'File Not Found : /etc/letsencrypt/live/{0}/cert.pem'
+ .format(domain),False)
+ Log.error(self, "Check logs for reason "
+ "`tail /var/log/ee/ee.log` & Try Again!!!")
+
+ expiration_date = EEShellExec.cmd_exec_stdout(self, "date -d \"`openssl x509 -in /etc/letsencrypt/live/{0}/cert.pem"
+ " -text -noout|grep \"Not After\"|cut -c 25-`\" ".format(domain))
+ return expiration_date
+
diff --git a/ee/core/variables.py b/ee/core/variables.py
index 5cb73187..a0f76234 100644
--- a/ee/core/variables.py
+++ b/ee/core/variables.py
@@ -12,13 +12,13 @@ class EEVariables():
"""Intialization of core variables"""
# EasyEngine version
- ee_version = "3.3.15"
+ ee_version = "3.4.0"
# EasyEngine packages versions
ee_wp_cli = "0.21.1"
ee_adminer = "4.2.1"
- ee_roundcube = "1.1.3"
+ ee_roundcube = "1.1.4"
ee_vimbadmin = "3.0.12"
# Get WPCLI path
@@ -83,22 +83,31 @@ class EEVariables():
else:
ee_mysql_host = "localhost"
- # EasyEngine stack installation varibales
+ # EasyEngine stack installation variables
# Nginx repo and packages
if ee_platform_codename == 'precise':
ee_nginx_repo = ("deb http://download.opensuse.org/repositories/home:"
"/rtCamp:/EasyEngine/xUbuntu_12.04/ /")
+ ee_nginx_dev_repo = ("deb http://download.opensuse.org/repositories/home:"
+ "/rtCamp:/EasyEngine-dev/xUbuntu_12.04/ /")
elif ee_platform_codename == 'trusty':
ee_nginx_repo = ("deb http://download.opensuse.org/repositories/home:"
"/rtCamp:/EasyEngine/xUbuntu_14.04/ /")
+ ee_nginx_dev_repo = ("deb http://download.opensuse.org/repositories/home:"
+ "/rtCamp:/EasyEngine-dev/xUbuntu_14.04/ /")
elif ee_platform_codename == 'wheezy':
ee_nginx_repo = ("deb http://download.opensuse.org/repositories/home:"
"/rtCamp:/EasyEngine/Debian_7.0/ /")
+ ee_nginx_dev_repo = None
elif ee_platform_codename == 'jessie':
ee_nginx_repo = ("deb http://download.opensuse.org/repositories/home:"
"/rtCamp:/EasyEngine/Debian_8.0/ /")
+ ee_nginx_dev_repo = ("deb http://download.opensuse.org/repositories/home:"
+ "/rtCamp:/EasyEngine-dev/Debian_8.0/ /")
+
ee_nginx = ["nginx-custom", "nginx-common"]
+ ee_nginx_dev = ["nginx-mainline", "nginx-common"]
ee_nginx_key = '3050AC3CD2AE6F03'
# PHP repo and packages
diff --git a/install b/install
index d682967e..083deeed 100644
--- a/install
+++ b/install
@@ -48,7 +48,7 @@ fi
# Define variables for later use
ee_branch=$1
readonly ee_version_old="2.2.3"
-readonly ee_version_new="3.3.15"
+readonly ee_version_new="3.4.0"
readonly ee_log_dir=/var/log/ee/
readonly ee_install_log=/var/log/ee/install.log
readonly ee_linux_distro=$(lsb_release -i | awk '{print $3}')
@@ -490,6 +490,14 @@ function ee_update_latest()
fi
fi
+ #Fix For --letsencrypt
+ if [ -f /etc/nginx/common/locations.conf ]; then
+ grep -0 'location ~ \/\\.well-known' /etc/nginx/common/locations.conf &>> /dev/null
+ if [ $? -ne 0 ]; then
+ sed -i 's/# Deny hidden files/# Deny hidden files\nlocation ~ \/\\.well-known {\n allow all;\n}\n /g' /etc/nginx/common/locations.conf &>> /dev/null
+ fi
+ fi
+
# Fix for 3.3.2 renamed nginx.conf
nginx -V 2>&1 &>>/dev/null
if [[ $? -eq 0 ]]; then
@@ -512,6 +520,11 @@ function ee_update_latest()
fi
fi
+ #Fix For ssl_ciphers
+ if [ -f /etc/nginx/nginx.conf ]; then
+ sed -i 's/HIGH:!aNULL:!MD5:!kEDH;/ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA;/' /etc/nginx/nginx.conf
+ fi
+
}
diff --git a/setup.py b/setup.py
index 30d99520..caa47e00 100644
--- a/setup.py
+++ b/setup.py
@@ -5,6 +5,7 @@ import os
import glob
import configparser
import re
+import shutil
conf = []
templates = []
@@ -53,8 +54,11 @@ except Exception as e:
os.system("git config --global user.name {0}".format(ee_user))
os.system("git config --global user.email {0}".format(ee_email))
+if not os.path.isfile('/root/.gitconfig'):
+ shutil.copy2(os.path.expanduser("~")+'/.gitconfig', '/root/.gitconfig')
+
setup(name='ee',
- version='3.3.15',
+ version='3.4.0',
description=long_description,
long_description=long_description,
classifiers=[],