|
|
|
@ -1,18 +1,23 @@
|
|
|
|
|
package agent
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"github.com/hashicorp/consul/consul"
|
|
|
|
|
"github.com/hashicorp/consul/consul/structs"
|
|
|
|
|
"log"
|
|
|
|
|
"reflect"
|
|
|
|
|
"strings"
|
|
|
|
|
"sync"
|
|
|
|
|
"sync/atomic"
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
"github.com/hashicorp/consul/consul"
|
|
|
|
|
"github.com/hashicorp/consul/consul/structs"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
const (
|
|
|
|
|
syncStaggerIntv = 3 * time.Second
|
|
|
|
|
syncRetryIntv = 15 * time.Second
|
|
|
|
|
|
|
|
|
|
// permissionDenied is returned when an ACL based rejection happens
|
|
|
|
|
permissionDenied = "Permission denied"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// syncStatus is used to represent the difference between
|
|
|
|
@ -292,8 +297,9 @@ SYNC:
|
|
|
|
|
// the local syncStatus as appropriate
|
|
|
|
|
func (l *localState) setSyncState() error {
|
|
|
|
|
req := structs.NodeSpecificRequest{
|
|
|
|
|
Datacenter: l.config.Datacenter,
|
|
|
|
|
Node: l.config.NodeName,
|
|
|
|
|
Datacenter: l.config.Datacenter,
|
|
|
|
|
Node: l.config.NodeName,
|
|
|
|
|
QueryOptions: structs.QueryOptions{Token: l.config.ACLToken},
|
|
|
|
|
}
|
|
|
|
|
var out1 structs.IndexedNodeServices
|
|
|
|
|
var out2 structs.IndexedHealthChecks
|
|
|
|
@ -403,9 +409,10 @@ func (l *localState) syncChanges() error {
|
|
|
|
|
// deleteService is used to delete a service from the server
|
|
|
|
|
func (l *localState) deleteService(id string) error {
|
|
|
|
|
req := structs.DeregisterRequest{
|
|
|
|
|
Datacenter: l.config.Datacenter,
|
|
|
|
|
Node: l.config.NodeName,
|
|
|
|
|
ServiceID: id,
|
|
|
|
|
Datacenter: l.config.Datacenter,
|
|
|
|
|
Node: l.config.NodeName,
|
|
|
|
|
ServiceID: id,
|
|
|
|
|
WriteRequest: structs.WriteRequest{Token: l.config.ACLToken},
|
|
|
|
|
}
|
|
|
|
|
var out struct{}
|
|
|
|
|
err := l.iface.RPC("Catalog.Deregister", &req, &out)
|
|
|
|
@ -419,9 +426,10 @@ func (l *localState) deleteService(id string) error {
|
|
|
|
|
// deleteCheck is used to delete a service from the server
|
|
|
|
|
func (l *localState) deleteCheck(id string) error {
|
|
|
|
|
req := structs.DeregisterRequest{
|
|
|
|
|
Datacenter: l.config.Datacenter,
|
|
|
|
|
Node: l.config.NodeName,
|
|
|
|
|
CheckID: id,
|
|
|
|
|
Datacenter: l.config.Datacenter,
|
|
|
|
|
Node: l.config.NodeName,
|
|
|
|
|
CheckID: id,
|
|
|
|
|
WriteRequest: structs.WriteRequest{Token: l.config.ACLToken},
|
|
|
|
|
}
|
|
|
|
|
var out struct{}
|
|
|
|
|
err := l.iface.RPC("Catalog.Deregister", &req, &out)
|
|
|
|
@ -435,16 +443,21 @@ func (l *localState) deleteCheck(id string) error {
|
|
|
|
|
// syncService is used to sync a service to the server
|
|
|
|
|
func (l *localState) syncService(id string) error {
|
|
|
|
|
req := structs.RegisterRequest{
|
|
|
|
|
Datacenter: l.config.Datacenter,
|
|
|
|
|
Node: l.config.NodeName,
|
|
|
|
|
Address: l.config.AdvertiseAddr,
|
|
|
|
|
Service: l.services[id],
|
|
|
|
|
Datacenter: l.config.Datacenter,
|
|
|
|
|
Node: l.config.NodeName,
|
|
|
|
|
Address: l.config.AdvertiseAddr,
|
|
|
|
|
Service: l.services[id],
|
|
|
|
|
WriteRequest: structs.WriteRequest{Token: l.config.ACLToken},
|
|
|
|
|
}
|
|
|
|
|
var out struct{}
|
|
|
|
|
err := l.iface.RPC("Catalog.Register", &req, &out)
|
|
|
|
|
if err == nil {
|
|
|
|
|
l.serviceStatus[id] = syncStatus{inSync: true}
|
|
|
|
|
l.logger.Printf("[INFO] agent: Synced service '%s'", id)
|
|
|
|
|
} else if strings.Contains(err.Error(), permissionDenied) {
|
|
|
|
|
l.serviceStatus[id] = syncStatus{inSync: true}
|
|
|
|
|
l.logger.Printf("[WARN] agent: Service '%s' registration blocked by ACLs", id)
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
@ -460,17 +473,22 @@ func (l *localState) syncCheck(id string) error {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
req := structs.RegisterRequest{
|
|
|
|
|
Datacenter: l.config.Datacenter,
|
|
|
|
|
Node: l.config.NodeName,
|
|
|
|
|
Address: l.config.AdvertiseAddr,
|
|
|
|
|
Service: service,
|
|
|
|
|
Check: l.checks[id],
|
|
|
|
|
Datacenter: l.config.Datacenter,
|
|
|
|
|
Node: l.config.NodeName,
|
|
|
|
|
Address: l.config.AdvertiseAddr,
|
|
|
|
|
Service: service,
|
|
|
|
|
Check: l.checks[id],
|
|
|
|
|
WriteRequest: structs.WriteRequest{Token: l.config.ACLToken},
|
|
|
|
|
}
|
|
|
|
|
var out struct{}
|
|
|
|
|
err := l.iface.RPC("Catalog.Register", &req, &out)
|
|
|
|
|
if err == nil {
|
|
|
|
|
l.checkStatus[id] = syncStatus{inSync: true}
|
|
|
|
|
l.logger.Printf("[INFO] agent: Synced check '%s'", id)
|
|
|
|
|
} else if strings.Contains(err.Error(), permissionDenied) {
|
|
|
|
|
l.checkStatus[id] = syncStatus{inSync: true}
|
|
|
|
|
l.logger.Printf("[WARN] agent: Check '%s' registration blocked by ACLs", id)
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|