Skip to content

Commit

Permalink
Merge branch 'add_verbose_curl_logging' of git://github.com/tpo/vip-m…
Browse files Browse the repository at this point in the history
…anager into tpo-add_verbose_curl_logging
  • Loading branch information
markwort committed Aug 19, 2020
2 parents f1f52ee + e993280 commit e60a3d1
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 13 deletions.
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

Manages a virtual IP based on state kept in etcd or Consul. Monitors state in etcd

<<<<<<< HEAD
## Table of Contents
- [Building](#building)
- [Installing from package](#Installing-from-package)
Expand All @@ -22,6 +23,11 @@ Manages a virtual IP based on state kept in etcd or Consul. Monitors state in et

## Building
1. Make sure you have at least version 1.14 of Golang for proper module support. You can get by with go 1.12 or 1.13, but YMMV.
=======
## Building

1. Make sure you have at least version 1.12 of Golang
>>>>>>> e99328045ca88cfcab2e1f67ef02a1aaf56e5052
2. To make sure that internal includes (the vipconfig and the checker package) are satisfied, place the base directory of this project properly into your `$GOPATH`.
The resulting location should be `$GOPATH/src/github.com/cybertec-postgresql/vip-manager/`. The easiest way to do this is:
```go get github.com/cybertec-postgresql/vip-manager```
Expand Down Expand Up @@ -50,6 +56,11 @@ to all found network interfaces. So something like `*` or `0.0.0.0` (IPv4 only)
to activate the automatic binding. This again might not be suitable for all use cases where security is paramount for example.

## Configuration
<<<<<<< HEAD
=======

The configuration can be passed to the executable through argument flags or through a YAML config file. Run `vip-manager --help` to see the available flags.
>>>>>>> e99328045ca88cfcab2e1f67ef02a1aaf56e5052
The configuration can be passed to the executable through argument flags, environment variables or through a YAML config file. Run `vip-manager --help` to see the available flags.

Expand Down Expand Up @@ -145,6 +156,15 @@ user="myUsername"
pass="myPassword"
```

## Debugging

Either:

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

(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
4 changes: 4 additions & 0 deletions vipconfig/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ type Config struct {

RetryAfter int `yaml:"retry_after"` //milliseconds
RetryNum int `yaml:"retry_num"`

Verbose bool `yaml:"verbose"`
}

func defineFlags() {
Expand All @@ -58,6 +60,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
3 changes: 3 additions & 0 deletions vipconfig/vip-manager.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,6 @@ consul_token: "Julian's secret token"
# how often things should be retried and how long to wait between retries. (currently only affects arpClient)
retry_num: 2
retry_after: 250 #in milliseconds

# verbose logs (currently only supported for hetzner)
verbose: false

0 comments on commit e60a3d1

Please sign in to comment.