Tim Jones f15ce549e9
fix: siderlink api assume port 443 with https schema
If no port is supplied for the SideroLink API endpoint and the https
schema is used, then assume port 443 is wanted.

Signed-off-by: Tim Jones <tim.jones@siderolabs.com>
2022-06-23 11:39:49 +02:00

237 lines
6.6 KiB
Go

// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package siderolink_test
import (
"context"
"fmt"
"net"
"testing"
"time"
"github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/state"
"github.com/siderolabs/go-pointer"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
"github.com/talos-systems/go-procfs/procfs"
"github.com/talos-systems/go-retry/retry"
pb "github.com/talos-systems/siderolink/api/siderolink"
"google.golang.org/grpc"
"inet.af/netaddr"
"github.com/talos-systems/talos/internal/app/machined/pkg/controllers/ctest"
siderolinkctrl "github.com/talos-systems/talos/internal/app/machined/pkg/controllers/siderolink"
"github.com/talos-systems/talos/pkg/machinery/constants"
"github.com/talos-systems/talos/pkg/machinery/nethelpers"
"github.com/talos-systems/talos/pkg/machinery/resources/network"
)
func TestManagerSuite(t *testing.T) {
var m ManagerSuite
m.AfterSetup = func(suite *ctest.DefaultSuite) {
lis, err := net.Listen("tcp", "localhost:0")
suite.Require().NoError(err)
m.s = grpc.NewServer()
pb.RegisterProvisionServiceServer(m.s, mockServer{})
go func() {
suite.Require().NoError(m.s.Serve(lis))
}()
cmdline := procfs.NewCmdline(fmt.Sprintf("%s=%s", constants.KernelParamSideroLink, lis.Addr().String()))
suite.Require().NoError(suite.Runtime().RegisterController(&siderolinkctrl.ManagerController{
Cmdline: cmdline,
}))
}
suite.Run(t, &m)
}
type ManagerSuite struct {
ctest.DefaultSuite
s *grpc.Server
}
type mockServer struct {
pb.UnimplementedProvisionServiceServer
}
const (
mockServerEndpoint = "127.0.0.11:51820"
mockServerAddress = "fdae:41e4:649b:9303:b6db:d99c:215e:dfc4"
mockServerPublicKey = "2aq/V91QyrHAoH24RK0bldukgo2rWk+wqE5Eg6TArCM="
mockNodeAddressPrefix = "fdae:41e4:649b:9303:2a07:9c7:5b08:aef7/64"
)
func (srv mockServer) Provision(ctx context.Context, req *pb.ProvisionRequest) (*pb.ProvisionResponse, error) {
return &pb.ProvisionResponse{
ServerEndpoint: mockServerEndpoint,
ServerAddress: mockServerAddress,
ServerPublicKey: mockServerPublicKey,
NodeAddressPrefix: mockNodeAddressPrefix,
}, nil
}
func (suite *ManagerSuite) TestReconcile() {
networkStatus := network.NewStatus(network.NamespaceName, network.StatusID)
networkStatus.TypedSpec().AddressReady = true
suite.Require().NoError(suite.State().Create(suite.Ctx(), networkStatus))
nodeAddress := netaddr.MustParseIPPrefix(mockNodeAddressPrefix)
suite.AssertWithin(10*time.Second, 100*time.Millisecond, func() error {
addressResource, err := ctest.Get[*network.AddressSpec](
suite,
resource.NewMetadata(
network.ConfigNamespaceName,
network.AddressSpecType,
network.LayeredID(
network.ConfigOperator,
network.AddressID(constants.SideroLinkName, nodeAddress),
),
resource.VersionUndefined,
),
)
if err != nil {
if state.IsNotFoundError(err) {
return retry.ExpectedError(err)
}
return err
}
address := addressResource.TypedSpec()
suite.Assert().Equal(nodeAddress, address.Address)
suite.Assert().Equal(network.ConfigOperator, address.ConfigLayer)
suite.Assert().Equal(nethelpers.FamilyInet6, address.Family)
suite.Assert().Equal(constants.SideroLinkName, address.LinkName)
linkResource, err := ctest.Get[*network.LinkSpec](
suite,
resource.NewMetadata(
network.ConfigNamespaceName,
network.LinkSpecType,
network.LayeredID(network.ConfigOperator, network.LinkID(constants.SideroLinkName)),
resource.VersionUndefined,
),
)
if err != nil {
if state.IsNotFoundError(err) {
return retry.ExpectedError(err)
}
return err
}
link := linkResource.TypedSpec()
suite.Assert().Equal("wireguard", link.Kind)
suite.Assert().Equal(network.ConfigOperator, link.ConfigLayer)
suite.Assert().NotEmpty(link.Wireguard.PrivateKey)
suite.Assert().Len(link.Wireguard.Peers, 1)
suite.Assert().Equal(mockServerEndpoint, link.Wireguard.Peers[0].Endpoint)
suite.Assert().Equal(mockServerPublicKey, link.Wireguard.Peers[0].PublicKey)
suite.Assert().Equal(
[]netaddr.IPPrefix{
netaddr.IPPrefixFrom(
netaddr.MustParseIP(mockServerAddress),
128,
),
}, link.Wireguard.Peers[0].AllowedIPs,
)
suite.Assert().Equal(
constants.SideroLinkDefaultPeerKeepalive,
link.Wireguard.Peers[0].PersistentKeepaliveInterval,
)
return nil
})
}
func TestParseJoinToken(t *testing.T) {
t.Run("parses a join token from a complete URL without error", func(t *testing.T) {
// when
endpoint, err := siderolinkctrl.ParseAPIEndpoint("grpc://10.5.0.2:3445?jointoken=ttt")
// then
assert.NoError(t, err)
assert.Equal(t, siderolinkctrl.APIEndpoint{
Host: "10.5.0.2:3445",
Insecure: true,
JoinToken: pointer.To("ttt"),
}, endpoint)
})
t.Run("parses a join token from a secure URL without error", func(t *testing.T) {
// when
endpoint, err := siderolinkctrl.ParseAPIEndpoint("https://10.5.0.2:3445?jointoken=ttt&jointoken=xxx")
// then
assert.NoError(t, err)
assert.Equal(t, siderolinkctrl.APIEndpoint{
Host: "10.5.0.2:3445",
Insecure: false,
JoinToken: pointer.To("ttt"),
}, endpoint)
})
t.Run("parses a join token from a secure URL without port", func(t *testing.T) {
// when
endpoint, err := siderolinkctrl.ParseAPIEndpoint("https://10.5.0.2?jointoken=ttt&jointoken=xxx")
// then
assert.NoError(t, err)
assert.Equal(t, siderolinkctrl.APIEndpoint{
Host: "10.5.0.2:443",
Insecure: false,
JoinToken: pointer.To("ttt"),
}, endpoint)
})
t.Run("parses a join token from an URL without a scheme", func(t *testing.T) {
// when
endpoint, err := siderolinkctrl.ParseAPIEndpoint("10.5.0.2:3445?jointoken=ttt")
// then
assert.NoError(t, err)
assert.Equal(t, siderolinkctrl.APIEndpoint{
Host: "10.5.0.2:3445",
Insecure: true,
JoinToken: pointer.To("ttt"),
}, endpoint)
})
t.Run("does not error if there is no join token in a complete URL", func(t *testing.T) {
// when
endpoint, err := siderolinkctrl.ParseAPIEndpoint("grpc://10.5.0.2:3445")
// then
assert.NoError(t, err)
assert.Equal(t, siderolinkctrl.APIEndpoint{
Host: "10.5.0.2:3445",
Insecure: true,
JoinToken: nil,
}, endpoint)
})
t.Run("does not error if there is no join token in an URL without a scheme", func(t *testing.T) {
// when
endpoint, err := siderolinkctrl.ParseAPIEndpoint("10.5.0.2:3445")
// then
assert.NoError(t, err)
assert.Equal(t, siderolinkctrl.APIEndpoint{
Host: "10.5.0.2:3445",
Insecure: true,
JoinToken: nil,
}, endpoint)
})
}