Skip to content

Commit

Permalink
Merge branch 'tpo-add_verbose_curl_logging' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
markwort committed Sep 17, 2020
2 parents 86db6ec + 472cc79 commit 827149e
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 13 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Manages a virtual IP based on state kept in etcd or Consul. Monitors state in et
- [Migration for Service Files using YAML config files](#Migration-for-Service-Files-using-YAML-config-files)
- [Configuration - Hetzner](#Configuration---Hetzner)
- [Credential File - Hetzmer](#Credential-File---Hetzner)
- [Debugging](#Debugging)
- [Author](#Author)

## Building
Expand Down Expand Up @@ -94,6 +95,7 @@ This is a list of all avaiable configuration items:
`etcd-ca-file` | `VIP_ETCD_CA_FILE` | no | /etc/etcd/ca.cert.pem | A certificate authority file that can be used to verify the certificate provided by etcd endpoints.
`etcd-cert-file` | `VIP_ETCD_CERT_FILE` | no | /etc/etcd/client.cert.pem | A client certificate that is used to authenticate against etcd endpoints. Requires `etcd-ca-file` to be set as well.
`etcd-key-file` | `VIP_ETCD_KEY_FILE` | no | /etc/etcd/client.key.pem | A private key for the client certificate, used to decrypt messages sent by etcd endpoints. Required when `etcd-cert-file` is specified.
`verbose` | `VIP_VERBOSE` | no | true | Enable more verbose logging. Currently only the manager-type=hetzner provides additional logs.


### Migrating configuration from releases before v1.0
Expand Down Expand Up @@ -148,6 +150,16 @@ user="myUsername"
pass="myPassword"
```

## Debugging

Either:

* run `vip-manager` with `--verbose` flag or
* set `verbose` to `true` in `/etc/default/vip-manager.yml`
* set `VIP_VERBOSE=true`

(currently only supported for `hetzner`)

## Author

Cybertec Schönig & Schönig GmbH, https://www.cybertec-postgresql.com
5 changes: 3 additions & 2 deletions ipmanager/basicConfigurer_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func (c *BasicConfigurer) configureAddress() bool {
// For now it is save to say that also working even if a
// gratuitous arp message could not be send but logging an
// errror should be enough.
_ = c.ARPSendGratuitous()
_ = c.arpSendGratuitous()
}

return result
Expand Down Expand Up @@ -87,7 +87,8 @@ func (c *BasicConfigurer) createArpClient() error {
return nil
}

func (c *BasicConfigurer) ARPSendGratuitous() error {
// sends a gratuitous ARP request and reply
func (c *BasicConfigurer) arpSendGratuitous() error {
/* While RFC 2002 does not say whether a gratuitous ARP request or reply is preferred
* to update ones neighbours' MAC tables, the Wireshark Wiki recommends sending both.
* https://wiki.wireshark.org/Gratuitous_ARP
Expand Down
56 changes: 47 additions & 9 deletions ipmanager/hetznerConfigurer.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,15 @@ type HetznerConfigurer struct {
*IPConfiguration
cachedState int
lastAPICheck time.Time
verbose bool
}

func newHetznerConfigurer(config *IPConfiguration) (*HetznerConfigurer, error) {
c := &HetznerConfigurer{IPConfiguration: config, cachedState: unknown, lastAPICheck: time.Unix(0, 0)}
func newHetznerConfigurer(config *IPConfiguration, verbose bool) (*HetznerConfigurer, error) {
c := &HetznerConfigurer{
IPConfiguration: config,
cachedState: unknown,
lastAPICheck: time.Unix(0, 0),
verbose: verbose}

return c, nil
}
Expand Down Expand Up @@ -102,9 +107,33 @@ func (c *HetznerConfigurer) curlQueryFailover(post bool) (string, error) {
}
log.Printf("my_own_ip: %s\n", myOwnIP.String())

cmd = exec.Command("curl", "--ipv4", "-u", user+":"+password, "https://robot-ws.your-server.de/failover/"+c.VIP.String(), "-d", "active_server_ip="+myOwnIP.String())
cmd = exec.Command("curl",
"--ipv4",
"-u", user+":"+password,
"https://robot-ws.your-server.de/failover/"+c.IPConfiguration.VIP.String(),
"-d", "active_server_ip="+myOwnIP.String())

if c.verbose {
log.Printf("%s %s %s '%s' %s %s %s",
"curl",
"--ipv4",
"-u", user+":XXXXXX",
"https://robot-ws.your-server.de/failover/"+c.IPConfiguration.VIP.String(),
"-d", "active_server_ip="+myOwnIP.String())
}
} else {
cmd = exec.Command("curl", "--ipv4", "-u", user+":"+password, "https://robot-ws.your-server.de/failover/"+c.VIP.String())
cmd = exec.Command("curl",
"--ipv4",
"-u", user+":"+password,
"https://robot-ws.your-server.de/failover/"+c.IPConfiguration.VIP.String())

if c.verbose {
log.Printf("%s %s %s %s %s",
"curl",
"--ipv4",
"-u", user+":XXXXXX",
"https://robot-ws.your-server.de/failover/"+c.IPConfiguration.VIP.String())
}
}

out, err := cmd.Output()
Expand All @@ -122,9 +151,13 @@ func (c *HetznerConfigurer) curlQueryFailover(post bool) (string, error) {
* This function is used to parse the response which comes from the
* curlQueryFailover function and in turn from the curl calls to the API.
*/
func getActiveIPFromJSON(str string) (net.IP, error) {
func (c *HetznerConfigurer) getActiveIPFromJSON(str string) (net.IP, error) {
var f map[string]interface{}

if c.verbose {
log.Printf("JSON response: %s\n", str)
}

err := json.Unmarshal([]byte(str), &f)
if err != nil {
log.Println(err)
Expand All @@ -134,7 +167,11 @@ func getActiveIPFromJSON(str string) (net.IP, error) {
if f["error"] != nil {
errormap := f["error"].(map[string]interface{})

log.Printf("There was an error accessing the Hetzner API!\n status: %f\n code: %s\n message: %s\n", errormap["status"].(float64), errormap["code"].(string), errormap["message"].(string))
log.Printf("There was an error accessing the Hetzner API!\n"+
" status: %f\n code: %s\n message: %s\n",
errormap["status"].(float64),
errormap["code"].(string),
errormap["message"].(string))
return nil, errors.New("Hetzner API returned error response")
}

Expand Down Expand Up @@ -188,7 +225,7 @@ func (c *HetznerConfigurer) queryAddress() bool {
c.lastAPICheck = time.Now()
}

currentFailoverDestinationIP, err := getActiveIPFromJSON(str)
currentFailoverDestinationIP, err := c.getActiveIPFromJSON(str)
if err != nil {
//TODO
c.cachedState = unknown
Expand Down Expand Up @@ -224,7 +261,7 @@ func (c *HetznerConfigurer) runAddressConfiguration(action string) bool {
c.cachedState = unknown
return false
}
currentFailoverDestinationIP, err := getActiveIPFromJSON(str)
currentFailoverDestinationIP, err := c.getActiveIPFromJSON(str)
if err != nil {
c.cachedState = unknown
return false
Expand All @@ -240,7 +277,8 @@ func (c *HetznerConfigurer) runAddressConfiguration(action string) bool {
}

log.Printf("The failover command was issued, but the current Failover destination (%s) is different from what it should be (%s).",
currentFailoverDestinationIP.String(), getOutboundIP().String())
currentFailoverDestinationIP.String(),
getOutboundIP().String())
//Something must have gone wrong while trying to switch IP's...
c.cachedState = unknown
return false
Expand Down
7 changes: 5 additions & 2 deletions ipmanager/ip_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,18 @@ type IPManager struct {
}

// NewIPManager returns a new instance of IPManager
func NewIPManager(hostingType string, config *IPConfiguration, states <-chan bool) (m *IPManager, err error) {
func NewIPManager(hostingType string, config *IPConfiguration, states <-chan bool, verbose bool) (m *IPManager, err error) {
m = &IPManager{
states: states,
currentState: false,
}
m.recheck = sync.NewCond(&m.stateLock)
switch hostingType {
case "hetzner":
m.configurer, err = newHetznerConfigurer(config)
m.configurer, err = newHetznerConfigurer(config, verbose)
if err != nil {
return nil, err
}
case "basic":
fallthrough
default:
Expand Down
1 change: 1 addition & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ func main() {
RetryAfter: conf.RetryAfter,
},
states,
conf.Verbose,
)
if err != nil {
log.Fatalf("Problems with generating the virtual ip manager: %s", err)
Expand Down
2 changes: 2 additions & 0 deletions vipconfig/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ func defineFlags() {
pflag.String("interval", "1000", "DCS scan interval in milliseconds.")
pflag.String("manager-type", "basic", "Type of VIP-management to be used. Supported values: basic, hetzner.")

pflag.Bool("verbose", false, "Be verbose. Currently only implemented for manager-type=hetzner .")

pflag.CommandLine.SortFlags = false
}

Expand Down

0 comments on commit 827149e

Please sign in to comment.