Merge branch 'master' of http://github.com/hashicorp/consul into issue/1447/http-access-logs

This commit is contained in:
Philippe M. Chiasson 2015-12-22 14:55:18 -05:00
commit b8f8861d97
77 changed files with 2689 additions and 1986 deletions

View File

@ -1,7 +1,7 @@
language: go
go:
- tip
- 1.5.2
branches:
only:

View File

@ -1,4 +1,19 @@
## 0.6.0 (Unreleased)
## 0.6.1 (UNRELEASED)
IMPROVEMENTS:
* Consul is now built with Go 1.5.2
* Added source IP address and port information to RPC-related log error
messages [GH-1513]
BUG FIXES:
* Fixed broken settings icon in web UI [GH-1469]
* Fixed a web UI bug where the supplied token wasn't being passed into
the internal endpoint, breaking some pages when multiple datacenters
were present [GH-1071]
## 0.6.0 (December 3, 2015)
BACKWARDS INCOMPATIBILITIES:
@ -12,7 +27,7 @@ FEATURES:
* Service ACLs now apply to service discovery [GH-1024]
* Added event ACLs to guard firing user events [GH-1046]
* Added keyring ACLs for gossip encryption keyring operations [GH-1090]
* Added a new socket check type that does a connect as a check [GH-1130]
* Added a new TCP check type that does a connect as a check [GH-1130]
* Added new "tag override" feature that lets catalog updates to a
service's tags flow down to agents [GH-1187]
* Ported in-memory database from LMDB to an immutable radix tree to improve
@ -33,7 +48,7 @@ FEATURES:
BUG FIXES:
* Fixes expired certificates in unit tests [GH-979]
* Fixed expired certificates in unit tests [GH-979]
* Allow services with `/` characters in the UI [GH-988]
* Added SOA/NXDOMAIN records to negative DNS responses per RFC2308 [GH-995]
[GH-1142] [GH-1195] [GH-1217]
@ -82,23 +97,33 @@ IMPROVEMENTS:
in the query string [GH-1318]
* Increased session TTL max to 24 hours (use with caution, see note added
to the Session HTTP endpoint documentation) [GH-1412]
* Added support to the API client for retrying lock monitoring when Consul
is unavailable, helping prevent false indications of lost locks (eg. apps
like Vault can avoid failing over when a Consul leader election occurs)
[GH-1457]
* Added reap of receive buffer space for idle streams in the connection
pool [GH-1452]
MISC:
* Lots of docs fixes
* Lots of Vagrantfile cleanup
* Data migrator utility removed to reduce cgo dependency [GH-1309]
* Data migrator utility removed to eliminate cgo dependency [GH-1309]
UPGRADE NOTES:
* Consul will refuse to start if the data directory contains an "mdb" folder.
This folder was used in versions of Consul up to 0.5.1. Consul version 0.5.2
included a baked-in utility to automatically upgrade the data format, but
this has been removed in Consul 0.6 to reduce the dependency on cgo.
* Previously, service discovery was wide open, and any client could query
information about any service without providing a token. Consul now requires
read-level access at a minimum when ACLs are enabled to return service
information over the REST or DNS interfaces.
this has been removed in Consul 0.6 to eliminate the dependency on cgo.
* New service read, event firing, and keyring ACLs may require special steps to
perform during an upgrade if ACLs are enabled and set to deny by default.
* Consul will refuse to start if there are multiple private IPs available, so
if this is the case you will need to configure Consul's advertise or bind
addresses before upgrading.
See https://www.consul.io/docs/upgrade-specific.html for detailed upgrade
instructions.
## 0.5.2 (May 18, 2015)

2
Vagrantfile vendored
View File

@ -5,7 +5,7 @@
VAGRANTFILE_API_VERSION = '2'
@script = <<SCRIPT
GOVERSION="1.5.1"
GOVERSION="1.5.2"
SRCROOT="/opt/go"
SRCPATH="/opt/gopath"

View File

@ -4,7 +4,7 @@ Consul API client
This package provides the `api` package which attempts to
provide programmatic access to the full Consul API.
Currently, all of the Consul APIs included in version 0.5.2 are supported.
Currently, all of the Consul APIs included in version 0.6.0 are supported.
Documentation
=============

View File

@ -172,11 +172,11 @@ func DefaultConfig() *Config {
}
if !doVerify {
config.HttpClient.Transport = &http.Transport{
TLSClientConfig: &tls.Config{
transport := cleanhttp.DefaultTransport()
transport.TLSClientConfig = &tls.Config{
InsecureSkipVerify: true,
},
}
config.HttpClient.Transport = transport
}
}

View File

@ -2,6 +2,7 @@ package api
import (
"fmt"
"strings"
"sync"
"time"
)
@ -22,9 +23,15 @@ const (
// DefaultLockRetryTime is how long we wait after a failed lock acquisition
// before attempting to do the lock again. This is so that once a lock-delay
// is in affect, we do not hot loop retrying the acquisition.
// is in effect, we do not hot loop retrying the acquisition.
DefaultLockRetryTime = 5 * time.Second
// DefaultMonitorRetryTime is how long we wait after a failed monitor check
// of a lock (500 response code). This allows the monitor to ride out brief
// periods of unavailability, subject to the MonitorRetries setting in the
// lock options which is by default set to 0, disabling this feature.
DefaultMonitorRetryTime = 2 * time.Second
// LockFlagValue is a magic flag we set to indicate a key
// is being used for a lock. It is used to detect a potential
// conflict with a semaphore.
@ -67,6 +74,8 @@ type LockOptions struct {
Session string // Optional, created if not specified
SessionName string // Optional, defaults to DefaultLockSessionName
SessionTTL string // Optional, defaults to DefaultLockSessionTTL
MonitorRetries int // Optional, defaults to 0 which means no retries
MonitorRetryTime time.Duration // Optional, defaults to DefaultMonitorRetryTime
}
// LockKey returns a handle to a lock struct which can be used
@ -96,6 +105,9 @@ func (c *Client) LockOpts(opts *LockOptions) (*Lock, error) {
return nil, fmt.Errorf("invalid SessionTTL: %v", err)
}
}
if opts.MonitorRetryTime == 0 {
opts.MonitorRetryTime = DefaultMonitorRetryTime
}
l := &Lock{
c: c,
opts: opts,
@ -327,8 +339,24 @@ func (l *Lock) monitorLock(session string, stopCh chan struct{}) {
kv := l.c.KV()
opts := &QueryOptions{RequireConsistent: true}
WAIT:
retries := l.opts.MonitorRetries
RETRY:
pair, meta, err := kv.Get(l.opts.Key, opts)
if err != nil {
// TODO (slackpad) - Make a real error type here instead of using
// a string check.
const serverError = "Unexpected response code: 500"
// If configured we can try to ride out a brief Consul unavailability
// by doing retries. Note that we have to attempt the retry in a non-
// blocking fashion so that we have a clean place to reset the retry
// counter if service is restored.
if retries > 0 && strings.Contains(err.Error(), serverError) {
time.Sleep(l.opts.MonitorRetryTime)
retries--
opts.WaitIndex = 0
goto RETRY
}
return
}
if pair != nil && pair.Session == session {

View File

@ -2,6 +2,10 @@ package api
import (
"log"
"net/http"
"net/http/httptest"
"net/http/httputil"
"strings"
"sync"
"testing"
"time"
@ -369,3 +373,118 @@ func TestLock_ReclaimLock(t *testing.T) {
t.Fatalf("should not be leader")
}
}
func TestLock_MonitorRetry(t *testing.T) {
t.Parallel()
raw, s := makeClient(t)
defer s.Stop()
// Set up a server that always responds with 500 errors.
failer := func(w http.ResponseWriter, req *http.Request) {
w.WriteHeader(500)
}
outage := httptest.NewServer(http.HandlerFunc(failer))
defer outage.Close()
// Set up a reverse proxy that will send some requests to the
// 500 server and pass everything else through to the real Consul
// server.
var mutex sync.Mutex
errors := 0
director := func(req *http.Request) {
mutex.Lock()
defer mutex.Unlock()
req.URL.Scheme = "http"
if errors > 0 && req.Method == "GET" && strings.Contains(req.URL.Path, "/v1/kv/test/lock") {
req.URL.Host = outage.URL[7:] // Strip off "http://".
errors--
} else {
req.URL.Host = raw.config.Address
}
}
proxy := httptest.NewServer(&httputil.ReverseProxy{Director: director})
defer proxy.Close()
// Make another client that points at the proxy instead of the real
// Consul server.
config := raw.config
config.Address = proxy.URL[7:] // Strip off "http://".
c, err := NewClient(&config)
if err != nil {
t.Fatalf("err: %v", err)
}
// Set up a lock with retries enabled.
opts := &LockOptions{
Key: "test/lock",
SessionTTL: "60s",
MonitorRetries: 3,
}
lock, err := c.LockOpts(opts)
if err != nil {
t.Fatalf("err: %v", err)
}
// Make sure the default got set.
if lock.opts.MonitorRetryTime != DefaultMonitorRetryTime {
t.Fatalf("bad: %d", lock.opts.MonitorRetryTime)
}
// Now set a custom time for the test.
opts.MonitorRetryTime = 250 * time.Millisecond
lock, err = c.LockOpts(opts)
if err != nil {
t.Fatalf("err: %v", err)
}
if lock.opts.MonitorRetryTime != 250*time.Millisecond {
t.Fatalf("bad: %d", lock.opts.MonitorRetryTime)
}
// Should get the lock.
leaderCh, err := lock.Lock(nil)
if err != nil {
t.Fatalf("err: %v", err)
}
if leaderCh == nil {
t.Fatalf("not leader")
}
// Poke the key using the raw client to force the monitor to wake up
// and check the lock again. This time we will return errors for some
// of the responses.
mutex.Lock()
errors = 2
mutex.Unlock()
pair, _, err := raw.KV().Get("test/lock", &QueryOptions{})
if err != nil {
t.Fatalf("err: %v", err)
}
if _, err := raw.KV().Put(pair, &WriteOptions{}); err != nil {
t.Fatalf("err: %v", err)
}
time.Sleep(5 * opts.MonitorRetryTime)
// Should still be the leader.
select {
case <-leaderCh:
t.Fatalf("should be leader")
default:
}
// Now return an overwhelming number of errors.
mutex.Lock()
errors = 10
mutex.Unlock()
if _, err := raw.KV().Put(pair, &WriteOptions{}); err != nil {
t.Fatalf("err: %v", err)
}
time.Sleep(5 * opts.MonitorRetryTime)
// Should lose leadership.
select {
case <-leaderCh:
case <-time.After(time.Second):
t.Fatalf("should not be leader")
}
}

View File

@ -18,6 +18,7 @@ import (
"github.com/armon/go-metrics/datadog"
"github.com/hashicorp/consul/watch"
"github.com/hashicorp/go-checkpoint"
"github.com/hashicorp/go-reap"
"github.com/hashicorp/go-syslog"
"github.com/hashicorp/logutils"
scada "github.com/hashicorp/scada-client"
@ -565,11 +566,6 @@ func (c *Command) Run(args []string) int {
return 1
}
// Check GOMAXPROCS
if runtime.GOMAXPROCS(0) == 1 {
c.Ui.Error("WARNING: It is highly recommended to set GOMAXPROCS higher than 1")
}
// Setup the log outputs
logGate, logWriter, logOutput := c.setupLoggers(config)
if logWriter == nil {
@ -646,6 +642,33 @@ func (c *Command) Run(args []string) int {
defer server.Shutdown()
}
// Enable child process reaping
if (config.Reap != nil && *config.Reap) || (config.Reap == nil && os.Getpid() == 1) {
if !reap.IsSupported() {
c.Ui.Error("Child process reaping is not supported on this platform (set reap=false)")
return 1
} else {
logger := c.agent.logger
logger.Printf("[DEBUG] Automatically reaping child processes")
pids := make(reap.PidCh, 1)
errors := make(reap.ErrorCh, 1)
go func() {
for {
select {
case pid := <-pids:
logger.Printf("[DEBUG] Reaped child process %d", pid)
case err := <-errors:
logger.Printf("[ERR] Error reaping child process: %v", err)
case <-c.agent.shutdownCh:
return
}
}
}()
go reap.ReapChildren(pids, errors, c.agent.shutdownCh)
}
}
// Check and shut down the SCADA listeners at the end
defer func() {
if c.scadaHttp != nil {

View File

@ -422,6 +422,17 @@ type Config struct {
// Minimum Session TTL
SessionTTLMin time.Duration `mapstructure:"-"`
SessionTTLMinRaw string `mapstructure:"session_ttl_min"`
// Reap controls automatic reaping of child processes, useful if running
// as PID 1 in a Docker container. This defaults to nil which will make
// Consul reap only if it detects it's running as PID 1. If non-nil,
// then this will be used to decide if reaping is enabled.
Reap *bool `mapstructure:"reap"`
}
// Bool is used to initialize bool pointers in struct literals.
func Bool(b bool) *bool {
return &b
}
// UnixSocketPermissions contains information about a unix socket, and
@ -1140,6 +1151,10 @@ func MergeConfig(a, b *Config) *Config {
result.RetryJoinWan = append(result.RetryJoinWan, a.RetryJoinWan...)
result.RetryJoinWan = append(result.RetryJoinWan, b.RetryJoinWan...)
if b.Reap != nil {
result.Reap = b.Reap
}
return &result
}

View File

@ -777,6 +777,27 @@ func TestDecodeConfig(t *testing.T) {
if config.SessionTTLMin != 5*time.Second {
t.Fatalf("bad: %s %#v", config.SessionTTLMin.String(), config)
}
// Reap
input = `{"reap": true}`
config, err = DecodeConfig(bytes.NewReader([]byte(input)))
if err != nil {
t.Fatalf("err: %s", err)
}
if config.Reap == nil || *config.Reap != true {
t.Fatalf("bad: reap not enabled: %#v", config)
}
input = `{}`
config, err = DecodeConfig(bytes.NewReader([]byte(input)))
if err != nil {
t.Fatalf("err: %s", err)
}
if config.Reap != nil {
t.Fatalf("bad: reap not tri-stated: %#v", config)
}
}
func TestDecodeConfig_invalidKeys(t *testing.T) {
@ -1266,6 +1287,7 @@ func TestMergeConfig(t *testing.T) {
RPC: &net.TCPAddr{},
RPCRaw: "127.0.0.5:1233",
},
Reap: Bool(true),
}
c := MergeConfig(a, b)

View File

@ -9,6 +9,7 @@ import (
"sync"
"time"
"github.com/armon/go-metrics"
"github.com/hashicorp/consul/consul"
"github.com/hashicorp/consul/consul/structs"
"github.com/miekg/dns"
@ -165,6 +166,7 @@ START:
func (d *DNSServer) handlePtr(resp dns.ResponseWriter, req *dns.Msg) {
q := req.Question[0]
defer func(s time.Time) {
metrics.MeasureSince([]string{"consul", "dns", "ptr_query", d.agent.config.NodeName}, s)
d.logger.Printf("[DEBUG] dns: request for %v (%v) from client %s (%s)",
q, time.Now().Sub(s), resp.RemoteAddr().String(),
resp.RemoteAddr().Network())
@ -227,6 +229,7 @@ func (d *DNSServer) handlePtr(resp dns.ResponseWriter, req *dns.Msg) {
func (d *DNSServer) handleQuery(resp dns.ResponseWriter, req *dns.Msg) {
q := req.Question[0]
defer func(s time.Time) {
metrics.MeasureSince([]string{"consul", "dns", "domain_query", d.agent.config.NodeName}, s)
d.logger.Printf("[DEBUG] dns: request for %v (%v) from client %s (%s)",
q, time.Now().Sub(s), resp.RemoteAddr().String(),
resp.RemoteAddr().Network())

View File

@ -567,7 +567,7 @@ func (l *localState) syncService(id string) error {
return err
}
// syncCheck is used to sync a service to the server
// syncCheck is used to sync a check to the server
func (l *localState) syncCheck(id string) error {
// Pull in the associated service if any
check := l.checks[id]

View File

@ -48,21 +48,6 @@ func (i *InfoCommand) Run(args []string) int {
return 1
}
// Check for specific warnings
didWarn := false
runtime, ok := stats["runtime"]
if ok {
if maxprocs := runtime["max_procs"]; maxprocs == "1" {
i.Ui.Output("WARNING: It is highly recommended to set GOMAXPROCS higher than 1")
didWarn = true
}
}
// Add a blank line if there are any warnings
if didWarn {
i.Ui.Output("")
}
// Get the keys in sorted order
keys := make([]string, 0, len(stats))
for key := range stats {

View File

@ -76,7 +76,7 @@ func (c *Coordinate) batchApplyUpdates() error {
break
}
updates[i] = &structs.Coordinate{node, coord}
updates[i] = &structs.Coordinate{Node: node, Coord: coord}
i++
}

View File

@ -103,6 +103,12 @@ func (c *Conn) returnClient(client *StreamClient) {
if c.clients.Len() < c.pool.maxStreams && atomic.LoadInt32(&c.shouldClose) == 0 {
c.clients.PushFront(client)
didSave = true
// If this is a Yamux stream, shrink the internal buffers so that
// we can GC the idle memory
if ys, ok := client.stream.(*yamux.Stream); ok {
ys.Shrink()
}
}
c.clientLock.Unlock()
if !didSave {

View File

@ -219,8 +219,6 @@ func (p *PreparedQuery) Get(args *structs.PreparedQuerySpecificRequest,
reply.Queries = structs.PreparedQueries{query}
return nil
})
return nil
}
// List returns all the prepared queries.

View File

@ -12,6 +12,7 @@ import (
"github.com/armon/go-metrics"
"github.com/hashicorp/consul/consul/state"
"github.com/hashicorp/consul/consul/structs"
"github.com/hashicorp/memberlist"
"github.com/hashicorp/net-rpc-msgpackrpc"
"github.com/hashicorp/yamux"
"github.com/inconshreveable/muxado"
@ -69,6 +70,12 @@ func (s *Server) listen() {
}
}
// logConn is a wrapper around memberlist's LogConn so that we format references
// to "from" addresses in a consistent way. This is just a shorter name.
func logConn(conn net.Conn) string {
return memberlist.LogConn(conn)
}
// handleConn is used to determine if this is a Raft or
// Consul type RPC connection and invoke the correct handler
func (s *Server) handleConn(conn net.Conn, isTLS bool) {
@ -76,7 +83,7 @@ func (s *Server) handleConn(conn net.Conn, isTLS bool) {
buf := make([]byte, 1)
if _, err := conn.Read(buf); err != nil {
if err != io.EOF {
s.logger.Printf("[ERR] consul.rpc: failed to read byte: %v", err)
s.logger.Printf("[ERR] consul.rpc: failed to read byte: %v %s", err, logConn(conn))
}
conn.Close()
return
@ -84,7 +91,7 @@ func (s *Server) handleConn(conn net.Conn, isTLS bool) {
// Enforce TLS if VerifyIncoming is set
if s.config.VerifyIncoming && !isTLS && RPCType(buf[0]) != rpcTLS {
s.logger.Printf("[WARN] consul.rpc: Non-TLS connection attempted with VerifyIncoming set")
s.logger.Printf("[WARN] consul.rpc: Non-TLS connection attempted with VerifyIncoming set %s", logConn(conn))
conn.Close()
return
}
@ -103,7 +110,7 @@ func (s *Server) handleConn(conn net.Conn, isTLS bool) {
case rpcTLS:
if s.rpcTLS == nil {
s.logger.Printf("[WARN] consul.rpc: TLS connection attempted, server not configured for TLS")
s.logger.Printf("[WARN] consul.rpc: TLS connection attempted, server not configured for TLS %s", logConn(conn))
conn.Close()
return
}
@ -114,7 +121,7 @@ func (s *Server) handleConn(conn net.Conn, isTLS bool) {
s.handleMultiplexV2(conn)
default:
s.logger.Printf("[ERR] consul.rpc: unrecognized RPC byte: %v", buf[0])
s.logger.Printf("[ERR] consul.rpc: unrecognized RPC byte: %v %s", buf[0], logConn(conn))
conn.Close()
return
}
@ -129,7 +136,7 @@ func (s *Server) handleMultiplex(conn net.Conn) {
sub, err := server.Accept()
if err != nil {
if !strings.Contains(err.Error(), "closed") {
s.logger.Printf("[ERR] consul.rpc: multiplex conn accept failed: %v", err)
s.logger.Printf("[ERR] consul.rpc: multiplex conn accept failed: %v %s", err, logConn(conn))
}
return
}
@ -148,7 +155,7 @@ func (s *Server) handleMultiplexV2(conn net.Conn) {
sub, err := server.Accept()
if err != nil {
if err != io.EOF {
s.logger.Printf("[ERR] consul.rpc: multiplex conn accept failed: %v", err)
s.logger.Printf("[ERR] consul.rpc: multiplex conn accept failed: %v %s", err, logConn(conn))
}
return
}
@ -169,7 +176,7 @@ func (s *Server) handleConsulConn(conn net.Conn) {
if err := s.rpcServer.ServeRequest(rpcCodec); err != nil {
if err != io.EOF && !strings.Contains(err.Error(), "closed") {
s.logger.Printf("[ERR] consul.rpc: RPC error: %v (%v)", err, conn)
s.logger.Printf("[ERR] consul.rpc: RPC error: %v %s", err, logConn(conn))
metrics.IncrCounter([]string{"consul", "rpc", "request_error"}, 1)
}
return

View File

@ -371,7 +371,7 @@ func getDatacenterMaps(s serfer, dcs []string) []structs.DatacenterMap {
nodes := s.GetNodesForDatacenter(dc)
for _, node := range nodes {
if coord, ok := s.GetCachedCoordinate(node); ok {
entry := &structs.Coordinate{node, coord}
entry := &structs.Coordinate{Node: node, Coord: coord}
m.Coordinates = append(m.Coordinates, entry)
}
}

View File

@ -76,6 +76,19 @@ func (s *StateStore) preparedQuerySetTxn(tx *memdb.Txn, idx uint64, query *struc
query.ModifyIndex = idx
}
// Verify that the query name doesn't already exist, or that we are
// updating the same instance that has this name.
if query.Name != "" {
alias, err := tx.First("prepared-queries", "name", query.Name)
if err != nil {
return fmt.Errorf("failed prepared query lookup: %s", err)
}
if alias != nil && (existing == nil ||
existing.(*structs.PreparedQuery).ID != alias.(*structs.PreparedQuery).ID) {
return fmt.Errorf("name '%s' aliases an existing query name", query.Name)
}
}
// Verify that the name doesn't alias any existing ID. We allow queries
// to be looked up by ID *or* name so we don't want anyone to try to
// register a query with a name equal to some other query's ID in an
@ -86,12 +99,12 @@ func (s *StateStore) preparedQuerySetTxn(tx *memdb.Txn, idx uint64, query *struc
// index will complain if we look up something that's not formatted
// like one.
if isUUID(query.Name) {
existing, err := tx.First("prepared-queries", "id", query.Name)
alias, err := tx.First("prepared-queries", "id", query.Name)
if err != nil {
return fmt.Errorf("failed prepared query lookup: %s", err)
}
if existing != nil {
return fmt.Errorf("name '%s' aliases an existing query id", query.Name)
if alias != nil {
return fmt.Errorf("name '%s' aliases an existing query ID", query.Name)
}
}

View File

@ -175,27 +175,22 @@ func TestStateStore_PreparedQuerySet_PreparedQueryGet(t *testing.T) {
t.Fatalf("bad: %v", actual)
}
// Finally, try to abuse the system by trying to register a query whose
// name aliases a real query ID.
// Try to register a query with the same name and make sure it fails.
{
evil := &structs.PreparedQuery{
ID: testUUID(),
Name: query.ID,
Name: query.Name,
Service: structs.ServiceQuery{
Service: "redis",
},
}
err = s.PreparedQuerySet(7, evil)
if err == nil || !strings.Contains(err.Error(), "aliases an existing query") {
err := s.PreparedQuerySet(7, evil)
if err == nil || !strings.Contains(err.Error(), "aliases an existing query name") {
t.Fatalf("bad: %v", err)
}
// Index is not updated if nothing is saved.
if idx := s.maxIndex("prepared-queries"); idx != 6 {
t.Fatalf("bad index: %d", idx)
}
// Sanity check to make sure it's not there.
idx, actual, err = s.PreparedQueryGet(evil.ID)
idx, actual, err := s.PreparedQueryGet(evil.ID)
if err != nil {
t.Fatalf("err: %s", err)
}
@ -205,6 +200,40 @@ func TestStateStore_PreparedQuerySet_PreparedQueryGet(t *testing.T) {
if actual != nil {
t.Fatalf("bad: %v", actual)
}
}
// Try to abuse the system by trying to register a query whose name
// aliases a real query ID.
{
evil := &structs.PreparedQuery{
ID: testUUID(),
Name: query.ID,
Service: structs.ServiceQuery{
Service: "redis",
},
}
err := s.PreparedQuerySet(8, evil)
if err == nil || !strings.Contains(err.Error(), "aliases an existing query ID") {
t.Fatalf("bad: %v", err)
}
// Sanity check to make sure it's not there.
idx, actual, err := s.PreparedQueryGet(evil.ID)
if err != nil {
t.Fatalf("err: %s", err)
}
if idx != 6 {
t.Fatalf("bad index: %d", idx)
}
if actual != nil {
t.Fatalf("bad: %v", actual)
}
}
// Index is not updated if nothing is saved.
if idx := s.maxIndex("prepared-queries"); idx != 6 {
t.Fatalf("bad index: %d", idx)
}
}
func TestStateStore_PreparedQueryDelete(t *testing.T) {

View File

@ -3,11 +3,12 @@
$script = <<SCRIPT
echo Installing dependencies...
sudo apt-get update
sudo apt-get install -y unzip curl
echo Fetching Consul...
cd /tmp/
wget https://dl.bintray.com/mitchellh/consul/0.5.2_linux_amd64.zip -O consul.zip
wget https://releases.hashicorp.com/consul/0.6.0/consul_0.6.0_linux_amd64.zip -O consul.zip
echo Installing Consul...
unzip consul.zip

134
deps/v0-6-0.json vendored Normal file
View File

@ -0,0 +1,134 @@
{
"ImportPath": "github.com/hashicorp/consul",
"GoVersion": "go1.5.1",
"Deps": [
{
"ImportPath": "github.com/DataDog/datadog-go/statsd",
"Rev": "b050cd8f4d7c394545fd7d966c8e2909ce89d552"
},
{
"ImportPath": "github.com/armon/circbuf",
"Rev": "bbbad097214e2918d8543d5201d12bfd7bca254d"
},
{
"ImportPath": "github.com/armon/go-metrics",
"Rev": "6c5fa0d8f48f4661c9ba8709799c88d425ad20f0"
},
{
"ImportPath": "github.com/armon/go-radix",
"Rev": "fbd82e84e2b13651f3abc5ffd26b65ba71bc8f93"
},
{
"ImportPath": "github.com/boltdb/bolt",
"Comment": "v1.1.0-19-g0b00eff",
"Rev": "0b00effdd7a8270ebd91c24297e51643e370dd52"
},
{
"ImportPath": "github.com/fsouza/go-dockerclient",
"Rev": "2350d7bc12bb04f2d7d6824c7718012b1397b760"
},
{
"ImportPath": "github.com/hashicorp/errwrap",
"Rev": "7554cd9344cec97297fa6649b055a8c98c2a1e55"
},
{
"ImportPath": "github.com/hashicorp/go-checkpoint",
"Rev": "e4b2dc34c0f698ee04750bf2035d8b9384233e1b"
},
{
"ImportPath": "github.com/hashicorp/go-cleanhttp",
"Rev": "5df5ddc69534f1a4697289f1dca2193fbb40213f"
},
{
"ImportPath": "github.com/hashicorp/go-immutable-radix",
"Rev": "aca1bd0689e10884f20d114aff148ddb849ece80"
},
{
"ImportPath": "github.com/hashicorp/go-memdb",
"Rev": "9ea975be0e31ada034a5760340d4892f3f543d20"
},
{
"ImportPath": "github.com/hashicorp/go-msgpack/codec",
"Rev": "fa3f63826f7c23912c15263591e65d54d080b458"
},
{
"ImportPath": "github.com/hashicorp/go-multierror",
"Rev": "d30f09973e19c1dfcd120b2d9c4f168e68d6b5d5"
},
{
"ImportPath": "github.com/hashicorp/go-syslog",
"Rev": "42a2b573b664dbf281bd48c3cc12c086b17a39ba"
},
{
"ImportPath": "github.com/hashicorp/golang-lru",
"Rev": "a6091bb5d00e2e9c4a16a0e739e306f8a3071a3c"
},
{
"ImportPath": "github.com/hashicorp/hcl",
"Rev": "2deb1d1db27ed473f38fe65a16044572b9ff9d30"
},
{
"ImportPath": "github.com/hashicorp/logutils",
"Rev": "0dc08b1671f34c4250ce212759ebd880f743d883"
},
{
"ImportPath": "github.com/hashicorp/memberlist",
"Rev": "28424fb38c7c3e30f366b72b1a55f690d318d8f3"
},
{
"ImportPath": "github.com/hashicorp/net-rpc-msgpackrpc",
"Rev": "a14192a58a694c123d8fe5481d4a4727d6ae82f3"
},
{
"ImportPath": "github.com/hashicorp/raft",
"Rev": "d136cd15dfb7876fd7c89cad1995bc4f19ceb294"
},
{
"ImportPath": "github.com/hashicorp/raft-boltdb",
"Rev": "d1e82c1ec3f15ee991f7cc7ffd5b67ff6f5bbaee"
},
{
"ImportPath": "github.com/hashicorp/scada-client",
"Rev": "84989fd23ad4cc0e7ad44d6a871fd793eb9beb0a"
},
{
"ImportPath": "github.com/hashicorp/serf/coordinate",
"Comment": "v0.6.4-145-ga72c045",
"Rev": "a72c0453da2ba628a013e98bf323a76be4aa1443"
},
{
"ImportPath": "github.com/hashicorp/serf/serf",
"Comment": "v0.6.4-145-ga72c045",
"Rev": "a72c0453da2ba628a013e98bf323a76be4aa1443"
},
{
"ImportPath": "github.com/hashicorp/yamux",
"Rev": "df949784da9ed028ee76df44652e42d37a09d7e4"
},
{
"ImportPath": "github.com/inconshreveable/muxado",
"Rev": "f693c7e88ba316d1a0ae3e205e22a01aa3ec2848"
},
{
"ImportPath": "github.com/miekg/dns",
"Rev": "d27455715200c7d3e321a1e5cadb27c9ee0b0f02"
},
{
"ImportPath": "github.com/mitchellh/cli",
"Rev": "8102d0ed5ea2709ade1243798785888175f6e415"
},
{
"ImportPath": "github.com/mitchellh/mapstructure",
"Rev": "281073eb9eb092240d33ef253c404f1cca550309"
},
{
"ImportPath": "github.com/ryanuber/columnize",
"Comment": "v2.0.1-8-g983d3a5",
"Rev": "983d3a5fab1bf04d1b412465d2d9f8430e2e917e"
},
{
"ImportPath": "golang.org/x/crypto/ssh/terminal",
"Rev": "346896d57731cb5670b36c6178fc5519f3225980"
}
]
}

View File

@ -57,3 +57,6 @@ development configuration.
`make dist`
The `dist` folder will contain the files you should use for deployment.
###Acknowledgements
cog icon by useiconic.com from the [Noun Project](https://thenounproject.com/term/setting/45865/)

View File

@ -161,7 +161,11 @@
</div>
<div class="col-md-1 col-sm-2 col-xs-2 col-md-offset-0 col-sm-offset-0 col-xs-offset-0">
{{#link-to 'settings' class='btn btn-default col-xs-6 icon'}}<span class="wrap">&#9881;</span>{{/link-to}}
{{#link-to 'settings' class='btn btn-default col-xs-6 icon'}}
<svg xmlns="http://www.w3.org/2000/svg" data-icon="cog" viewBox="0 0 32 40">
<path d="M14 0l-1.313 4c-1 .3-1.975.688-2.875 1.188l-3.72-1.875-2.78 2.78 1.875 3.72c-.5.9-.888 1.875-1.188 2.875L0 14v4l4 1.314c.3 1 .687 1.975 1.187 2.875l-1.78 3.718 2.78 2.78 3.72-1.874c.9.5 1.905.887 2.905 1.188l1.28 4h4l1.314-4c1-.3 2.006-.688 2.906-1.188L26 28.594l2.813-2.78-1.906-3.72c.5-.9.887-1.905 1.188-2.905L32 18v-4l-4-1.312c-.3-1-.687-1.975-1.187-2.875l1.78-3.72-2.78-2.78-3.72 1.875c-.9-.5-1.905-.888-2.905-1.188L18 0h-4zm2 9c3.9 0 7 3.1 7 7s-3.1 7-7 7-7-3.1-7-7 3.1-7 7-7z"/>
</svg>
{{/link-to}}
</div>
</div>
</div>

View File

@ -88,12 +88,14 @@ App.IndexRoute = App.BaseRoute.extend({
// functioning, as well as the per-dc requests.
App.DcRoute = App.BaseRoute.extend({
model: function(params) {
var token = App.get('settings.token');
// Return a promise hash to retreieve the
// dcs and nodes used in the header
return Ember.RSVP.hash({
dc: params.dc,
dcs: Ember.$.getJSON('/v1/catalog/datacenters'),
nodes: Ember.$.getJSON(formatUrl('/v1/internal/ui/nodes', params.dc)).then(function(data) {
nodes: Ember.$.getJSON(formatUrl('/v1/internal/ui/nodes', params.dc, token)).then(function(data) {
var objs = [];
// Merge the nodes into a list and create objects out of them

File diff suppressed because one or more lines are too long

View File

@ -112,13 +112,11 @@
.topbar {
.btn.icon {
min-width: 50px;
font-size: 30px;
height: 33px;
padding: 0;
.wrap {
position: absolute;
top: -8px;
left: 14px;
padding: 6px 0;
svg {
height: 20px;
fill: currentColor;
}
}
}

View File

@ -7,9 +7,9 @@ var (
)
// The main version number that is being run at the moment.
const Version = "0.6.0"
const Version = "0.6.1"
// A pre-release marker for the version. If this is "" (empty string)
// then it means that it is a final release. Otherwise, this is a pre-release
// such as "dev" (in development), "beta", "rc1", etc.
const VersionPrerelease = "rc2"
const VersionPrerelease = "dev"

View File

@ -6,7 +6,7 @@ set :base_url, "https://www.consul.io/"
activate :hashicorp do |h|
h.name = "consul"
h.version = "0.5.2"
h.version = "0.6.0"
h.github_slug = "hashicorp/consul"
end

BIN
website/source/assets/images/logo-header-gradient@2x.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
website/source/assets/images/wordtype@2x.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,50 @@
(function(){
Sidebar = Base.extend({
$body: null,
$overlay: null,
$sidebar: null,
$sidebarHeader: null,
$sidebarImg: null,
$toggleButton: null,
constructor: function(){
this.$body = $('body');
this.$overlay = $('.sidebar-overlay');
this.$sidebar = $('#sidebar');
this.$sidebarHeader = $('#sidebar .sidebar-header');
this.$toggleButton = $('.navbar-toggle');
this.sidebarImg = this.$sidebarHeader.css('background-image');
this.addEventListeners();
},
addEventListeners: function(){
var _this = this;
_this.$toggleButton.on('click', function() {
_this.$sidebar.toggleClass('open');
if ((_this.$sidebar.hasClass('sidebar-fixed-left') || _this.$sidebar.hasClass('sidebar-fixed-right')) && _this.$sidebar.hasClass('open')) {
_this.$overlay.addClass('active');
_this.$body.css('overflow', 'hidden');
} else {
_this.$overlay.removeClass('active');
_this.$body.css('overflow', 'auto');
}
return false;
});
_this.$overlay.on('click', function() {
$(this).removeClass('active');
_this.$body.css('overflow', 'auto');
_this.$sidebar.removeClass('open');
});
}
});
window.Sidebar = Sidebar;
})();

View File

@ -4,8 +4,15 @@
var APP = (function() {
function initialize (){
function initializeSidebar() {
new Sidebar();
}
function initialize() {
APP.Utils.runIfClassNamePresent('page-home', initHome);
//always init sidebar
initializeSidebar();
}
function initHome() {

View File

@ -0,0 +1,48 @@
(function(){
var mainContentMin = 600;
var Init = {
start: function(){
var classname = this.hasClass(document.body, 'page-sub');
if (classname) {
this.addEventListeners();
}
},
hasClass: function (elem, className) {
return new RegExp(' ' + className + ' ').test(' ' + elem.className + ' ');
},
addEventListeners: function(){
var _this = this;
//console.log(document.querySelectorAll('.navbar-static-top')[0]);
window.addEventListener('resize', _this.resizeImage, false);
this.resizeImage();
},
resizeImage: function(){
var header = document.getElementById('header'),
footer = document.getElementById('footer'),
main = document.getElementById('main-content'),
vp = window.innerHeight,
bodyHeight = document.body.clientHeight,
hHeight = header.clientHeight,
fHeight = footer.clientHeight,
withMinHeight = hHeight + fHeight + mainContentMin;
if(withMinHeight < vp && bodyHeight < vp){
var newHeight = mainContentMin + (vp-withMinHeight) + 'px';
main.style.height = newHeight;
}
}
};
Init.start();
})();

View File

@ -46,4 +46,3 @@ var APP = APP || {};
}());
}(jQuery, this));

View File

@ -28,6 +28,6 @@ APP.Utils = (function () {
initFunction();
}
}
}
}
}());

View File

@ -2,6 +2,10 @@
#= require jquery
#= require bootstrap
#= require lib/Base
#= require _app/docs
#= require _app/Sidebar
#= require _app/app
#= require _app/homepage
#= require _app/util

View File

@ -0,0 +1,145 @@
/*
Based on Base.js 1.1a (c) 2006-2010, Dean Edwards
Updated to pass JSHint and converted into a module by Kenneth Powers
License: http://www.opensource.org/licenses/mit-license.php
*/
/*global define:true module:true*/
/*jshint eqeqeq:true*/
(function (name, global, definition) {
if (typeof module !== 'undefined') {
module.exports = definition();
} else if (typeof define !== 'undefined' && typeof define.amd === 'object') {
define(definition);
} else {
global[name] = definition();
}
})('Base', this, function () {
// Base Object
var Base = function () {};
// Implementation
Base.extend = function (_instance, _static) { // subclass
var extend = Base.prototype.extend;
// build the prototype
Base._prototyping = true;
var proto = new this();
extend.call(proto, _instance);
proto.base = function () {
// call this method from any other method to invoke that method's ancestor
};
delete Base._prototyping;
// create the wrapper for the constructor function
//var constructor = proto.constructor.valueOf(); //-dean
var constructor = proto.constructor;
var klass = proto.constructor = function () {
if (!Base._prototyping) {
if (this._constructing || this.constructor === klass) { // instantiation
this._constructing = true;
constructor.apply(this, arguments);
delete this._constructing;
} else if (arguments[0] !== null) { // casting
return (arguments[0].extend || extend).call(arguments[0], proto);
}
}
};
// build the class interface
klass.ancestor = this;
klass.extend = this.extend;
klass.forEach = this.forEach;
klass.implement = this.implement;
klass.prototype = proto;
klass.toString = this.toString;
klass.valueOf = function (type) {
return (type === 'object') ? klass : constructor.valueOf();
};
extend.call(klass, _static);
// class initialization
if (typeof klass.init === 'function') klass.init();
return klass;
};
Base.prototype = {
extend: function (source, value) {
if (arguments.length > 1) { // extending with a name/value pair
var ancestor = this[source];
if (ancestor && (typeof value === 'function') && // overriding a method?
// the valueOf() comparison is to avoid circular references
(!ancestor.valueOf || ancestor.valueOf() !== value.valueOf()) && /\bbase\b/.test(value)) {
// get the underlying method
var method = value.valueOf();
// override
value = function () {
var previous = this.base || Base.prototype.base;
this.base = ancestor;
var returnValue = method.apply(this, arguments);
this.base = previous;
return returnValue;
};
// point to the underlying method
value.valueOf = function (type) {
return (type === 'object') ? value : method;
};
value.toString = Base.toString;
}
this[source] = value;
} else if (source) { // extending with an object literal
var extend = Base.prototype.extend;
// if this object has a customized extend method then use it
if (!Base._prototyping && typeof this !== 'function') {
extend = this.extend || extend;
}
var proto = {
toSource: null
};
// do the "toString" and other methods manually
var hidden = ['constructor', 'toString', 'valueOf'];
// if we are prototyping then include the constructor
for (var i = Base._prototyping ? 0 : 1; i < hidden.length; i++) {
var h = hidden[i];
if (source[h] !== proto[h])
extend.call(this, h, source[h]);
}
// copy each of the source object's properties to this object
for (var key in source) {
if (!proto[key]) extend.call(this, key, source[key]);
}
}
return this;
}
};
// initialize
Base = Base.extend({
constructor: function () {
this.extend(arguments[0]);
}
}, {
ancestor: Object,
version: '1.1',
forEach: function (object, block, context) {
for (var key in object) {
if (this.prototype[key] === undefined) {
block.call(context, object[key], key, object);
}
}
},
implement: function () {
for (var i = 0; i < arguments.length; i++) {
if (typeof arguments[i] === 'function') {
// if it's a function, call it
arguments[i](this.prototype);
} else {
// add the interface using the extend method
this.prototype.extend(arguments[i]);
}
}
return this;
},
toString: function () {
return String(this.valueOf());
}
});
// Return Base implementation
return Base;
});

View File

@ -6,6 +6,10 @@ body.layout-docs,
body.layout-intro{
background: $light-purple image-url('sidebar-dots.jpg') left 62px no-repeat;
#main-content{
min-height: 600px;
}
>.container{
.col-md-8[role=main]{
min-height: 800px;
@ -140,7 +144,7 @@ body.layout-intro{
> a{
-webkit-font-smoothing: antialiased;
font-family: $font-family-open-sans;
font-family: $font-family-source-sans;
padding: 6px 15px;
}
@ -152,14 +156,14 @@ body.layout-intro{
padding: 6px 0;
> a{
-webkit-font-smoothing: antialiased;
font-family: $font-family-open-sans;
}
font-family: $font-family-source-sans;
}
}
}
}
}
}
}
.bs-docs-section{
@ -177,7 +181,7 @@ body.layout-intro{
p, li, .alert {
font-size: 20px;
font-family: $font-family-open-sans;
font-family: $font-family-source-sans;
font-weight: $font-weight-open;
line-height: 1.5em;
margin: 0 0 18px;
@ -253,4 +257,3 @@ body.layout-intro{
}
}
}

View File

@ -19,8 +19,3 @@
font-family: $font-family-museo;
font-weight: $font-weight-museo-xb;
}
.os{
font-family: $font-family-open-sans;
font-weight: $font-weight-open;
}

View File

@ -0,0 +1,70 @@
#footer{
padding: 64px 0;
background-color: $black;
.hashicorp-project{
margin-top: 24px;
}
.pull-right{
padding-right: 15px;
}
}
.edit-page-link{
position: absolute;
top: -110px;
right: 30px;
z-index: 9999;
a{
text-transform: uppercase;
color: $black;
}
}
@media (max-width: 768px) {
#footer{
text-align: center;
.footer-hashi {
float: none !important;
display: block;
.pull-right{
float: none !important;
padding-right: 0;
}
}
ul{
float: none;
display: inline-block;
margin-bottom: 36px;
}
}
}
@media (max-width: 414px) {
#footer{
ul{
display: block;
li{
display: block;
float: none;
}
&.external-links{
li{
svg{
position: relative;
left: 0;
top: 2px;
margin-top: 0;
margin-right: 4px;
}
}
}
}
}
}

View File

@ -3,8 +3,8 @@
// --------------------------------------------------
/*html{
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
}*/
body {
@ -81,3 +81,10 @@ pre {
.center {
text-align: center;
}
.edit-this-page{
padding-top: 48px;
a{
text-transform: uppercase;
}
}

View File

@ -1,322 +1,77 @@
//
// Header
// - Project Specific
// - edits should be made here
// --------------------------------------------------
body.page-sub{
#header{
@include consul-gradient-bg();
.navbar-brand {
.logo{
&:hover{
color: $black;
}
}
}
}
}
#footer,
#header {
@include anti-alias();
position: relative;
color: $white;
text-rendering: optimizeLegibility;
margin-bottom: 0;
.navbar-collapse{
box-shadow: none;
}
&.navbar-static-top{
z-index: 1000;
}
a{
color: $white;
}
.navbar-toggle{
margin-top: 14px;
margin-bottom: 14px;
border: 2px solid $white;
.icon-bar{
border: 1px solid $white;
}
}
.brand {
padding: 13px 15px;
line-height: 0;
.navbar-brand {
.logo{
display: block;
width: 179px;
height: 59px;
background: image-url('consul-header-logo.png') 0 0 no-repeat;
@include img-retina("consul-header-logo.png", "consul-header-logo@2x.png", 179px, 59px);
}
}
.navbar-nav{
-webkit-font-smoothing: antialiased;
li{
position: relative;
> a {
font-size: 12px;
padding-left: 50px;
font-size: 0;
text-transform: uppercase;
letter-spacing: 3px;
padding-left: 22px;
background: image-url('../images/consul-hero-logo.png') 0 0 no-repeat;
@include img-retina("../images/consul-hero-logo.png", "../images/consul-hero-logo@2x.png", $project-logo-width, $project-logo-height);
background-position: 0 center;
&:hover{
opacity: .4;
}
}
&.first{
>a{
padding-left: 15px;
.by-hashicorp{
&:hover{
svg{
.svg-bg-line{
opacity: .4;
}
}
}
}
}
.nav.li-under a::after {
}
.nav > li > a:hover, .nav > li > a:focus {
background-color: transparent;
/*color: $p;
@include transition( color 0.3s ease );*/
}
.main-links.navbar-nav{
li + li::before {
content: "";
position: absolute;
left: 0;
top: 35px;
width: 4px;
height: 23px;
background: image-url('nav-dotpipes.png') 0 0 no-repeat;
@include img-retina("nav-dotpipes.png", "nav-dotpipes@2x.png", 4px, 23px);
padding-right: 15px;
}
/*li + li.li-under a::after{
left: 15px;
}*/
li > a {
line-height: 62px;
}
}
.buttons.navbar-nav{
margin-top: 26px;
margin-left: 30px;
li{
&.first{
margin-right: 12px;
}
&.download{
a{
background: image-url('icon-download.png') 8px 6px no-repeat;
@include img-retina("icon-download.png", "icon-download@2x.png", 20px, 20px);
}
}
&.github{
a{
background: image-url('icon-github.png') 8px 6px no-repeat;
@include img-retina("icon-github.png", "icon-github@2x.png", 20px, 20px);
}
}
}
li > a {
padding-top: 6px;
padding-bottom: 6px;
padding-left: 40px;
}
.buttons{
margin-top: 2px; //baseline everything
}
}
#footer{
height: 650px;
text-align: center;
color: $purple;
.main-links.navbar-nav{
float: none;
display: inline-block;
padding-top: 155px;
.li-under a::after {
background-color: $purple;
}
}
.footer-hashi{
padding-top: 110px;
}
a{
color: $purple;
}
.buttons.navbar-nav{
float: none;
display: inline-block;
margin-bottom: 30px;
margin-top: 0px;
li{
&.first{
margin-right: 12px;
}
&.download{
a{
background: image-url('icon-download-purple.png') 8px 6px no-repeat;
@include img-retina("icon-download-purple.png", "icon-download-purple@2x.png", 20px, 20px);
}
}
&.github{
a{
background: image-url('icon-github-purple.png') 8px 6px no-repeat;
@include img-retina("icon-github-purple.png", "icon-github-purple@2x.png", 20px, 20px);
}
}
}
li > a {
padding-top: 6px;
padding-bottom: 6px;
padding-left: 40px;
}
}
}
@media (max-width: 992px) {
@media (max-width: 414px) {
#header {
.brand {
.navbar-brand {
.logo{
width: 120px;
height: 39px;
margin-top: 12px;
background-size: 120px 39px;
}
}
padding-left: 37px;
@include img-retina("../images/consul-hero-logo.png", "../images/consul-hero-logo@2x.png", $project-logo-width * .75, $project-logo-height * .75);
.buttons.navbar-nav{
li{
a{
background: none !important;
padding-left: 15px;
img{
width: 72px;
height: 14px;
}
}
}
}
}
@media (max-width: 768px) {
#footer,
#header{
.buttons.navbar-nav,
.main-links.navbar-nav{
display: block;
padding-bottom: 15px;
li{
display: block;
float: none;
margin-top: 15px;
}
.li-under a::after,
li + li::before {
display: none;
}
}
}
#header,
#footer{
.main-links.navbar-nav{
li > a {
padding: 0;
padding-left: 0;
line-height: 22px;
}
}
}
#footer{
.footer-hashi {
span{
margin-right: 0;
}
.hashi-logo{
display: block;
margin-top: 15px;
margin-bottom: 20px;
}
}
.buttons.navbar-nav{
margin-left: 0;
li.first {
margin-right: 0 !important;
}
}
}
#header{
@include consul-gradient-bg();
.navbar-right{
float: none !important;
}
.brand {
@media (max-width: 320px) {
#header {
.navbar-brand {
.logo{
margin-top: 0;
}
}
.navbar-nav > li{
float: none;
}
.buttons.navbar-nav{
margin-top: 15px;
margin-left: 0px;
li{
a{
padding-left: 40px;
}
&.first{
margin-right: 0;
margin-bottom: 10px;
}
&.download{
a{
background: image-url('icon-download.png') 8px 6px no-repeat !important;;
@include img-retina("icon-download.png", "icon-download@2x.png", 20px, 20px);
}
}
&.github{
a{
background: image-url('icon-github.png') 8px 6px no-repeat !important;;
@include img-retina("icon-github.png", "icon-github@2x.png", 20px, 20px);
}
}
}
}
}
}
@media (max-width: 480px) {
}

View File

@ -127,37 +127,6 @@ body.page-home{
}
}
#footer{
background-color: $consul-footer-gray;
background: $consul-footer-gray image-url('consul-footer-logo.png') center center no-repeat;
@include img-retina("consul-footer-logo.png", "consul-footer-logo@2x.png", 446px, 443px);
.footer-links{
margin-bottom: 20px;
}
.footer-hashi{
letter-spacing: 2px;
margin-bottom: 30px;
a{
font-weight: $font-weight-museo-xb;
}
span{
margin-right: 20px;
}
img{
display: inline-block;
width: 37px;
height: 40px;
}
}
}
@media (max-width: 992px) {
#features{
top: $large-negative-hero-margin;
@ -174,6 +143,17 @@ body.page-home{
}
}
@media (max-width: 768px){
#cta{
text-align: center;
.intro{
.left{
text-align: center !important;
}
}
}
}
@media (max-width: 480px) {
#features{
text-align: center;
@ -236,7 +216,6 @@ body.page-home{
h2 {
font-size: 22px;
color: lighten($gray-light, 15%);
text-transform: uppercase;
font-family: $font-family-museo;
font-weight: $font-weight-museo-xb;

View File

@ -1,724 +0,0 @@
//
// Mixins
// --------------------------------------------------
// Utilities
// -------------------------
// Clearfix
// Source: http://nicolasgallagher.com/micro-clearfix-hack/
//
// For modern browsers
// 1. The space content is one way to avoid an Opera bug when the
// contenteditable attribute is included anywhere else in the document.
// Otherwise it causes space to appear at the top and bottom of elements
// that are clearfixed.
// 2. The use of `table` rather than `block` is only necessary if using
// `:before` to contain the top-margins of child elements.
@mixin clearfix() {
&:before,
&:after {
content: " "; /* 1 */
display: table; /* 2 */
}
&:after {
clear: both;
}
}
// Webkit-style focus
@mixin tab-focus() {
// Default
outline: thin dotted #333;
// Webkit
outline: 5px auto -webkit-focus-ring-color;
outline-offset: -2px;
}
// Center-align a block level element
@mixin center-block() {
display: block;
margin-left: auto;
margin-right: auto;
}
// Sizing shortcuts
@mixin size($width, $height) {
width: $width;
height: $height;
}
@mixin square($size) {
@include size($size, $size);
}
// Placeholder text
@mixin placeholder($color: $input-color-placeholder) {
&:-moz-placeholder { color: $color; } // Firefox 4-18
&::-moz-placeholder { color: $color; } // Firefox 19+
&:-ms-input-placeholder { color: $color; } // Internet Explorer 10+
&::-webkit-input-placeholder { color: $color; } // Safari and Chrome
}
// Text overflow
// Requires inline-block or block for proper styling
@mixin text-overflow() {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
// CSS image replacement
// Source: https://github.com/h5bp/html5-boilerplate/commit/aa0396eae757
@mixin hide-text() {
font: #{"0/0"} a;
color: transparent;
text-shadow: none;
background-color: transparent;
border: 0;
}
// CSS3 PROPERTIES
// --------------------------------------------------
// Single side border-radius
@mixin border-top-radius($radius) {
border-top-right-radius: $radius;
border-top-left-radius: $radius;
}
@mixin border-right-radius($radius) {
border-bottom-right-radius: $radius;
border-top-right-radius: $radius;
}
@mixin border-bottom-radius($radius) {
border-bottom-right-radius: $radius;
border-bottom-left-radius: $radius;
}
@mixin border-left-radius($radius) {
border-bottom-left-radius: $radius;
border-top-left-radius: $radius;
}
// Drop shadows
@mixin box-shadow($shadow) {
-webkit-box-shadow: $shadow; // iOS <4.3 & Android <4.1
box-shadow: $shadow;
}
// Transitions
@mixin transition($transition) {
-webkit-transition: $transition;
transition: $transition;
}
@mixin transition-delay($transition-delay) {
-webkit-transition-delay: $transition-delay;
transition-delay: $transition-delay;
}
@mixin transition-duration($transition-duration) {
-webkit-transition-duration: $transition-duration;
transition-duration: $transition-duration;
}
@mixin transition-transform($transition) {
-webkit-transition: -webkit-transform $transition;
-moz-transition: -moz-transform $transition;
-o-transition: -o-transform $transition;
transition: transform $transition;
}
// Transformations
@mixin rotate($degrees) {
-webkit-transform: rotate($degrees);
-ms-transform: rotate($degrees); // IE9+
transform: rotate($degrees);
}
@mixin scale($ratio) {
-webkit-transform: scale($ratio);
-ms-transform: scale($ratio); // IE9+
transform: scale($ratio);
}
@mixin translate($x, $y) {
-webkit-transform: translate($x, $y);
-ms-transform: translate($x, $y); // IE9+
transform: translate($x, $y);
}
@mixin skew($x, $y) {
-webkit-transform: skew($x, $y);
-ms-transform: skewX($x) skewY($y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+
transform: skew($x, $y);
}
@mixin translate3d($x, $y, $z) {
-webkit-transform: translate3d($x, $y, $z);
transform: translate3d($x, $y, $z);
}
// Backface visibility
// Prevent browsers from flickering when using CSS 3D transforms.
// Default value is `visible`, but can be changed to `hidden`
// See git pull https://github.com/dannykeane/bootstrap.git backface-visibility for examples
@mixin backface-visibility($visibility) {
-webkit-backface-visibility: $visibility;
-moz-backface-visibility: $visibility;
backface-visibility: $visibility;
}
// Box sizing
@mixin box-sizing($boxmodel) {
-webkit-box-sizing: $boxmodel;
-moz-box-sizing: $boxmodel;
box-sizing: $boxmodel;
}
// User select
// For selecting text on the page
@mixin user-select($select) {
-webkit-user-select: $select;
-moz-user-select: $select;
-ms-user-select: $select; // IE10+
-o-user-select: $select;
user-select: $select;
}
// Resize anything
@mixin resizable($direction) {
resize: $direction; // Options: horizontal, vertical, both
overflow: auto; // Safari fix
}
// CSS3 Content Columns
@mixin content-columns($column-count, $column-gap: $grid-gutter-width) {
-webkit-column-count: $column-count;
-moz-column-count: $column-count;
column-count: $column-count;
-webkit-column-gap: $column-gap;
-moz-column-gap: $column-gap;
column-gap: $column-gap;
}
// Optional hyphenation
@mixin hyphens($mode: auto) {
word-wrap: break-word;
-webkit-hyphens: $mode;
-moz-hyphens: $mode;
-ms-hyphens: $mode; // IE10+
-o-hyphens: $mode;
hyphens: $mode;
}
// Opacity
@mixin opacity($opacity) {
opacity: $opacity;
// IE8 filter
$opacity-ie: ($opacity * 100);
filter: #{"alpha(opacity=${opacity-ie})"};
}
// GRADIENTS
// --------------------------------------------------
#gradient {
// Horizontal gradient, from left to right
//
// Creates two color stops, start and end, by specifying a color and position for each color stop.
// Color stops are not available in IE9 and below.
@mixin horizontal($start-color: #555, $end-color: #333, $start-percent: 0%, $end-percent: 100%) {
background-image: -webkit-gradient(linear, $start-percent top, $end-percent top, from($start-color), to($end-color)); // Safari 4+, Chrome 2+
background-image: -webkit-linear-gradient(left, color-stop($start-color $start-percent), color-stop($end-color $end-percent)); // Safari 5.1+, Chrome 10+
background-image: -moz-linear-gradient(left, $start-color $start-percent, $end-color $end-percent); // FF 3.6+
background-image: linear-gradient(to right, $start-color $start-percent, $end-color $end-percent); // Standard, IE10
background-repeat: repeat-x;
// filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)",argb($start-color),argb($end-color))); // IE9 and down
}
// Vertical gradient, from top to bottom
//
// Creates two color stops, start and end, by specifying a color and position for each color stop.
// Color stops are not available in IE9 and below.
@mixin vertical($start-color: #555, $end-color: #333, $start-percent: 0%, $end-percent: 100%) {
background-image: -webkit-gradient(linear, left $start-percent, left $end-percent, from($start-color), to($end-color)); // Safari 4+, Chrome 2+
background-image: -webkit-linear-gradient(top, $start-color, $start-percent, $end-color, $end-percent); // Safari 5.1+, Chrome 10+
background-image: -moz-linear-gradient(top, $start-color $start-percent, $end-color $end-percent); // FF 3.6+
background-image: linear-gradient(to bottom, $start-color $start-percent, $end-color $end-percent); // Standard, IE10
background-repeat: repeat-x;
// filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",argb($start-color),argb($end-color))); // IE9 and down
}
@mixin directional($start-color: #555, $end-color: #333, $deg: 45deg) {
background-repeat: repeat-x;
background-image: -webkit-linear-gradient($deg, $start-color, $end-color); // Safari 5.1+, Chrome 10+
background-image: -moz-linear-gradient($deg, $start-color, $end-color); // FF 3.6+
background-image: linear-gradient($deg, $start-color, $end-color); // Standard, IE10
}
@mixin horizontal-three-colors($start-color: #00b3ee, $mid-color: #7a43b6, $color-stop: 50%, $end-color: #c3325f) {
background-image: -webkit-gradient(left, linear, 0 0, 0 100%, from($start-color), color-stop($color-stop, $mid-color), to($end-color));
background-image: -webkit-linear-gradient(left, $start-color, $mid-color $color-stop, $end-color);
background-image: -moz-linear-gradient(left, $start-color, $mid-color $color-stop, $end-color);
background-image: linear-gradient(to right, $start-color, $mid-color $color-stop, $end-color);
background-repeat: no-repeat;
// filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)",argb($start-color),argb($end-color))); // IE9 and down, gets no color-stop at all for proper fallback
}
@mixin vertical-three-colors($start-color: #00b3ee, $mid-color: #7a43b6, $color-stop: 50%, $end-color: #c3325f) {
background-image: -webkit-gradient(linear, 0 0, 0 100%, from($start-color), color-stop($color-stop, $mid-color), to($end-color));
background-image: -webkit-linear-gradient($start-color, $mid-color $color-stop, $end-color);
background-image: -moz-linear-gradient(top, $start-color, $mid-color $color-stop, $end-color);
background-image: linear-gradient($start-color, $mid-color $color-stop, $end-color);
background-repeat: no-repeat;
// filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",argb($start-color),argb($end-color))); // IE9 and down, gets no color-stop at all for proper fallback
}
@mixin radial($inner-color: #555, $outer-color: #333) {
background-image: -webkit-gradient(radial, center center, 0, center center, 460, from($inner-color), to($outer-color));
background-image: -webkit-radial-gradient(circle, $inner-color, $outer-color);
background-image: -moz-radial-gradient(circle, $inner-color, $outer-color);
background-image: radial-gradient(circle, $inner-color, $outer-color);
background-repeat: no-repeat;
}
@mixin striped($color: #555, $angle: 45deg) {
background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(.25, rgba(255,255,255,.15)), color-stop(.25, transparent), color-stop(.5, transparent), color-stop(.5, rgba(255,255,255,.15)), color-stop(.75, rgba(255,255,255,.15)), color-stop(.75, transparent), to(transparent));
background-image: -webkit-linear-gradient($angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent);
background-image: -moz-linear-gradient($angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent);
background-image: linear-gradient($angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent);
}
}
// Reset filters for IE
//
// When you need to remove a gradient background, do not forget to use this to reset
// the IE filter for IE9 and below.
@mixin reset-filter() {
// filter: e(%("progid:DXImageTransform.Microsoft.gradient(enabled = false)"));
}
// Retina images
//
// Short retina mixin for setting background-image and -size
@mixin img-retina($file-1x, $file-2x, $width-1x, $height-1x) {
background-image: image-url("#{$file-1x}");
background-size: $width-1x $height-1x;
@media
only screen and (-webkit-min-device-pixel-ratio: 2),
only screen and ( min--moz-device-pixel-ratio: 2),
only screen and ( -o-min-device-pixel-ratio: 2/1),
only screen and ( min-device-pixel-ratio: 2),
only screen and ( min-resolution: 192dpi),
only screen and ( min-resolution: 2dppx) {
background-image: image-url("#{$file-2x}");
background-size: $width-1x $height-1x;
}
}
// Responsive image
//
// Keep images from scaling beyond the width of their parents.
@mixin img-responsive($display: block) {
display: $display;
max-width: 100%; // Part 1: Set a maximum relative to the parent
height: auto; // Part 2: Scale the height according to the width, otherwise you get stretching
}
// COMPONENT MIXINS
// --------------------------------------------------
// Horizontal dividers
// -------------------------
// Dividers (basically an hr) within dropdowns and nav lists
@mixin nav-divider($color: #e5e5e5) {
height: 1px;
margin: (($line-height-computed / 2) - 1) 0;
overflow: hidden;
background-color: $color;
}
// Panels
// -------------------------
@mixin panel-variant($border, $heading-text-color, $heading-bg-color, $heading-border) {
border-color: $border;
& > .panel-heading {
color: $heading-text-color;
background-color: $heading-bg-color;
border-color: $heading-border;
+ .panel-collapse .panel-body {
border-top-color: $border;
}
}
& > .panel-footer {
+ .panel-collapse .panel-body {
border-bottom-color: $border;
}
}
}
// Alerts
// -------------------------
@mixin alert-variant($background, $border, $text-color) {
background-color: $background;
border-color: $border;
color: $text-color;
hr {
border-top-color: darken($border, 5%);
}
.alert-link {
color: darken($text-color, 10%);
}
}
// Tables
// -------------------------
@mixin table-row-variant($state, $background, $border) {
// Exact selectors below required to override `.table-striped` and prevent
// inheritance to nested tables.
.table > thead > tr,
.table > tbody > tr,
.table > tfoot > tr {
> td.#{state},
> th.#{state},
&.#{state} > td,
&.#{state} > th {
background-color: $background;
border-color: $border;
}
}
// Hove# states for `.table-hover`
// Note: this is not available for cells or rows within `thead` or `tfoot`.
.table-hover > tbody > tr {
> td.#{state}:hover,
> th.#{state}:hover,
&.#{state}:hover > td {
background-color: darken($background, 5%);
border-color: darken($border, 5%);
}
}
}
// Button variants
// -------------------------
// Easily pump out default styles, as well as :hover, :focus, :active,
// and disabled options for all buttons
@mixin button-variant($color, $background, $border) {
color: $color;
background-color: $background;
border-color: $border;
&:hover,
&:focus,
&:active,
&.active,
.open .dropdown-toggle& {
color: $color;
background-color: darken($background, 8%);
border-color: darken($border, 12%);
}
&:active,
&.active,
.open .dropdown-toggle& {
background-image: none;
}
&.disabled,
&[disabled],
fieldset[disabled] & {
&,
&:hover,
&:focus,
&:active,
&.active {
background-color: $background;
border-color: $border
}
}
}
// Button sizes
// -------------------------
@mixin button-size($padding-vertical, $padding-horizontal, $font-size, $line-height, $border-radius) {
padding: $padding-vertical $padding-horizontal;
font-size: $font-size;
line-height: $line-height;
border-radius: $border-radius;
}
// Pagination
// -------------------------
@mixin pagination-size($padding-vertical, $padding-horizontal, $font-size, $border-radius) {
> li {
> a,
> span {
padding: $padding-vertical $padding-horizontal;
font-size: $font-size;
}
&:first-child {
> a,
> span {
@include border-left-radius($border-radius);
}
}
&:last-child {
> a,
> span {
@include border-right-radius($border-radius);
}
}
}
}
// Labels
// -------------------------
@mixin label-variant($color) {
background-color: $color;
&[href] {
&:hover,
&:focus {
background-color: darken($color, 10%);
}
}
}
// Navbar vertical align
// -------------------------
// Vertically center elements in the navbar.
// Example: an element has a height of 30px, so write out `@include navbar-vertical-align(30px);` to calculate the appropriate top margin.
@mixin navbar-vertical-align($element-height) {
margin-top: (($navbar-height - $element-height) / 2);
margin-bottom: (($navbar-height - $element-height) / 2);
}
// Progress bars
// -------------------------
// @mixin progress-bar-variant($color) {
// background-color: $color;
// .progress-striped & {
// #gradient > @include striped($color);
// }
// }
// Responsive utilities
// -------------------------
// More easily include all the states for responsive-utilities.less.
@mixin responsive-visibility() {
display: block !important;
tr& { display: table-row !important; }
th&,
td& { display: table-cell !important; }
}
@mixin responsive-invisibility() {
display: none !important;
tr& { display: none !important; }
th&,
td& { display: none !important; }
}
// Grid System
// -----------
// Centered container element
@mixin container-fixed() {
margin-right: auto;
margin-left: auto;
padding-left: ($grid-gutter-width / 2);
padding-right: ($grid-gutter-width / 2);
@include clearfix();
}
// Creates a wrapper for a series of columns
@mixin make-row($gutter: $grid-gutter-width) {
margin-left: ($gutter / -2);
margin-right: ($gutter / -2);
@include clearfix();
}
// Generate the extra small columns
@mixin make-xs-column($columns, $gutter: $grid-gutter-width) {
position: relative;
float: left;
width: percentage(($columns / $grid-columns));
// Prevent columns from collapsing when empty
min-height: 1px;
// Inner gutter via padding
padding-left: ($gutter / 2);
padding-right: ($gutter / 2);
}
// Generate the small columns
@mixin make-sm-column($columns, $gutter: $grid-gutter-width) {
position: relative;
// Prevent columns from collapsing when empty
min-height: 1px;
// Inner gutter via padding
padding-left: ($gutter / 2);
padding-right: ($gutter / 2);
// Calculate width based on number of columns available
@media (min-width: $screen-sm) {
float: left;
width: percentage(($columns / $grid-columns));
}
}
// Generate the small column offsets
@mixin make-sm-column-offset($columns) {
@media (min-width: $screen-sm) {
margin-left: percentage(($columns / $grid-columns));
}
}
@mixin make-sm-column-push($columns) {
@media (min-width: $screen-sm) {
left: percentage(($columns / $grid-columns));
}
}
@mixin make-sm-column-pull($columns) {
@media (min-width: $screen-sm) {
right: percentage(($columns / $grid-columns));
}
}
// Generate the medium columns
@mixin make-md-column($columns, $gutter: $grid-gutter-width) {
position: relative;
// Prevent columns from collapsing when empty
min-height: 1px;
// Inner gutter via padding
padding-left: ($gutter / 2);
padding-right: ($gutter / 2);
// Calculate width based on number of columns available
@media (min-width: $screen-md) {
float: left;
width: percentage(($columns / $grid-columns));
}
}
// Generate the large column offsets
@mixin make-md-column-offset($columns) {
@media (min-width: $screen-md) {
margin-left: percentage(($columns / $grid-columns));
}
}
@mixin make-md-column-push($columns) {
@media (min-width: $screen-md) {
left: percentage(($columns / $grid-columns));
}
}
@mixin make-md-column-pull($columns) {
@media (min-width: $screen-md) {
right: percentage(($columns / $grid-columns));
}
}
// Generate the large columns
@mixin make-lg-column($columns, $gutter: $grid-gutter-width) {
position: relative;
// Prevent columns from collapsing when empty
min-height: 1px;
// Inner gutter via padding
padding-left: ($gutter / 2);
padding-right: ($gutter / 2);
// Calculate width based on number of columns available
@media (min-width: $screen-lg) {
float: left;
width: percentage(($columns / $grid-columns));
}
}
// Generate the large column offsets
@mixin make-lg-column-offset($columns) {
@media (min-width: $screen-lg) {
margin-left: percentage(($columns / $grid-columns));
}
}
@mixin make-lg-column-push($columns) {
@media (min-width: $screen-lg) {
left: percentage(($columns / $grid-columns));
}
}
@mixin make-lg-column-pull($columns) {
@media (min-width: $screen-lg) {
right: percentage(($columns / $grid-columns));
}
}
// Form validation states
//
// Used in forms.less to generate the form validation CSS for warnings, errors,
// and successes.
@mixin form-control-validation($text-color: #555, $border-color: #ccc, $background-color: #f5f5f5) {
// Color the label and help text
.help-block,
.control-label {
color: $text-color;
}
// Set the border and box shadow on specific inputs to match
.form-control {
border-color: $border-color;
@include box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); // Redeclare so transitions work
&:focus {
border-color: darken($border-color, 10%);
$shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 6px lighten($border-color, 20%);
@include box-shadow($shadow);
}
}
// Set validation states also for addons
.input-group-addon {
color: $text-color;
border-color: $border-color;
background-color: $background-color;
}
}
// Form control focus state
//
// Generate a customized focus state and for any input with the specified color,
// which defaults to the `$input-focus-border` variable.
//
// We highly encourage you to not customize the default value, but instead use
// this to tweak colors on an as-needed basis. This aesthetic change is based on
// WebKit's default styles, but applicable to a wider range of browsers. Its
// usability and accessibility should be taken into account with any change.
//
// Example usage: change the default blue border and shadow to white for better
// contrast against a dark gray background.
@mixin form-control-focus($color: $input-border-focus) {
$color-rgba: rgba(red($color), green($color), blue($color), .6);
&:focus {
border-color: $color;
outline: 0;
@include box-shadow(#{"inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px ${color-rgba}"});
}
}
// Form control sizing
//
// Relative text size, padding, and border-radii changes for form controls. For
// horizontal sizing, wrap controls in the predefined grid classes. `<select>`
// element gets special love because it's special, and that's a fact!
@mixin input-size($input-height, $padding-vertical, $padding-horizontal, $font-size, $line-height, $border-radius) {
height: $input-height;
padding: $padding-vertical $padding-horizontal;
font-size: $font-size;
line-height: $line-height;
border-radius: $border-radius;
select& {
height: $input-height;
line-height: $input-height;
}
textarea& {
height: auto;
}
}

View File

@ -0,0 +1,23 @@
//
// Sidebar
// - Project Specific
// - Make sidebar edits here
// --------------------------------------------------
.sidebar {
.sidebar-nav {
// Links
//----------------
li {
a {
color: $purple;
svg{
path{
fill: $purple;
}
}
}
}
}
}

View File

@ -20,5 +20,4 @@
background: -ms-linear-gradient(left, #694a9c 0%,#cd2028 100%); /* IE10+ */
background: linear-gradient(to right, #694a9c 0%,#cd2028 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#694a9c', endColorstr='#cd2028',GradientType=1 ); /* IE6-9 */
}

View File

@ -47,7 +47,7 @@ $link-hover-color: darken($link-color, 15%);
// Typography
// -------------------------
$font-family-museo: 'museo-sans', "Helvetica Neue", Helvetica, Arial, sans-serif;
$font-family-open-sans: 'Source Sans Pro', "Helvetica Neue", Helvetica, Arial, sans-serif;
$font-family-source-sans: 'Source Sans Pro', "Helvetica Neue", Helvetica, Arial, sans-serif;
$font-weight-museo-xl: 100;
$font-weight-museo-reg: 300;
$font-weight-museo-sb: 500;

View File

@ -3,11 +3,10 @@
@import "bootstrap";
// Remote fonts
@import url("//fonts.googleapis.com/css?family=Source+Sans+Pro:400,700");
@import url("//fonts.googleapis.com/css?family=Source+Sans+Pro:400,700|Open+Sans:300,600");
// Core variables and mixins
@import "_variables";
@import "_mixins";
// Utility classes
@import "_utilities";
@ -18,10 +17,18 @@
//Global Site
@import "_global";
// Hashicorp Shared Project Styles
@import 'hashicorp-shared/_hashicorp-utility';
@import 'hashicorp-shared/_project-utility';
@import 'hashicorp-shared/_hashicorp-header';
@import 'hashicorp-shared/_hashicorp-sidebar';
// Components
@import "_header";
@import '_footer';
@import "_jumbotron";
@import "_buttons";
@import '_sidebar';
// Pages
@import "_home";

View File

@ -0,0 +1,323 @@
//
// Hashicorp header
// - Shared throughout projects
// - Edits should not be made here
// --------------------------------------------------
#header{
position: relative;
margin-bottom: 0;
}
.navigation {
color: black;
text-rendering: optimizeLegibility;
transition: all 1s ease;
&.white{
.navbar-brand {
.logo {
color: white;
}
}
.main-links,
.external-links {
li > a {
&:hover{
opacity: 1;
}
}
}
}
.navbar-toggle{
height: $header-height;
margin: 0;
border-radius: 0;
.icon-bar{
border: 1px solid $black;
border-radius: 0;
}
}
.external-links {
&.white{
svg path{
fill: $white;
}
}
li {
position: relative;
svg path{
@include transition( all 300ms ease-in );
}
&:hover{
svg path{
@include transition( all 300ms ease-in );
}
}
&.download{
margin-right: 10px;
}
> a {
padding-left: 12px !important;
svg{
position: absolute;
left: -12px;
top: 50%;
margin-top: -7px;
width: 14px;
height: 14px;
}
}
}
}
.main-links{
margin-right: $nav-margin-right * 2;
}
.main-links,
.external-links {
&.white{
li > a {
color: white;
}
}
li > a {
@include hashi-a-style();
margin: 0 10px;
padding-top: 1px;
line-height: $header-height;
@include project-a-style();
}
}
.nav > li > a:hover, .nav > li > a:focus {
background-color: transparent;
@include transition( all 300ms ease-in );
}
}
.navbar-brand {
display: block;
height: $header-height;
padding: 0;
margin: 0 10px 0 0;
.logo{
display: inline-block;
height: $header-height;
vertical-align:top;
padding: 0;
line-height: $header-height;
padding-left: $project-logo-width + $project-logo-pad-left;
background-position: 0 center;
@include transition(all 300ms ease-in);
&:hover{
@include transition(all 300ms ease-in);
text-decoration: none;
}
}
}
.navbar-toggle{
&.white{
.icon-bar{
border: 1px solid white;
}
}
}
.by-hashicorp{
display: inline-block;
vertical-align:top;
height: $header-height;
margin-left: 3px;
padding-top: 2px;
color: black;
line-height: $header-height;
font-family: $header-font-family;
font-weight: 600;
font-size: 0;
text-decoration: none;
&.white{
color: white;
font-weight: 300;
svg{
path,
polygon,
rect{
fill: white;
}
}
}
&:focus,
&:hover{
text-decoration: none;
}
.svg-wrap{
font-size: 13px;
}
svg{
&.svg-by{
width: $by-hashicorp-width;
height: $by-hashicorp-height;
margin-bottom: -4px;
margin-left: 4px;
}
&.svg-logo{
width: 16px;
height: 16px;
margin-bottom: -3px;
margin-left: 4px;
}
path,
polygon{
fill: black;
@include transition(all 300ms ease-in);
&:hover{
@include transition(all 300ms ease-in);
}
}
.svg-bg-line{
@include transition(all 300ms ease-in);
&:hover{
@include transition(all 300ms ease-in);
}
}
}
}
.hashicorp-project{
display: inline-block;
height: 30px;
line-height: 30px;
text-decoration: none;
font-size: 14px;
color: $black;
font-weight: 600;
&.white{
color: white;
svg{
path,
polygon,
rect{
fill: white;
}
}
}
&:focus{
text-decoration: none;
}
&:hover{
text-decoration: none;
svg{
&.svg-by{
line{
stroke: $purple;
}
}
}
}
span{
margin-right: 4px;
font-family: $header-font-family;
font-weight: 500;
}
span,
svg{
display: inline-block;
}
svg{
&.svg-by{
width: $by-hashicorp-width;
height: $by-hashicorp-height;
margin-bottom: -4px;
margin-left: -3px;
}
&.svg-logo{
width: 30px;
height: 30px;
margin-bottom: -10px;
margin-left: -1px;
}
path,
line{
fill: $black;
@include transition(all 300ms ease-in);
&:hover{
@include transition(all 300ms ease-in);
}
}
}
}
@media (max-width: 992px) {
.navigation {
> .container{
width: 100%;
}
}
}
@media (max-width: 768px) {
.navigation {
.main-links{
margin-right: 0;
}
}
}
@media (max-width: 414px) {
#header {
.navbar-toggle{
padding-top: 10px;
height: $header-mobile-height;
}
.navbar-brand {
height: $header-mobile-height;
.logo{
height: $header-mobile-height;
line-height: $header-mobile-height;
}
.by-hashicorp{
height: $header-mobile-height;
line-height: $header-mobile-height;
padding-top: 0;
}
}
.main-links,
.external-links {
li > a {
line-height: $header-mobile-height;
}
}
}
}

View File

@ -0,0 +1,293 @@
//
// Hashicorp Sidebar
// - Shared throughout projects
// - Edits should not be made here
// --------------------------------------------------
// Base variables
// --------------------------------------------------
$screen-tablet: 768px;
$gray-darker: #212121; // #212121 - text
$gray-secondary: #757575; // #757575 - secondary text, icons
$gray: #bdbdbd; // #bdbdbd - hint text
$gray-light: #e0e0e0; // #e0e0e0 - divider
$gray-lighter: #f5f5f5; // #f5f5f5 - background
$link-color: $gray-darker;
$link-bg: transparent;
$link-hover-color: $gray-lighter;
$link-hover-bg: $gray-lighter;
$link-active-color: $gray-darker;
$link-active-bg: $gray-light;
$link-disabled-color: $gray-light;
$link-disabled-bg: transparent;
/* -- Sidebar style ------------------------------- */
// Sidebar variables
// --------------------------------------------------
$zindex-sidebar-fixed: 1035;
$sidebar-desktop-width: 280px;
$sidebar-width: 240px;
$sidebar-padding: 16px;
$sidebar-divider: $sidebar-padding/2;
$sidebar-icon-width: 40px;
$sidebar-icon-height: 20px;
@mixin sidebar-nav-base {
text-align: center;
&:last-child{
border-bottom: none;
}
li > a {
background-color: $link-bg;
}
li:hover > a {
background-color: $link-hover-bg;
}
li:focus > a, li > a:focus {
background-color: $link-bg;
}
> .open > a {
&,
&:hover,
&:focus {
background-color: $link-hover-bg;
}
}
> .active > a {
&,
&:hover,
&:focus {
background-color: $link-active-bg;
}
}
> .disabled > a {
&,
&:hover,
&:focus {
background-color: $link-disabled-bg;
}
}
// Dropdown menu items
> .dropdown {
// Remove background color from open dropdown
> .dropdown-menu {
background-color: $link-hover-bg;
> li > a {
&:focus {
background-color: $link-hover-bg;
}
&:hover {
background-color: $link-hover-bg;
}
}
> .active > a {
&,
&:hover,
&:focus {
color: $link-active-color;
background-color: $link-active-bg;
}
}
}
}
}
//
// Sidebar
// --------------------------------------------------
// Sidebar Elements
//
// Basic style of sidebar elements
.sidebar {
position: relative;
display: block;
min-height: 100%;
overflow-y: auto;
overflow-x: hidden;
border: none;
@include transition(all 0.5s cubic-bezier(0.55, 0, 0.1, 1));
@include clearfix();
background-color: $white;
ul{
padding-left: 0;
list-style-type: none;
}
.sidebar-divider, .divider {
width: 80%;
height: 1px;
margin: 8px auto;
background-color: lighten($gray, 20%);
}
// Sidebar heading
//----------------
.sidebar-header {
position: relative;
margin-bottom: $sidebar-padding;
@include transition(all .2s ease-in-out);
}
.sidebar-image {
padding-top: 24px;
img {
display: block;
margin: 0 auto;
}
}
// Sidebar icons
//----------------
.sidebar-icon {
display: inline-block;
height: $sidebar-icon-height;
margin-right: $sidebar-divider;
text-align: left;
font-size: $sidebar-icon-height;
vertical-align: middle;
&:before, &:after {
vertical-align: middle;
}
}
.sidebar-nav {
margin: 0;
padding: 0;
@include sidebar-nav-base();
// Links
//----------------
li {
position: relative;
list-style-type: none;
text-align: center;
a {
position: relative;
cursor: pointer;
user-select: none;
@include hashi-a-style-core();
svg{
top: 2px;
width: 14px;
height: 14px;
margin-bottom: -2px;
margin-right: 4px;
}
}
}
}
}
// Sidebar toggling
//
// Hide sidebar
.sidebar {
width: 0;
@include translate3d(-$sidebar-desktop-width, 0, 0);
&.open {
min-width: $sidebar-desktop-width;
width: $sidebar-desktop-width;
@include translate3d(0, 0, 0);
}
}
// Sidebar positions: fix the left/right sidebars
.sidebar-fixed-left,
.sidebar-fixed-right,
.sidebar-stacked {
position: fixed;
top: 0;
bottom: 0;
z-index: $zindex-sidebar-fixed;
}
.sidebar-stacked {
left: 0;
}
.sidebar-fixed-left {
left: 0;
box-shadow: 2px 0px 25px rgba(0,0,0,0.15);
-webkit-box-shadow: 2px 0px 25px rgba(0,0,0,0.15);
}
.sidebar-fixed-right {
right: 0;
box-shadow: 0px 2px 25px rgba(0,0,0,0.15);
-webkit-box-shadow: 0px 2px 25px rgba(0,0,0,0.15);
@include translate3d($sidebar-desktop-width, 0, 0);
&.open {
@include translate3d(0, 0, 0);
}
.icon-material-sidebar-arrow:before {
content: "\e614"; // icon-material-arrow-forward
}
}
// Sidebar size
//
// Change size of sidebar and sidebar elements on small screens
@media (max-width: $screen-tablet) {
.sidebar.open {
min-width: $sidebar-width;
width: $sidebar-width;
}
.sidebar .sidebar-header {
//height: $sidebar-width * 9/16; // 16:9 header dimension
}
.sidebar .sidebar-image {
/* img {
width: $sidebar-width/4 - $sidebar-padding;
height: $sidebar-width/4 - $sidebar-padding;
} */
}
}
.sidebar-overlay {
visibility: hidden;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
opacity: 0;
background: $white;
z-index: $zindex-sidebar-fixed - 1;
-webkit-transition: visibility 0 linear .4s,opacity .4s cubic-bezier(.4,0,.2,1);
-moz-transition: visibility 0 linear .4s,opacity .4s cubic-bezier(.4,0,.2,1);
transition: visibility 0 linear .4s,opacity .4s cubic-bezier(.4,0,.2,1);
-webkit-transform: translateZ(0);
-moz-transform: translateZ(0);
-ms-transform: translateZ(0);
-o-transform: translateZ(0);
transform: translateZ(0);
}
.sidebar-overlay.active {
opacity: 0.3;
visibility: visible;
-webkit-transition-delay: 0;
-moz-transition-delay: 0;
transition-delay: 0;
}

View File

@ -0,0 +1,87 @@
//
// Hashicorp Nav (header/footer) Utiliy Vars and Mixins
//
// Notes:
// - Include this in Application.scss before header and feature-footer
// - Open Sans Google (Semibold - 600) font needs to be included if not already
// --------------------------------------------------
// Variables
$font-family-open-sans: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
$header-font-family: $font-family-open-sans;
$header-font-weight: 600; // semi-bold
$header-height: 74px;
$header-mobile-height: 60px;
$by-hashicorp-width: 74px;
$by-hashicorp-height: 16px;
$nav-margin-right: 12px;
// Mixins
@mixin hashi-a-style-core{
font-family: $header-font-family;
font-weight: $header-font-weight;
font-size: 14px;
//letter-spacing: 0.0625em;
}
@mixin hashi-a-style{
margin: 0 15px;
padding: 0;
line-height: 22px;
@include hashi-a-style-core();
@include transition( all 0.3s ease );
&:hover{
@include transition( all 0.3s ease );
background-color: transparent;
}
}
//general shared project mixins
@mixin img-retina($image1x, $image, $width, $height) {
background-image: url($image1x);
background-size: $width $height;
background-repeat: no-repeat;
@media (min--moz-device-pixel-ratio: 1.3),
(-o-min-device-pixel-ratio: 2.6/2),
(-webkit-min-device-pixel-ratio: 1.3),
(min-device-pixel-ratio: 1.3),
(min-resolution: 1.3dppx) {
/* on retina, use image that's scaled by 2 */
background-image: url($image);
background-size: $width $height;
}
}
//
// -------------------------
@mixin anti-alias() {
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
}
@mixin open-light() {
font-family: $font-family-open-sans;
font-weight: 300;
}
@mixin open() {
font-family: $font-family-open-sans;
font-weight: 400;
}
@mixin open-sb() {
font-family: $font-family-open-sans;
font-weight: 600;
}
@mixin open-bold() {
font-family: $font-family-open-sans;
font-weight: 700;
}
@mixin bez-1-transition{
@include transition( all 300ms ease-in-out );
}

View File

@ -0,0 +1,28 @@
//
// Mixins Specific to project
// - make edits to mixins here
// --------------------------------------------------
// Variables
$project-logo-width: 40px;
$project-logo-height: 40px;
$project-logo-pad-left: 0px;
// Mixins
@mixin project-a-style{
font-weight: 300;
opacity: .75;
&:hover{
color: $white;
opacity: 1;
}
}
@mixin project-footer-a-style{
line-height: 30px;
&:hover{
opacity: .5;
}
}

View File

@ -93,6 +93,59 @@ description: |-
<div class="clearfix"></div>
<div class="person">
<img class="pull-left" src="//avatars0.githubusercontent.com/u/1642288?v=3&amp;s=125">
<div class="bio">
<h3>Ryan Uber (<a href="https://github.com/ryanuber">@ryanuber</a>)</h3>
<p>
Ryan Uber is a core contributor to Consul where he works on all
facets of Consul. He is also a core committer to
<a href="https://www.serfdom.io">Serf</a>,
<a href="https://www.nomadproject.io">Nomad</a>, and
the Consul tools ecosystem, all while being an employee at
<a href="https://www.hashicorp.com">HashiCorp</a>.
</p>
</div>
</div>
<div class="clearfix"></div>
<div class="person">
<img class="pull-left" src="//avatars3.githubusercontent.com/u/673509?v=3&amp;s=125">
<div class="bio">
<h3>James Phillips (<a href="https://github.com/slackpad">@slackpad</a>)</h3>
<p>
James Phillips is a core contributor to Consul where he works on all
facets of Consul, including network tomography and prepared
queries. He is also a core committer to
<a href="https://www.serfdom.io">Serf</a> and
the Consul tools ecosystem, all while being an employee at
<a href="https://www.hashicorp.com">HashiCorp</a>.
</p>
</div>
</div>
<div class="clearfix"></div>
<div class="person">
<img class="pull-left" src="//avatars1.githubusercontent.com/u/408570?v=3&amp;s=125">
<div class="bio">
<h3>Seth Vargo (<a href="https://github.com/sethvargo">@sethvargo</a>)</h3>
<p>
Seth Vargo is a contributor to Consul, but his main focus is the
<a href="https://www.consul.io/downloads_tools.html">Consul tools ecosystem</a>.
He is also a core committer to
<a href="https://www.vagrantup.com">Vagrant</a>,
<a href="https://www.packer.io">Packer</a>, and
<a href="https://www.vaultproject.io">Vault</a>, and many more
open source projects, all while being an employee at
<a href="https://www.hashicorp.com">HashiCorp</a>.
</p>
</div>
</div>
<div class="clearfix"></div>
<div class="person">
<img class="pull-left" src="//www.gravatar.com/avatar/1e87e6016a7c4f4ecbd2517d84058467.png?s=125">
<div class="bio">

View File

@ -127,6 +127,7 @@ A TTL check:
```
A Docker check:
```javascript
{
"check": {

View File

@ -15,7 +15,7 @@ descriptions.
When loading configuration, Consul loads the configuration from files
and directories in lexical order. For example, configuration file `basic_config.json`
will be processed before `extra_config.js`. Configuration specified later
will be processed before `extra_config.json`. Configuration specified later
will be merged into configuration specified earlier. In most cases,
"merge" means that the later version will override the earlier. In
some cases, such as event handlers, merging appends the handlers to the
@ -504,6 +504,11 @@ definitions support being updated during a reload.
* <a name="protocol"></a><a href="#protocol">`protocol`</a> Equivalent to the
[`-protocol` command-line flag](#_protocol).
* <a name="reap"></a><a href="#reap">`reap`</a> controls Consul's automatic reaping of child processes, which
is useful if Consul is running as PID 1 in a Docker container. If this isn't specified, then Consul will
automatically reap child processes if it detects it is running as PID 1. If this is specified, then it
controls reaping regardless of Consul's PID.
* <a name="recursor"></a><a href="#recursor">`recursor`</a> Provides a single recursor address.
This has been deprecated, and the value is appended to the [`recursors`](#recursors) list for
backwards compatibility.
@ -557,24 +562,25 @@ definitions support being updated during a reload.
* <a name="start_join_wan"></a><a href="#start_join_wan">`start_join_wan`</a> An array of strings specifying
addresses of WAN nodes to [`-join-wan`](#_join_wan) upon startup.
* <a name="statsd_addr"></a><a href="#statsd_addr">`statsd_addr`</a> This provides the address of a statsd
instance. If provided, Consul will send various telemetry information to that instance for aggregation.
This can be used to capture runtime information. This sends UDP packets only and can be used with statsd
or statsite.
* <a name="statsd_addr"></a><a href="#statsd_addr">`statsd_addr`</a> This provides the address of a
statsd instance in the format `host:port`. If provided, Consul will send various telemetry information
to that instance for aggregation. This can be used to capture runtime information. This sends UDP packets
only and can be used with statsd or statsite.
* <a name="dogstatsd_addr"></a><a href="#dogstatsd_addr">`dogstatsd_addr`</a> This provides the
address of a DogStatsD instance. DogStatsD is a protocol-compatible flavor of statsd, with the added ability
to decorate metrics with tags and event information. If provided, Consul will send various telemetry information
to that instance for aggregation. This can be used to capture runtime information.
address of a DogStatsD instance in the format `host:port`. DogStatsD is a protocol-compatible flavor of
statsd, with the added ability to decorate metrics with tags and event information. If provided, Consul will
send various telemetry information to that instance for aggregation. This can be used to capture runtime
information.
* <a name="dogstatsd_tags"></a><a href="#dogstatsd_tags">`dogstatsd_tags`</a> This provides a list of global tags
that will be added to all telemetry packets sent to DogStatsD. It is a list of strings, where each string
looks like "my_tag_name:my_tag_value".
* <a name="statsite_addr"></a><a href="#statsite_addr">`statsite_addr`</a> This provides the address of a
statsite instance. If provided, Consul will stream various telemetry information to that instance for
aggregation. This can be used to capture runtime information. This streams via
TCP and can only be used with statsite.
statsite instance in the format `host:port`. If provided, Consul will stream various telemetry information
to that instance for aggregation. This can be used to capture runtime information. This streams via TCP and
can only be used with statsite.
* <a name="statsite_prefix"></a><a href="#statsite_prefix">`statsite_prefix`</a>
The prefix used while writing all telemetry data to statsite. By default, this

View File

@ -38,6 +38,11 @@ The list of available flags are:
to send this command. If this isn't specified, the command will contact
"127.0.0.1:8500" which is the default HTTP address of a Consul agent.
The following environment variables control accessing the HTTP server via SSL:
* `CONSUL_HTTP_SSL` Set this to enable SSL
* `CONSUL_HTTP_SSL_VERIFY` Set this to disable certificate checking (not recommended)
## Output
If coordinates are available, the command will print the estimated round trip

View File

@ -18,7 +18,7 @@ Atlas is able to securely retrieve data from nodes as Consul maintains a long-ru
To enable Atlas integration, you must specify the name of the Atlas infrastructure and the Atlas authentication
token in your Consul configuration. The Atlas infrastructure name can be set either with the [`-atlas` CLI flag](/docs/agent/options.html#_atlas) or with the [`atlas_infrastructure` configuration option](/docs/agent/options.html#atlas_infrastructure). The Atlas token is set with the [`-atlas-token` CLI flag](/docs/agent/options.html#_atlas_token),
[`-atlas-token` configuration option](/docs/agent/options.html#atlas_token), or `ATLAS_TOKEN` environment variable.
[`atlas_token` configuration option](/docs/agent/options.html#atlas_token), or `ATLAS_TOKEN` environment variable.
To get an Atlas username and token, [create an account here](https://atlas.hashicorp.com/account/new?utm_source=oss&utm_medium=guide-atlas&utm_campaign=consul) and replace the respective values in your Consul configuration with your credentials.

View File

@ -39,11 +39,11 @@ downloadable versions of the tool.
Consul 0.6 introduces enhancements to the ACL system which may require special
handling:
* Service ACL's are enforced during service discovery (REST + DNS)
* Service ACLs are enforced during service discovery (REST + DNS)
Previously, service discovery was wide open, and any client could query
information about any service without providing a token. Consul now requires
read-level access at a minimum when ACL's are enabled to return service
read-level access at a minimum when ACLs are enabled to return service
information over the REST or DNS interfaces. If clients depend on an open
service discovery system, then the following should be added to all ACL tokens
which require it:
@ -57,6 +57,40 @@ Note that the agent's [`acl_token`](/docs/agent/options.html#acl_token) is used
when the DNS interface is queried, so be sure that token has sufficient
privileges to return the DNS records you expect to retrieve from it.
* Event and keyring ACLs
Similar to service discovery, the new event and keyring ACLs will block access
to these operations if the `acl_default_policy` is set to `deny`. If clients depend
on open access to these, then the following should be added to all ACL tokens which
require them:
event "" {
policy = "write"
}
keyring = "write"
Unfortunately, these are new ACLs for Consul 0.6, so they must be added after the
upgrade is complete.
#### Prepared Queries
Prepared queries introduce a new Raft log entry type that isn't supported on older
versions of Consul. It's important to not use the prepared query features of Consul
until all servers in a cluster have been upgraded to version 0.6.0.
#### Single Private IP Enforcement
Consul will refuse to start if there are multiple private IPs available, so
if this is the case you will need to configure Consul's advertise or bind addresses
before upgrading.
#### New Web UI File Layout
The release .zip file for Consul's web UI no longer contains a `dist` sub-folder;
everything has been moved up one level. If you have any automated scripts that
expect the old layout you may need to update them.
## Consul 0.5.1
Consul version 0.5.1 uses a different backend store for persisting the Raft

View File

@ -178,6 +178,8 @@ description: Service discovery and configuration made easy. Distributed, highly
<p> "Value": <span class="txt-p">"YmFy"</span></p>
<p> }</p>
<p>]</p>
<p class="command"><span class="txt-r">admin@hashicorp</span>: echo "YmFy" | base64 --decode</p>
<p>bar</p>
<p class="command"><span class="txt-r">admin@hashicorp</span>: <span class="cursor">&nbsp;</span></p>
</div>
</div>
@ -196,7 +198,7 @@ description: Service discovery and configuration made easy. Distributed, highly
<p>The intro and getting started guide contain
a simple and approachable walkthrough for running Consul locally.</p>
</div>
<div class="col-xs-offset-5 col-xs-12 col-sm-6 col-sm-offset-0 right">
<div class="col-xs-12 col-sm-6 col-sm-offset-0 right">
<a class="outline-btn purple" href="/intro/index.html">Read the intro &#187;</a>
</div>
</div>

View File

@ -28,7 +28,6 @@ For simplicity, we'll run a single Consul agent in server mode:
$ consul agent -server -bootstrap-expect 1 -data-dir /tmp/consul
==> WARNING: BootstrapExpect Mode is specified as 1; this is the same as Bootstrap mode.
==> WARNING: Bootstrap mode enabled! Do not enable unless necessary
==> WARNING: It is highly recommended to set GOMAXPROCS higher than 1
==> Starting Consul agent...
==> Starting Consul agent RPC...
==> Consul agent running!

View File

@ -40,7 +40,7 @@ and replace the respective values in your Consul configuration with
your credentials.
You can view a live demo
[here](https://atlas.hashicorp.com/hashicorp/infrastructures/consul-demo).
[here](https://atlas.hashicorp.com/hashicorp/environments/consul-demo).
## Self-hosted Dashboard

View File

@ -1,29 +1,40 @@
<div id="footer">
<div id="footer" class="navigation">
<div class="container">
<div class="footer-links">
<ul class="main-links nav navbar-nav rls-sb">
<li class="li-under"><a href="/intro/index.html">Intro</a></li>
<li class="active li-under"><a href="/docs/index.html">Docs</a></li>
<li class="li-under"><a href="/community.html">Community</a></li>
<li class="li-under"><a href="http://demo.consul.io/">Demo</a></li>
<div class="row">
<div class="col-xs-12">
<% if current_page.url != '/' %>
<li class="li-under"><a href="<%= github_url :current_page %>">Edit this page</a></li>
<div class="edit-page-link"><a href="<%= github_url :current_page %>">Edit this page</a></div>
<% end %>
<div>
<ul class="main-links white nav navbar-nav">
<li><a href="/intro/index.html">Intro</a></li>
<li><a href="/docs/index.html">Docs</a></li>
<li><a href="/community.html">Community</a></li>
<li><a href="http://demo.consul.io/">Demo</a></li>
</ul>
<ul class="buttons nav navbar-nav rls-sb">
<li class="first download outline-btn purple"><a href="/downloads.html">Download</a></li>
<li class="github outline-btn purple"><a href="https://github.com/hashicorp/consul">GitHub</a></li>
<ul class="external-links white nav navbar-nav">
<li class="first download">
<a href="/downloads.html"><%= partial "layouts/svg/svg-download" %>Download</a>
</li>
<li class="github">
<a href="https://github.com/hashicorp/consul"><%= partial "layouts/svg/svg-github" %>GitHub</a>
</li>
</ul>
</div>
<div class="footer-logo">
<span></span>
</div>
<div class="footer-hashi os">
<span>Copyright &copy; <%= Time.now.year %>. A <a href="https://www.hashicorp.com">HashiCorp</a> Project.</span>
<a class="hashi-logo" href="http://www.hashicorp.com"><%= image_tag 'footer-hashicorp-logo.png' %></a>
</ div>
<div class="footer-hashi pull-right">
<div class="">
<a class="hashicorp-project white" href="https://www.hashicorp.com">
<span class="project-text">A </span>
<%= partial "layouts/svg/svg-by-hashicorp" %>
<span class="project-text">Project</span>
<%= partial "layouts/svg/svg-hashicorp-logo" %>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>

View File

@ -25,26 +25,33 @@
</head>
<body class="page-<%= current_page.data.page_title ? "#{current_page.data.page_title} layout-#{current_page.data.layout} page-sub" : "home layout-#{current_page.data.layout}" %>">
<div id="header" class="<%= current_page.data.page_title == "home" ? "" : "navbar-static-top" %>">
<div id="header" class="navigation <%= current_page.data.page_title == "home" ? "" : "navbar-static-top" %>">
<div class="container">
<div class="row">
<div class="col-xs-12">
<div class="navbar-header">
<button class="navbar-toggle" type="button" data-toggle="collapse" data-target=".bs-navbar-collapse">
<div class="navbar-brand">
<a class="logo" href="/"><img src="<%= image_path('wordtype@2x.png') %>" width="96px" height="18px">Consul</a>
<a class="by-hashicorp white" href="https://hashicorp.com/"><span class="svg-wrap">by</span><%= partial "layouts/svg/svg-by-hashicorp" %><%= partial "layouts/svg/svg-hashicorp-logo" %>Hashicorp</a>
</div>
<button class="navbar-toggle white" type="button">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<div class="brand">
<a class="logo" href="/"></a>
</div>
</div>
<nav class="collapse navbar-collapse bs-navbar-collapse" role="navigation">
<ul class="buttons nav navbar-nav navbar-right rls-sb">
<li class="first download outline-btn"><a href="/downloads.html">Download</a></li>
<li class="github outline-btn"><a href="https://github.com/hashicorp/consul">GitHub</a></li>
<div class="buttons hidden-xs">
<nav class="navigation-links" role="navigation">
<ul class="external-links white nav navbar-nav navbar-right">
<li class="first download">
<a href="/downloads.html"><%= partial "layouts/svg/svg-download" %>Download</a>
</li>
<li class="github">
<a href="https://github.com/hashicorp/consul"><%= partial "layouts/svg/svg-github" %>GitHub</a>
</li>
</ul>
<ul class="main-links nav navbar-nav navbar-right rls-sb">
<ul class="main-links white nav navbar-nav navbar-right">
<li class="first li-under"><a href="/intro/index.html">Intro</a></li>
<li class="li-under"><a href="/docs/index.html">Docs</a></li>
<li class="li-under"><a href="/community.html">Community</a></li>
@ -53,3 +60,6 @@
</nav>
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,27 @@
<!-- Overlay for fixed sidebar -->
<div class="sidebar-overlay"></div>
<!-- Material sidebar -->
<aside id="sidebar" class="sidebar sidebar-default sidebar-fixed-right" role="navigation">
<!-- Sidebar header -->
<div class="sidebar-header header-cover">
<!-- Sidebar brand image -->
<div class="sidebar-image">
<img src="<%= image_path('logo-header-gradient@2x.png') %>" width="50px" height="50px">
</div>
</div>
<!-- Sidebar navigation -->
<ul class="main nav sidebar-nav">
<li class="first"><a href="/intro/index.html">Intro</a></li>
<li class=""><a href="/docs/index.html">Docs</a></li>
<li class=""><a href="/community.html">Community</a></li>
<li class=""><a href="http://demo.consul.io/">Demo</a></li>
</ul>
<div class="divider"></div>
<!-- Sidebar navigation 2-->
<ul class="external nav sidebar-nav">
<li class="first"><a class="v-btn gray sml" href="/downloads.html"><%= partial "layouts/svg/svg-download" %>Download</a></li>
<li class=""><a class="v-btn gray sml" href="https://github.com/hashicorp/consul"><%= partial "layouts/svg/svg-github" %>GitHub</a></li>
</ul>
</aside>

View File

@ -3,7 +3,7 @@
<div class="col-md-4">
<%= yield_content :sidebar %>
</div> <!-- /col-md-4 -->
<div class="col-md-8" role="main">
<div id="main-content" class="col-md-8" role="main">
<div class="bs-docs-section">
<%= yield %>
</div>

View File

@ -1,3 +1,4 @@
<%= partial "layouts/header" %>
<%= partial "layouts/sidebar" %>
<%= yield %>
<%= partial "layouts/footer" %>

View File

@ -0,0 +1,17 @@
<svg class="svg-by" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="-1337.4 1130.1 73.8 16.1" xml:space="preserve" enable-background="new -1337.4 1130.1 73.8 16.1">
<g>
<path d="M-1329.6 1142.4v-4.9h-4.3v4.9h-2.2v-11.6h2.2v4.8h4.3v-4.8h2.2v11.6H-1329.6z"/>
<path d="M-1318.8 1142.4h-1.7l-0.2-0.6c-0.8 0.5-1.7 0.8-2.5 0.8 -1.6 0-2.2-1.1-2.2-2.5 0-1.7 0.8-2.4 2.5-2.4h2v-0.9c0-0.9-0.3-1.3-1.6-1.3 -0.8 0-1.6 0.1-2.4 0.3l-0.3-1.6c0.8-0.2 2-0.4 2.9-0.4 2.7 0 3.5 0.9 3.5 3.1V1142.4zM-1321 1139.2h-1.6c-0.7 0-0.9 0.2-0.9 0.8 0 0.6 0.2 0.9 0.9 0.9 0.6 0 1.2-0.2 1.6-0.4V1139.2z"/>
<path d="M-1314.2 1142.6c-0.9 0-2.1-0.2-2.9-0.5l0.3-1.6c0.7 0.2 1.7 0.4 2.5 0.4 0.9 0 1.1-0.2 1.1-0.9 0-0.5-0.1-0.8-1.5-1.1 -2.1-0.5-2.3-1-2.3-2.7s0.8-2.5 3.2-2.5c0.8 0 1.8 0.1 2.5 0.3l-0.2 1.7c-0.6-0.1-1.7-0.2-2.3-0.2 -0.9 0-1.1 0.2-1.1 0.7 0 0.7 0.1 0.7 1.2 1 2.4 0.6 2.6 0.9 2.6 2.7C-1311.1 1141.6-1311.6 1142.6-1314.2 1142.6z"/>
<path d="M-1304.3 1142.4v-5.9c0-0.5-0.2-0.7-0.7-0.7s-1.4 0.3-2.2 0.7v5.9h-2.1v-12l2.1-0.3v4.4c0.9-0.5 2.2-0.8 3.1-0.8 1.4 0 1.9 1 1.9 2.5v6.2H-1304.3L-1304.3 1142.4z"/>
<path d="M-1300.1 1132.7v-2.5h2.1v2.5H-1300.1zM-1300.1 1142.4v-8.5h2.1v8.5H-1300.1z"/>
<path d="M-1296 1134c0-2.1 1.2-3.4 4.1-3.4 1.1 0 2.2 0.1 3.2 0.4l-0.2 1.9c-0.9-0.2-2-0.3-2.8-0.3 -1.5 0-2 0.5-2 1.8v4.5c0 1.2 0.5 1.8 2 1.8 0.8 0 1.9-0.1 2.8-0.3l0.2 1.9c-1 0.2-2.1 0.4-3.2 0.4 -2.9 0-4.1-1.2-4.1-3.4V1134z"/>
<path d="M-1283.8 1142.6c-2.9 0-3.7-1.6-3.7-3.3v-2.1c0-1.7 0.8-3.4 3.7-3.4s3.7 1.6 3.7 3.4v2.1C-1280.1 1141-1280.9 1142.6-1283.8 1142.6zM-1283.8 1135.6c-1.1 0-1.6 0.5-1.6 1.5v2.3c0 1 0.4 1.5 1.6 1.5 1.1 0 1.6-0.5 1.6-1.5v-2.4C-1282.2 1136.1-1282.7 1135.6-1283.8 1135.6z"/>
<path d="M-1273.9 1135.7c-0.8 0.4-1.5 0.8-2.3 1.2v5.5h-2.1v-8.5h1.8l0.1 0.9c0.5-0.3 1.5-0.9 2.2-1.1L-1273.9 1135.7z"/>
<path d="M-1265.6 1139.6c0 1.9-0.8 3-2.8 3 -0.8 0-1.6-0.1-2.3-0.2v3.5l-2.1 0.3V1134h1.7l0.2 0.7c0.8-0.5 1.6-0.9 2.7-0.9 1.7 0 2.6 1 2.6 2.9V1139.6L-1265.6 1139.6zM-1270.6 1140.5c0.6 0.1 1.3 0.2 1.9 0.2 0.8 0 1.1-0.4 1.1-1.1v-3c0-0.7-0.3-1.1-1-1.1 -0.7 0-1.4 0.3-1.9 0.8L-1270.6 1140.5 -1270.6 1140.5z"/>
</g>
<g class="svg-bg-line">
<rect x="-1268" y="1145" width="4.3" height="1"/>
<rect x="-1338" y="1145" width="63" height="1"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -0,0 +1,4 @@
<svg id="svg-download" xmlns="http://www.w3.org/2000/svg" viewBox="-345 275 28 28" style="enable-background:new -345 275 28 28;">
<path d="M-319,275h-24c-1.1,0-2,0.9-2,2v24c0,1.1,0.9,2,2,2h24c1.1,0,2-0.9,2-2v-24C-317,275.9-317.9,275-319,275z M-331.2,297.9
l-6.8-5.6l2-2.4l3.2,2.6V282h3.2v10.5l3.2-2.6l2,2.4L-331.2,297.9z"/>
</svg>

After

Width:  |  Height:  |  Size: 333 B

View File

@ -0,0 +1,7 @@
<svg id="svg-download" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14 14" style="enable-background:new 0 0 14 14;">
<path d="M13,0H1C0.5,0,0,0.5,0,1v12c0,0.5,0.5,1,1,1h4.7c0,0,0,0,0-0.1c0-0.2,0-0.6,0-1.1c-1.8,0.4-2.2-0.9-2.2-0.9
c-0.3-0.8-0.7-1-0.7-1c-0.6-0.4,0-0.4,0-0.4c0.7,0,1,0.7,1,0.7c0.6,1,1.5,0.7,1.9,0.5c0.1-0.4,0.2-0.7,0.4-0.9c-1.5-0.2-3-0.7-3-3.2
c0-0.7,0.3-1.3,0.7-1.8C3.7,5.8,3.5,5.1,3.9,4.2c0,0,0.6-0.2,1.8,0.7c0.5-0.1,1.1-0.2,1.6-0.2c0.6,0,1.1,0.1,1.6,0.2
c1.3-0.8,1.8-0.7,1.8-0.7c0.4,0.9,0.1,1.6,0.1,1.7c0.4,0.5,0.7,1,0.7,1.8c0,2.5-1.5,3.1-3,3.2C8.7,11.1,9,11.5,9,12.1
c0,0.9,0,1.6,0,1.8c0,0,0,0,0,0.1h4c0.5,0,1-0.5,1-1V1C14,0.5,13.5,0,13,0z"/>
</svg>

After

Width:  |  Height:  |  Size: 689 B

View File

@ -0,0 +1,7 @@
<svg class="svg-logo" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Isolation_Mode" x="0px" y="0px" viewBox="-344 273 29.4 32" xml:space="preserve" enable-background="new -344 273 29.4 32">
<g>
<polygon points="-326.2 296.7 -321.4 294.1 -321.4 275.8 -326.2 273 -326.2 286.6 -332.4 286.6 -332.4 281.3 -337.3 283.9 -337.3 302.2 -332.4 305 -332.4 291.4 -326.2 291.4 "/>
<polygon points="-319.1 277.1 -319.1 295.6 -326.2 299.5 -326.2 305 -314.6 298.3 -314.6 279.7 "/>
<polygon points="-332.4 273 -344 279.7 -344 298.3 -339.5 300.9 -339.5 282.4 -332.4 278.6 "/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 635 B