def test_get_vhosts(self): nparser = parser.NginxParser(self.config_path, self.ssl_options) vhosts = nparser.get_vhosts() vhost1 = obj.VirtualHost(nparser.abs_path('nginx.conf'), [obj.Addr('', '8080', False, False)], False, True, set(['localhost', r'~^(www\.)?(example|bar)\.']), []) vhost2 = obj.VirtualHost(nparser.abs_path('nginx.conf'), [obj.Addr('somename', '8080', False, False), obj.Addr('', '8000', False, False)], False, True, set(['somename', 'another.alias', 'alias']), []) vhost3 = obj.VirtualHost(nparser.abs_path('sites-enabled/example.com'), [obj.Addr('69.50.225.155', '9000', False, False), obj.Addr('127.0.0.1', '', False, False)], False, True, set(['.example.com', 'example.*']), []) vhost4 = obj.VirtualHost(nparser.abs_path('sites-enabled/default'), [obj.Addr('myhost', '', False, True)], False, True, set(['www.example.org']), []) vhost5 = obj.VirtualHost(nparser.abs_path('foo.conf'), [obj.Addr('*', '80', True, True)], True, True, set(['*.www.foo.com', '*.www.example.com']), []) self.assertEqual(5, len(vhosts)) example_com = [x for x in vhosts if 'example.com' in x.filep][0] self.assertEqual(vhost3, example_com) default = [x for x in vhosts if 'default' in x.filep][0] self.assertEqual(vhost4, default) fooconf = [x for x in vhosts if 'foo.conf' in x.filep][0] self.assertEqual(vhost5, fooconf) localhost = [x for x in vhosts if 'localhost' in x.names][0] self.assertEquals(vhost1, localhost) somename = [x for x in vhosts if 'somename' in x.names][0] self.assertEquals(vhost2, somename)
def choose_vhost(self, target_name): """Chooses a virtual host based on the given domain name. .. note:: This makes the vhost SSL-enabled if it isn't already. Follows Nginx's server block selection rules preferring blocks that are already SSL. .. todo:: This should maybe return list if no obvious answer is presented. .. todo:: The special name "$hostname" corresponds to the machine's hostname. Currently we just ignore this. :param str target_name: domain name :returns: ssl vhost associated with name :rtype: :class:`~letsencrypt_nginx.obj.VirtualHost` """ vhost = None matches = self._get_ranked_matches(target_name) if not matches: # No matches. Create a new vhost with this name in nginx.conf. filep = self.parser.loc["root"] new_block = [['server'], [['server_name', target_name]]] self.parser.add_http_directives(filep, new_block) vhost = obj.VirtualHost(filep, set([]), False, True, set([target_name]), list(new_block[1])) elif matches[0]['rank'] in xrange(2, 6): # Wildcard match - need to find the longest one rank = matches[0]['rank'] wildcards = [x for x in matches if x['rank'] == rank] vhost = max(wildcards, key=lambda x: len(x['name']))['vhost'] else: vhost = matches[0]['vhost'] if vhost is not None: if not vhost.ssl: self._make_server_ssl(vhost) return vhost
def get_vhosts(self): # pylint: disable=cell-var-from-loop """Gets list of all 'virtual hosts' found in Nginx configuration. Technically this is a misnomer because Nginx does not have virtual hosts, it has 'server blocks'. :returns: List of :class:`~letsencrypt_nginx.obj.VirtualHost` objects found in configuration :rtype: list """ enabled = True # We only look at enabled vhosts for now vhosts = [] servers = {} for filename in self.parsed: tree = self.parsed[filename] servers[filename] = [] srv = servers[filename] # workaround undefined loop var in lambdas # Find all the server blocks _do_for_subarray(tree, lambda x: x[0] == ['server'], lambda x: srv.append(x[1])) # Find 'include' statements in server blocks and append their trees for i, server in enumerate(servers[filename]): new_server = self._get_included_directives(server) servers[filename][i] = new_server for filename in servers: for server in servers[filename]: # Parse the server block into a VirtualHost object parsed_server = _parse_server(server) vhost = obj.VirtualHost(filename, parsed_server['addrs'], parsed_server['ssl'], enabled, parsed_server['names'], server) vhosts.append(vhost) return vhosts