Skip to content

Commit

Permalink
incusd/network/openvswitch: Support OVN SSL config keys
Browse files Browse the repository at this point in the history
Closes #277

Signed-off-by: Stéphane Graber <[email protected]>
Sponsored-by: Luizalabs (https://luizalabs.com)
  • Loading branch information
stgraber committed Dec 7, 2023
1 parent a36b5e5 commit 6db6715
Showing 1 changed file with 111 additions and 8 deletions.
119 changes: 111 additions & 8 deletions internal/server/network/openvswitch/ovn.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package openvswitch

import (
"context"
"fmt"
"net"
"os"
"strconv"
"strings"
"time"
Expand Down Expand Up @@ -179,16 +181,66 @@ type OVNRouterPeering struct {

// NewOVN initialises new OVN client wrapper with the connection set in network.ovn.northbound_connection config.
func NewOVN(s *state.State) (*OVN, error) {
// Get database connection strings.
nbConnection := s.GlobalConfig.NetworkOVNNorthboundConnection()

sbConnection, err := NewOVS().OVNSouthboundDBRemoteAddress()
if err != nil {
return nil, fmt.Errorf("Failed to get OVN southbound connection string: %w", err)
}

client := &OVN{}
client.SetNorthboundDBAddress(nbConnection)
client.SetSouthboundDBAddress(sbConnection)
// Create the OVN struct.
client := &OVN{
nbDBAddr: nbConnection,
sbDBAddr: sbConnection,
}

// If using SSL, then get the CA and client key pair.
if strings.Contains(nbConnection, "ssl:") {
sslCACert, sslClientCert, sslClientKey := s.GlobalConfig.NetworkOVNSSL()

if sslCACert == "" {
content, err := os.ReadFile("/etc/ovn/ovn-central.crt")
if err != nil {
if os.IsNotExist(err) {
return nil, fmt.Errorf("OVN configured to use SSL but no SSL CA certificate defined")
}

return nil, err
}

sslCACert = string(content)
}

if sslClientCert == "" {
content, err := os.ReadFile("/etc/ovn/cert_host")
if err != nil {
if os.IsNotExist(err) {
return nil, fmt.Errorf("OVN configured to use SSL but no SSL client certificate defined")
}

return nil, err
}

sslClientCert = string(content)
}

if sslClientKey == "" {
content, err := os.ReadFile("/etc/ovn/key_host")
if err != nil {
if os.IsNotExist(err) {
return nil, fmt.Errorf("OVN configured to use SSL but no SSL client key defined")
}

return nil, err
}

sslClientKey = string(content)
}

client.sslCACert = sslCACert
client.sslClientCert = sslClientCert
client.sslClientKey = sslClientKey
}

return client, nil
}
Expand All @@ -197,6 +249,10 @@ func NewOVN(s *state.State) (*OVN, error) {
type OVN struct {
nbDBAddr string
sbDBAddr string

sslCACert string
sslClientCert string
sslClientKey string
}

// SetNorthboundDBAddress sets the address that runs the OVN northbound databases.
Expand Down Expand Up @@ -253,16 +309,63 @@ func (o *OVN) xbctl(southbound bool, extraArgs ...string) (string, error) {
// Figure out args.
args := []string{"--timeout=10", "--db", dbAddr}

// Handle SSL args.
files := []*os.File{}
if strings.Contains(dbAddr, "ssl:") {
// Handle client certificate.
clientCertFile, err := os.CreateTemp("", "ovn")
if err != nil {
return "", err
}

defer clientCertFile.Close()
_ = os.Remove(clientCertFile.Name())
files = append(files, clientCertFile)

_, err = clientCertFile.WriteString(o.sslClientCert)
if err != nil {
return "", err
}

// Handle client key.
clientKeyFile, err := os.CreateTemp("", "ovn")
if err != nil {
return "", err
}

defer clientKeyFile.Close()
_ = os.Remove(clientKeyFile.Name())
files = append(files, clientKeyFile)

_, err = clientKeyFile.WriteString(o.sslClientKey)
if err != nil {
return "", err
}

// Handle CA certificate.
caCertFile, err := os.CreateTemp("", "ovn")
if err != nil {
return "", err
}

defer caCertFile.Close()
_ = os.Remove(caCertFile.Name())
files = append(files, caCertFile)

_, err = caCertFile.WriteString(o.sslCACert)
if err != nil {
return "", err
}

args = append(args,
"-c", "/etc/ovn/cert_host",
"-p", "/etc/ovn/key_host",
"-C", "/etc/ovn/ovn-central.crt",
"-c", "/proc/self/fd/3",
"-p", "/proc/self/fd/4",
"-C", "/proc/self/fd/5",
)
}

args = append(args, extraArgs...)
return subprocess.RunCommand(cmd, args...)
return subprocess.RunCommandInheritFds(context.Background(), files, cmd, args...)
}

// LogicalRouterAdd adds a named logical router.
Expand Down

0 comments on commit 6db6715

Please sign in to comment.