mirror of
https://github.com/edgelesssys/constellation.git
synced 2024-10-01 01:36:09 -04:00
Remove PublicIP from QEMU metadata (#396)
Signed-off-by: Daniel Weiße <dw@edgeless.systems>
This commit is contained in:
parent
6d2ec109d0
commit
55cfff034a
@ -314,9 +314,6 @@ func (c *JoinClient) getNodeMetadata() error {
|
|||||||
if inst.VPCIP != "" {
|
if inst.VPCIP != "" {
|
||||||
ips = append(ips, net.ParseIP(inst.VPCIP))
|
ips = append(ips, net.ParseIP(inst.VPCIP))
|
||||||
}
|
}
|
||||||
if inst.PublicIP != "" {
|
|
||||||
ips = append(ips, net.ParseIP(inst.PublicIP))
|
|
||||||
}
|
|
||||||
|
|
||||||
c.nodeName = inst.Name
|
c.nodeName = inst.Name
|
||||||
c.role = inst.Role
|
c.role = inst.Role
|
||||||
|
@ -25,8 +25,6 @@ type ProviderMetadata interface {
|
|||||||
Self(ctx context.Context) (metadata.InstanceMetadata, error)
|
Self(ctx context.Context) (metadata.InstanceMetadata, error)
|
||||||
// GetSubnetworkCIDR retrieves the subnetwork CIDR for the current instance.
|
// GetSubnetworkCIDR retrieves the subnetwork CIDR for the current instance.
|
||||||
GetSubnetworkCIDR(ctx context.Context) (string, error)
|
GetSubnetworkCIDR(ctx context.Context) (string, error)
|
||||||
// SupportsLoadBalancer returns true if the cloud provider supports load balancers.
|
|
||||||
SupportsLoadBalancer() bool
|
|
||||||
// GetLoadBalancerEndpoint retrieves the load balancer endpoint.
|
// GetLoadBalancerEndpoint retrieves the load balancer endpoint.
|
||||||
GetLoadBalancerEndpoint(ctx context.Context) (string, error)
|
GetLoadBalancerEndpoint(ctx context.Context) (string, error)
|
||||||
// GetInstance retrieves an instance using its providerID.
|
// GetInstance retrieves an instance using its providerID.
|
||||||
|
@ -103,7 +103,6 @@ func (k *KubeWrapper) InitCluster(
|
|||||||
nodeName := ip
|
nodeName := ip
|
||||||
var providerID string
|
var providerID string
|
||||||
var instance metadata.InstanceMetadata
|
var instance metadata.InstanceMetadata
|
||||||
var publicIP string
|
|
||||||
var nodePodCIDR string
|
var nodePodCIDR string
|
||||||
var subnetworkPodCIDR string
|
var subnetworkPodCIDR string
|
||||||
var controlPlaneEndpoint string // this is the endpoint in "kubeadm init --control-plane-endpoint=<IP/DNS>:<port>"
|
var controlPlaneEndpoint string // this is the endpoint in "kubeadm init --control-plane-endpoint=<IP/DNS>:<port>"
|
||||||
@ -120,13 +119,9 @@ func (k *KubeWrapper) InitCluster(
|
|||||||
if instance.VPCIP != "" {
|
if instance.VPCIP != "" {
|
||||||
validIPs = append(validIPs, net.ParseIP(instance.VPCIP))
|
validIPs = append(validIPs, net.ParseIP(instance.VPCIP))
|
||||||
}
|
}
|
||||||
if instance.PublicIP != "" {
|
|
||||||
validIPs = append(validIPs, net.ParseIP(instance.PublicIP))
|
|
||||||
}
|
|
||||||
nodeName = k8sCompliantHostname(instance.Name)
|
nodeName = k8sCompliantHostname(instance.Name)
|
||||||
providerID = instance.ProviderID
|
providerID = instance.ProviderID
|
||||||
nodeIP = instance.VPCIP
|
nodeIP = instance.VPCIP
|
||||||
publicIP = instance.PublicIP
|
|
||||||
|
|
||||||
if len(instance.AliasIPRanges) > 0 {
|
if len(instance.AliasIPRanges) > 0 {
|
||||||
nodePodCIDR = instance.AliasIPRanges[0]
|
nodePodCIDR = instance.AliasIPRanges[0]
|
||||||
@ -135,12 +130,10 @@ func (k *KubeWrapper) InitCluster(
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("retrieving subnetwork CIDR: %w", err)
|
return nil, fmt.Errorf("retrieving subnetwork CIDR: %w", err)
|
||||||
}
|
}
|
||||||
controlPlaneEndpoint = publicIP
|
|
||||||
if k.providerMetadata.SupportsLoadBalancer() {
|
controlPlaneEndpoint, err = k.providerMetadata.GetLoadBalancerEndpoint(ctx)
|
||||||
controlPlaneEndpoint, err = k.providerMetadata.GetLoadBalancerEndpoint(ctx)
|
if err != nil {
|
||||||
if err != nil {
|
return nil, fmt.Errorf("retrieving load balancer endpoint: %w", err)
|
||||||
return nil, fmt.Errorf("retrieving load balancer endpoint: %w", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log.With(
|
log.With(
|
||||||
@ -154,7 +147,7 @@ func (k *KubeWrapper) InitCluster(
|
|||||||
// Step 2: configure kubeadm init config
|
// Step 2: configure kubeadm init config
|
||||||
initConfig := k.configProvider.InitConfiguration(k.cloudControllerManager.Supported(), k8sVersion)
|
initConfig := k.configProvider.InitConfiguration(k.cloudControllerManager.Supported(), k8sVersion)
|
||||||
initConfig.SetNodeIP(nodeIP)
|
initConfig.SetNodeIP(nodeIP)
|
||||||
initConfig.SetCertSANs([]string{publicIP, nodeIP})
|
initConfig.SetCertSANs([]string{nodeIP})
|
||||||
initConfig.SetNodeName(nodeName)
|
initConfig.SetNodeName(nodeName)
|
||||||
initConfig.SetProviderID(providerID)
|
initConfig.SetProviderID(providerID)
|
||||||
initConfig.SetControlPlaneEndpoint(controlPlaneEndpoint)
|
initConfig.SetControlPlaneEndpoint(controlPlaneEndpoint)
|
||||||
@ -286,11 +279,9 @@ func (k *KubeWrapper) JoinCluster(ctx context.Context, args *kubeadm.BootstrapTo
|
|||||||
providerID = instance.ProviderID
|
providerID = instance.ProviderID
|
||||||
nodeName = instance.Name
|
nodeName = instance.Name
|
||||||
nodeInternalIP = instance.VPCIP
|
nodeInternalIP = instance.VPCIP
|
||||||
if k.providerMetadata.SupportsLoadBalancer() {
|
loadbalancerEndpoint, err = k.providerMetadata.GetLoadBalancerEndpoint(ctx)
|
||||||
loadbalancerEndpoint, err = k.providerMetadata.GetLoadBalancerEndpoint(ctx)
|
if err != nil {
|
||||||
if err != nil {
|
return fmt.Errorf("retrieving loadbalancer endpoint: %w", err)
|
||||||
return fmt.Errorf("retrieving loadbalancer endpoint: %w", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nodeName = k8sCompliantHostname(nodeName)
|
nodeName = k8sCompliantHostname(nodeName)
|
||||||
|
@ -40,7 +40,6 @@ func TestInitCluster(t *testing.T) {
|
|||||||
nodeName := "node-name"
|
nodeName := "node-name"
|
||||||
providerID := "provider-id"
|
providerID := "provider-id"
|
||||||
privateIP := "192.0.2.1"
|
privateIP := "192.0.2.1"
|
||||||
publicIP := "192.0.2.2"
|
|
||||||
loadbalancerIP := "192.0.2.3"
|
loadbalancerIP := "192.0.2.3"
|
||||||
aliasIPRange := "192.0.2.0/24"
|
aliasIPRange := "192.0.2.0/24"
|
||||||
|
|
||||||
@ -91,7 +90,6 @@ func TestInitCluster(t *testing.T) {
|
|||||||
Name: nodeName,
|
Name: nodeName,
|
||||||
ProviderID: providerID,
|
ProviderID: providerID,
|
||||||
VPCIP: privateIP,
|
VPCIP: privateIP,
|
||||||
PublicIP: publicIP,
|
|
||||||
AliasIPRanges: []string{aliasIPRange},
|
AliasIPRanges: []string{aliasIPRange},
|
||||||
},
|
},
|
||||||
GetLoadBalancerEndpointResp: loadbalancerIP,
|
GetLoadBalancerEndpointResp: loadbalancerIP,
|
||||||
@ -113,7 +111,7 @@ func TestInitCluster(t *testing.T) {
|
|||||||
ClusterConfiguration: kubeadm.ClusterConfiguration{
|
ClusterConfiguration: kubeadm.ClusterConfiguration{
|
||||||
ControlPlaneEndpoint: loadbalancerIP,
|
ControlPlaneEndpoint: loadbalancerIP,
|
||||||
APIServer: kubeadm.APIServer{
|
APIServer: kubeadm.APIServer{
|
||||||
CertSANs: []string{publicIP, privateIP},
|
CertSANs: []string{privateIP},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -66,7 +66,6 @@ require (
|
|||||||
github.com/Azure/azure-sdk-for-go/sdk/keyvault/azkeys v0.8.1 // indirect
|
github.com/Azure/azure-sdk-for-go/sdk/keyvault/azkeys v0.8.1 // indirect
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/keyvault/azsecrets v0.10.1 // indirect
|
github.com/Azure/azure-sdk-for-go/sdk/keyvault/azsecrets v0.10.1 // indirect
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/keyvault/internal v0.7.0 // indirect
|
github.com/Azure/azure-sdk-for-go/sdk/keyvault/internal v0.7.0 // indirect
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork v1.1.0 // indirect
|
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.5.1 // indirect
|
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.5.1 // indirect
|
||||||
github.com/AzureAD/microsoft-authentication-library-for-go v0.5.1 // indirect
|
github.com/AzureAD/microsoft-authentication-library-for-go v0.5.1 // indirect
|
||||||
github.com/Masterminds/semver/v3 v3.1.1 // indirect
|
github.com/Masterminds/semver/v3 v3.1.1 // indirect
|
||||||
@ -83,7 +82,6 @@ require (
|
|||||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.19 // indirect
|
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.19 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.24 // indirect
|
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.24 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.14 // indirect
|
github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.14 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/ec2 v1.63.3 // indirect
|
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.9 // indirect
|
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.9 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.18 // indirect
|
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.18 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.19 // indirect
|
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.19 // indirect
|
||||||
|
@ -115,7 +115,6 @@ github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v2 v2.0
|
|||||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v2 v2.0.0/go.mod h1:aLFjumYDvv63tH1qnqkcmdjdZ6Sn+/viPv7H3jft0oY=
|
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v2 v2.0.0/go.mod h1:aLFjumYDvv63tH1qnqkcmdjdZ6Sn+/viPv7H3jft0oY=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal v1.0.0 h1:lMW1lD/17LUA5z1XTURo7LcVG2ICBPlyMHjIUrcFZNQ=
|
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal v1.0.0 h1:lMW1lD/17LUA5z1XTURo7LcVG2ICBPlyMHjIUrcFZNQ=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork v1.1.0 h1:QM6sE5k2ZT/vI5BEe0r7mqjsUSnhVBFbOsVkEuaEfiA=
|
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork v1.1.0 h1:QM6sE5k2ZT/vI5BEe0r7mqjsUSnhVBFbOsVkEuaEfiA=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork v1.1.0/go.mod h1:243D9iHbcQXoFUtgHJwL7gl2zx1aDuDMjvBZVGr2uW0=
|
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.0.0 h1:ECsQtyERDVz3NP3kvDOTLvbQhqWp/x9EsGKtb4ogUr8=
|
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.0.0 h1:ECsQtyERDVz3NP3kvDOTLvbQhqWp/x9EsGKtb4ogUr8=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.5.1 h1:BMTdr+ib5ljLa9MxTJK8x/Ds0MbBb4MfuW5BL0zMJnI=
|
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.5.1 h1:BMTdr+ib5ljLa9MxTJK8x/Ds0MbBb4MfuW5BL0zMJnI=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.5.1/go.mod h1:c6WvOhtmjNUWbLfOG1qxM/q0SPvQNSVJvolm+C52dIU=
|
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.5.1/go.mod h1:c6WvOhtmjNUWbLfOG1qxM/q0SPvQNSVJvolm+C52dIU=
|
||||||
@ -221,8 +220,6 @@ github.com/aws/aws-sdk-go-v2/internal/ini v1.3.24 h1:wj5Rwc05hvUSvKuOF29IYb9QrCL
|
|||||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.24/go.mod h1:jULHjqqjDlbyTa7pfM7WICATnOv+iOhjletM3N0Xbu8=
|
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.24/go.mod h1:jULHjqqjDlbyTa7pfM7WICATnOv+iOhjletM3N0Xbu8=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.14 h1:ZSIPAkAsCCjYrhqfw2+lNzWDzxzHXEckFkTePL5RSWQ=
|
github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.14 h1:ZSIPAkAsCCjYrhqfw2+lNzWDzxzHXEckFkTePL5RSWQ=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.14/go.mod h1:AyGgqiKv9ECM6IZeNQtdT8NnMvUb3/2wokeq2Fgryto=
|
github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.14/go.mod h1:AyGgqiKv9ECM6IZeNQtdT8NnMvUb3/2wokeq2Fgryto=
|
||||||
github.com/aws/aws-sdk-go-v2/service/ec2 v1.63.3 h1:+UHyeFhdPddRB+EkgeaKMutWiqwWrj3FIQUif3VnalM=
|
|
||||||
github.com/aws/aws-sdk-go-v2/service/ec2 v1.63.3/go.mod h1:zul71QqzR4D1a90/5FloZiAnZ1CtuIjVH7R9MP997+A=
|
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.9 h1:Lh1AShsuIJTwMkoxVCAYPJgNG5H+eN6SmoUn8nOZ5wE=
|
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.9 h1:Lh1AShsuIJTwMkoxVCAYPJgNG5H+eN6SmoUn8nOZ5wE=
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.9/go.mod h1:a9j48l6yL5XINLHLcOKInjdvknN+vWqPBxqeIDw7ktw=
|
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.9/go.mod h1:a9j48l6yL5XINLHLcOKInjdvknN+vWqPBxqeIDw7ktw=
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.18 h1:BBYoNQt2kUZUUK4bIPsKrCcjVPUMNsgQpNAwhznK/zo=
|
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.18 h1:BBYoNQt2kUZUUK4bIPsKrCcjVPUMNsgQpNAwhznK/zo=
|
||||||
|
@ -41,6 +41,7 @@ func (s *Server) ListenAndServe(port string) error {
|
|||||||
mux.Handle("/peers", http.HandlerFunc(s.listPeers))
|
mux.Handle("/peers", http.HandlerFunc(s.listPeers))
|
||||||
mux.Handle("/log", http.HandlerFunc(s.postLog))
|
mux.Handle("/log", http.HandlerFunc(s.postLog))
|
||||||
mux.Handle("/pcrs", http.HandlerFunc(s.exportPCRs))
|
mux.Handle("/pcrs", http.HandlerFunc(s.exportPCRs))
|
||||||
|
mux.Handle("/endpoint", http.HandlerFunc(s.getEndpoint))
|
||||||
|
|
||||||
server := http.Server{
|
server := http.Server{
|
||||||
Handler: mux,
|
Handler: mux,
|
||||||
@ -75,7 +76,7 @@ func (s *Server) listSelf(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, peer := range peers {
|
for _, peer := range peers {
|
||||||
if peer.PublicIP == remoteIP {
|
if peer.VPCIP == remoteIP {
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
if err := json.NewEncoder(w).Encode(peer); err != nil {
|
if err := json.NewEncoder(w).Encode(peer); err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
@ -110,6 +111,43 @@ func (s *Server) listPeers(w http.ResponseWriter, r *http.Request) {
|
|||||||
log.Infof("Request successful")
|
log.Infof("Request successful")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getEndpoint returns the IP address of the first control-plane instance.
|
||||||
|
// This allows us to fake a load balancer for QEMU instances.
|
||||||
|
func (s *Server) getEndpoint(w http.ResponseWriter, r *http.Request) {
|
||||||
|
log := s.log.With(zap.String("peer", r.RemoteAddr))
|
||||||
|
log.Infof("Serving GET request for /endpoint")
|
||||||
|
|
||||||
|
net, err := s.virt.LookupNetworkByName(s.network)
|
||||||
|
if err != nil {
|
||||||
|
log.With(zap.Error(err)).Errorf("Failed to lookup network")
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer net.Free()
|
||||||
|
|
||||||
|
leases, err := net.GetDHCPLeases()
|
||||||
|
if err != nil {
|
||||||
|
log.With(zap.Error(err)).Errorf("Failed to get DHCP leases")
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, lease := range leases {
|
||||||
|
if strings.HasPrefix(lease.Hostname, "control-plane") &&
|
||||||
|
strings.HasSuffix(lease.Hostname, "0") {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
if err := json.NewEncoder(w).Encode(lease.IPaddr); err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Infof("Request successful")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Errorf("Failed to find control-plane peer in active leases")
|
||||||
|
http.Error(w, "No matching peer found", http.StatusNotFound)
|
||||||
|
}
|
||||||
|
|
||||||
// postLog writes implements cloud-logging for QEMU instances.
|
// postLog writes implements cloud-logging for QEMU instances.
|
||||||
func (s *Server) postLog(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) postLog(w http.ResponseWriter, r *http.Request) {
|
||||||
log := s.log.With(zap.String("peer", r.RemoteAddr))
|
log := s.log.With(zap.String("peer", r.RemoteAddr))
|
||||||
@ -178,7 +216,7 @@ func (s *Server) exportPCRs(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
for _, peer := range peers {
|
for _, peer := range peers {
|
||||||
if peer.PublicIP == remoteIP {
|
if peer.VPCIP == remoteIP {
|
||||||
nodeName = peer.Name
|
nodeName = peer.Name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -210,7 +248,6 @@ func (s *Server) listAll() ([]metadata.InstanceMetadata, error) {
|
|||||||
Name: lease.Hostname,
|
Name: lease.Hostname,
|
||||||
Role: instanceRole,
|
Role: instanceRole,
|
||||||
VPCIP: lease.IPaddr,
|
VPCIP: lease.IPaddr,
|
||||||
PublicIP: lease.IPaddr,
|
|
||||||
ProviderID: "qemu:///hostname/" + lease.Hostname,
|
ProviderID: "qemu:///hostname/" + lease.Hostname,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -168,7 +168,7 @@ func TestListSelf(t *testing.T) {
|
|||||||
var metadata metadata.InstanceMetadata
|
var metadata metadata.InstanceMetadata
|
||||||
require.NoError(json.Unmarshal(metadataRaw, &metadata))
|
require.NoError(json.Unmarshal(metadataRaw, &metadata))
|
||||||
assert.Equal(tc.connect.network.leases[0].Hostname, metadata.Name)
|
assert.Equal(tc.connect.network.leases[0].Hostname, metadata.Name)
|
||||||
assert.Equal(tc.connect.network.leases[0].IPaddr, metadata.PublicIP)
|
assert.Equal(tc.connect.network.leases[0].IPaddr, metadata.VPCIP)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) Edgeless Systems GmbH
|
|
||||||
|
|
||||||
SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
package cloudtypes
|
|
||||||
|
|
||||||
/*
|
|
||||||
Package cloudtypes contains code that is shared by all cloud providers
|
|
||||||
and provides a common interface for interacting with cloud resources.
|
|
||||||
*/
|
|
@ -1,146 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) Edgeless Systems GmbH
|
|
||||||
|
|
||||||
SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
package cloudtypes
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork"
|
|
||||||
ec2types "github.com/aws/aws-sdk-go-v2/service/ec2/types"
|
|
||||||
"golang.org/x/text/cases"
|
|
||||||
"golang.org/x/text/language"
|
|
||||||
computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
|
|
||||||
"google.golang.org/protobuf/proto"
|
|
||||||
)
|
|
||||||
|
|
||||||
// FirewallRule holds a single firewall rule.
|
|
||||||
type FirewallRule struct {
|
|
||||||
Name string
|
|
||||||
Description string
|
|
||||||
Protocol string
|
|
||||||
IPRange string
|
|
||||||
FromPort int
|
|
||||||
ToPort int
|
|
||||||
}
|
|
||||||
|
|
||||||
// Firewall contains all firewall rules to be applied for either ingress or egress.
|
|
||||||
type Firewall []FirewallRule
|
|
||||||
|
|
||||||
func (f Firewall) GCP() ([]*computepb.Firewall, error) {
|
|
||||||
var fw []*computepb.Firewall
|
|
||||||
for _, rule := range f {
|
|
||||||
var srcRange []string
|
|
||||||
if rule.IPRange != "" {
|
|
||||||
srcRange = []string{rule.IPRange}
|
|
||||||
}
|
|
||||||
|
|
||||||
var ports []string
|
|
||||||
if rule.FromPort != 0 || rule.ToPort != 0 {
|
|
||||||
port, err := portOrRange(rule.FromPort, rule.ToPort)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
ports = []string{port}
|
|
||||||
}
|
|
||||||
|
|
||||||
fw = append(fw, &computepb.Firewall{
|
|
||||||
Allowed: []*computepb.Allowed{
|
|
||||||
{
|
|
||||||
IPProtocol: proto.String(rule.Protocol),
|
|
||||||
Ports: ports,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Description: proto.String(rule.Description),
|
|
||||||
SourceRanges: srcRange,
|
|
||||||
Name: proto.String(rule.Name),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return fw, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f Firewall) Azure() ([]*armnetwork.SecurityRule, error) {
|
|
||||||
var fw []*armnetwork.SecurityRule
|
|
||||||
for i, rule := range f {
|
|
||||||
// format string according to armnetwork.SecurityRuleProtocol specification
|
|
||||||
protocol := cases.Title(language.English).String(rule.Protocol)
|
|
||||||
|
|
||||||
dstPortRange, err := portOrRange(rule.FromPort, rule.ToPort)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
fw = append(fw, &armnetwork.SecurityRule{
|
|
||||||
Name: proto.String(rule.Name),
|
|
||||||
Properties: &armnetwork.SecurityRulePropertiesFormat{
|
|
||||||
Description: proto.String(rule.Description),
|
|
||||||
Protocol: (*armnetwork.SecurityRuleProtocol)(proto.String(protocol)),
|
|
||||||
SourceAddressPrefix: proto.String(rule.IPRange),
|
|
||||||
SourcePortRange: proto.String("*"),
|
|
||||||
DestinationAddressPrefix: proto.String(rule.IPRange),
|
|
||||||
DestinationPortRange: proto.String(dstPortRange),
|
|
||||||
Access: to.Ptr(armnetwork.SecurityRuleAccessAllow),
|
|
||||||
Direction: to.Ptr(armnetwork.SecurityRuleDirectionInbound),
|
|
||||||
// Each security role needs a unique priority
|
|
||||||
Priority: proto.Int32(int32(100 * (i + 1))),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return fw, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f Firewall) AWS() []ec2types.IpPermission {
|
|
||||||
var fw []ec2types.IpPermission
|
|
||||||
for _, rule := range f {
|
|
||||||
fw = append(fw, ec2types.IpPermission{
|
|
||||||
FromPort: proto.Int32(int32(rule.FromPort)),
|
|
||||||
ToPort: proto.Int32(int32(rule.ToPort)),
|
|
||||||
IpProtocol: proto.String(rule.Protocol),
|
|
||||||
IpRanges: []ec2types.IpRange{
|
|
||||||
{
|
|
||||||
CidrIp: proto.String(rule.IPRange),
|
|
||||||
Description: proto.String(rule.Description),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return fw
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
MinPort = 0
|
|
||||||
MaxPort = 65535
|
|
||||||
)
|
|
||||||
|
|
||||||
// PortOutOfRangeError occurs when either FromPort or ToPort are out of range
|
|
||||||
// of [MinPort-MaxPort].
|
|
||||||
type PortOutOfRangeError struct {
|
|
||||||
FromPort int
|
|
||||||
ToPort int
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PortOutOfRangeError) Error() string {
|
|
||||||
return fmt.Sprintf(
|
|
||||||
"[%d-%d] not in allowed port range of [%d-%d]",
|
|
||||||
p.FromPort, p.ToPort, MinPort, MaxPort,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// portOrRange returns "fromPort" as single port, if toPort is zero.
|
|
||||||
// If toPort is >0 a port range of form "fromPort-toPort".
|
|
||||||
// If either value is negative PortOutOfRangeError is returned.
|
|
||||||
func portOrRange(fromPort, toPort int) (string, error) {
|
|
||||||
if fromPort < MinPort || toPort < MinPort || fromPort > MaxPort || toPort > MaxPort {
|
|
||||||
return "", &PortOutOfRangeError{FromPort: fromPort, ToPort: toPort}
|
|
||||||
}
|
|
||||||
if toPort == MinPort || fromPort == toPort {
|
|
||||||
return fmt.Sprintf("%d", fromPort), nil
|
|
||||||
}
|
|
||||||
if toPort > MinPort {
|
|
||||||
return fmt.Sprintf("%d-%d", fromPort, toPort), nil
|
|
||||||
}
|
|
||||||
return "", &PortOutOfRangeError{FromPort: fromPort, ToPort: toPort}
|
|
||||||
}
|
|
@ -1,282 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) Edgeless Systems GmbH
|
|
||||||
|
|
||||||
SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
package cloudtypes
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strconv"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork"
|
|
||||||
ec2types "github.com/aws/aws-sdk-go-v2/service/ec2/types"
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
"google.golang.org/protobuf/proto"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestFirewallGCP(t *testing.T) {
|
|
||||||
assert := assert.New(t)
|
|
||||||
require := require.New(t)
|
|
||||||
testFw := Firewall{
|
|
||||||
{
|
|
||||||
Name: "test-1",
|
|
||||||
Description: "This is the Test-1 Permission",
|
|
||||||
Protocol: "tcp",
|
|
||||||
IPRange: "",
|
|
||||||
FromPort: 9000,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "test-2",
|
|
||||||
Description: "This is the Test-2 Permission",
|
|
||||||
Protocol: "udp",
|
|
||||||
IPRange: "",
|
|
||||||
FromPort: 51820,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "test-3",
|
|
||||||
Description: "This is the Test-3 Permission",
|
|
||||||
Protocol: "tcp",
|
|
||||||
IPRange: "192.0.2.0/24",
|
|
||||||
FromPort: 4000,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
firewalls, err := testFw.GCP()
|
|
||||||
assert.NoError(err)
|
|
||||||
assert.Equal(len(testFw), len(firewalls))
|
|
||||||
|
|
||||||
// Check permissions
|
|
||||||
for i := 0; i < len(testFw); i++ {
|
|
||||||
firewall1 := firewalls[i]
|
|
||||||
actualPermission1 := firewall1.Allowed[0]
|
|
||||||
|
|
||||||
actualPort, err := strconv.Atoi(actualPermission1.GetPorts()[0])
|
|
||||||
require.NoError(err)
|
|
||||||
assert.Equal(testFw[i].FromPort, actualPort)
|
|
||||||
assert.Equal(testFw[i].Protocol, actualPermission1.GetIPProtocol())
|
|
||||||
|
|
||||||
assert.Equal(testFw[i].Name, firewall1.GetName())
|
|
||||||
assert.Equal(testFw[i].Description, firewall1.GetDescription())
|
|
||||||
|
|
||||||
if testFw[i].IPRange != "" {
|
|
||||||
require.Len(firewall1.GetSourceRanges(), 1)
|
|
||||||
assert.Equal(testFw[i].IPRange, firewall1.GetSourceRanges()[0])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFirewallAzure(t *testing.T) {
|
|
||||||
assert := assert.New(t)
|
|
||||||
|
|
||||||
input := Firewall{
|
|
||||||
{
|
|
||||||
Name: "perm1",
|
|
||||||
Description: "perm1 description",
|
|
||||||
Protocol: "TCP",
|
|
||||||
IPRange: "192.0.2.0/24",
|
|
||||||
FromPort: 22,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "perm2",
|
|
||||||
Description: "perm2 description",
|
|
||||||
Protocol: "udp",
|
|
||||||
IPRange: "192.0.2.0/24",
|
|
||||||
FromPort: 4433,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "perm3",
|
|
||||||
Description: "perm3 description",
|
|
||||||
Protocol: "tcp",
|
|
||||||
IPRange: "192.0.2.0/24",
|
|
||||||
FromPort: 4433,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
wantOutput := []*armnetwork.SecurityRule{
|
|
||||||
{
|
|
||||||
Name: proto.String("perm1"),
|
|
||||||
Properties: &armnetwork.SecurityRulePropertiesFormat{
|
|
||||||
Description: proto.String("perm1 description"),
|
|
||||||
Protocol: to.Ptr(armnetwork.SecurityRuleProtocolTCP),
|
|
||||||
SourceAddressPrefix: proto.String("192.0.2.0/24"),
|
|
||||||
SourcePortRange: proto.String("*"),
|
|
||||||
DestinationAddressPrefix: proto.String("192.0.2.0/24"),
|
|
||||||
DestinationPortRange: proto.String("22"),
|
|
||||||
Access: to.Ptr(armnetwork.SecurityRuleAccessAllow),
|
|
||||||
Direction: to.Ptr(armnetwork.SecurityRuleDirectionInbound),
|
|
||||||
Priority: proto.Int32(100),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: proto.String("perm2"),
|
|
||||||
Properties: &armnetwork.SecurityRulePropertiesFormat{
|
|
||||||
Description: proto.String("perm2 description"),
|
|
||||||
Protocol: to.Ptr(armnetwork.SecurityRuleProtocolUDP),
|
|
||||||
SourceAddressPrefix: proto.String("192.0.2.0/24"),
|
|
||||||
SourcePortRange: proto.String("*"),
|
|
||||||
DestinationAddressPrefix: proto.String("192.0.2.0/24"),
|
|
||||||
DestinationPortRange: proto.String("4433"),
|
|
||||||
Access: to.Ptr(armnetwork.SecurityRuleAccessAllow),
|
|
||||||
Direction: to.Ptr(armnetwork.SecurityRuleDirectionInbound),
|
|
||||||
Priority: proto.Int32(200),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: proto.String("perm3"),
|
|
||||||
Properties: &armnetwork.SecurityRulePropertiesFormat{
|
|
||||||
Description: proto.String("perm3 description"),
|
|
||||||
Protocol: to.Ptr(armnetwork.SecurityRuleProtocolTCP),
|
|
||||||
SourceAddressPrefix: proto.String("192.0.2.0/24"),
|
|
||||||
SourcePortRange: proto.String("*"),
|
|
||||||
DestinationAddressPrefix: proto.String("192.0.2.0/24"),
|
|
||||||
DestinationPortRange: proto.String("4433"),
|
|
||||||
Access: to.Ptr(armnetwork.SecurityRuleAccessAllow),
|
|
||||||
Direction: to.Ptr(armnetwork.SecurityRuleDirectionInbound),
|
|
||||||
Priority: proto.Int32(300),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
out, err := input.Azure()
|
|
||||||
assert.NoError(err)
|
|
||||||
assert.Equal(wantOutput, out)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestIPPermissonsToAWS(t *testing.T) {
|
|
||||||
assert := assert.New(t)
|
|
||||||
|
|
||||||
input := Firewall{
|
|
||||||
{
|
|
||||||
Description: "perm1",
|
|
||||||
Protocol: "TCP",
|
|
||||||
IPRange: "192.0.2.0/24",
|
|
||||||
FromPort: 22,
|
|
||||||
ToPort: 22,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Description: "perm2",
|
|
||||||
Protocol: "UDP",
|
|
||||||
IPRange: "192.0.2.0/24",
|
|
||||||
FromPort: 4433,
|
|
||||||
ToPort: 4433,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Description: "perm3",
|
|
||||||
Protocol: "TCP",
|
|
||||||
IPRange: "192.0.2.0/24",
|
|
||||||
FromPort: 4433,
|
|
||||||
ToPort: 4433,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
wantOutput := []ec2types.IpPermission{
|
|
||||||
{
|
|
||||||
FromPort: proto.Int32(int32(22)),
|
|
||||||
ToPort: proto.Int32(int32(22)),
|
|
||||||
IpProtocol: proto.String("TCP"),
|
|
||||||
IpRanges: []ec2types.IpRange{
|
|
||||||
{
|
|
||||||
CidrIp: proto.String("192.0.2.0/24"),
|
|
||||||
Description: proto.String("perm1"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
FromPort: proto.Int32(int32(4433)),
|
|
||||||
ToPort: proto.Int32(int32(4433)),
|
|
||||||
IpProtocol: proto.String("UDP"),
|
|
||||||
IpRanges: []ec2types.IpRange{
|
|
||||||
{
|
|
||||||
CidrIp: proto.String("192.0.2.0/24"),
|
|
||||||
Description: proto.String("perm2"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
FromPort: proto.Int32(int32(4433)),
|
|
||||||
ToPort: proto.Int32(int32(4433)),
|
|
||||||
IpProtocol: proto.String("TCP"),
|
|
||||||
IpRanges: []ec2types.IpRange{
|
|
||||||
{
|
|
||||||
CidrIp: proto.String("192.0.2.0/24"),
|
|
||||||
Description: proto.String("perm3"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
out := input.AWS()
|
|
||||||
assert.Equal(wantOutput, out)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPortOrRange(t *testing.T) {
|
|
||||||
testCases := map[string]struct {
|
|
||||||
fromPort int
|
|
||||||
toPort int
|
|
||||||
result string
|
|
||||||
wantErr bool
|
|
||||||
}{
|
|
||||||
"ssh": {
|
|
||||||
fromPort: 22,
|
|
||||||
result: "22",
|
|
||||||
},
|
|
||||||
"https": {
|
|
||||||
fromPort: 443,
|
|
||||||
result: "443",
|
|
||||||
},
|
|
||||||
"nodePorts": {
|
|
||||||
fromPort: 30000,
|
|
||||||
toPort: 32767,
|
|
||||||
result: "30000-32767",
|
|
||||||
},
|
|
||||||
"negative fromPort": {
|
|
||||||
fromPort: -1,
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
"negative toPort": {
|
|
||||||
toPort: -1,
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
"same value no range": {
|
|
||||||
fromPort: 22,
|
|
||||||
toPort: 22,
|
|
||||||
result: "22",
|
|
||||||
},
|
|
||||||
"from zero to ssh": {
|
|
||||||
toPort: 22,
|
|
||||||
result: "0-22",
|
|
||||||
},
|
|
||||||
"from max": {
|
|
||||||
fromPort: MaxPort,
|
|
||||||
result: "65535",
|
|
||||||
},
|
|
||||||
"from max+1": {
|
|
||||||
fromPort: MaxPort + 1,
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
"to max": {
|
|
||||||
toPort: MaxPort,
|
|
||||||
result: "0-65535",
|
|
||||||
},
|
|
||||||
"to max+1": {
|
|
||||||
toPort: MaxPort + 1,
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for name, tc := range testCases {
|
|
||||||
t.Run(name, func(t *testing.T) {
|
|
||||||
assert := assert.New(t)
|
|
||||||
|
|
||||||
got, err := portOrRange(tc.fromPort, tc.toPort)
|
|
||||||
if tc.wantErr {
|
|
||||||
assert.Error(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
assert.NoError(err)
|
|
||||||
assert.Equal(tc.result, got)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,70 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) Edgeless Systems GmbH
|
|
||||||
|
|
||||||
SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
package cloudtypes
|
|
||||||
|
|
||||||
import "errors"
|
|
||||||
|
|
||||||
// Instance is a gcp instance.
|
|
||||||
type Instance struct {
|
|
||||||
PublicIP string
|
|
||||||
PrivateIP string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Instances is a map of gcp Instances. The ID of an instance is used as key.
|
|
||||||
type Instances map[string]Instance
|
|
||||||
|
|
||||||
// IDs returns the IDs of all instances of the Constellation.
|
|
||||||
func (i Instances) IDs() []string {
|
|
||||||
var ids []string
|
|
||||||
for id := range i {
|
|
||||||
ids = append(ids, id)
|
|
||||||
}
|
|
||||||
return ids
|
|
||||||
}
|
|
||||||
|
|
||||||
// PublicIPs returns the public IPs of all the instances of the Constellation.
|
|
||||||
func (i Instances) PublicIPs() []string {
|
|
||||||
var ips []string
|
|
||||||
for _, instance := range i {
|
|
||||||
ips = append(ips, instance.PublicIP)
|
|
||||||
}
|
|
||||||
return ips
|
|
||||||
}
|
|
||||||
|
|
||||||
// PrivateIPs returns the private IPs of all the instances of the Constellation.
|
|
||||||
func (i Instances) PrivateIPs() []string {
|
|
||||||
var ips []string
|
|
||||||
for _, instance := range i {
|
|
||||||
ips = append(ips, instance.PrivateIP)
|
|
||||||
}
|
|
||||||
return ips
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetOne return anyone instance out of the instances and its ID.
|
|
||||||
func (i Instances) GetOne() (string, Instance, error) {
|
|
||||||
for id, instance := range i {
|
|
||||||
return id, instance, nil
|
|
||||||
}
|
|
||||||
return "", Instance{}, errors.New("map is empty")
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetOthers returns all instances but the one with the handed ID.
|
|
||||||
func (i Instances) GetOthers(id string) Instances {
|
|
||||||
others := make(Instances)
|
|
||||||
for key, instance := range i {
|
|
||||||
if key != id {
|
|
||||||
others[key] = instance
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return others
|
|
||||||
}
|
|
||||||
|
|
||||||
// ScalingGroup is a group of instances, with an identifying group ID.
|
|
||||||
type ScalingGroup struct {
|
|
||||||
Instances
|
|
||||||
GroupID string
|
|
||||||
}
|
|
@ -1,82 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) Edgeless Systems GmbH
|
|
||||||
|
|
||||||
SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
package cloudtypes
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"go.uber.org/goleak"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
|
||||||
goleak.VerifyTestMain(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestIDs(t *testing.T) {
|
|
||||||
assert := assert.New(t)
|
|
||||||
testState := testInstances()
|
|
||||||
wantIDs := []string{"id-9", "id-10", "id-11", "id-12"}
|
|
||||||
assert.ElementsMatch(wantIDs, testState.IDs())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPublicIPs(t *testing.T) {
|
|
||||||
assert := assert.New(t)
|
|
||||||
testState := testInstances()
|
|
||||||
wantIPs := []string{"192.0.2.1", "192.0.2.3", "192.0.2.5", "192.0.2.7"}
|
|
||||||
assert.ElementsMatch(wantIPs, testState.PublicIPs())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPrivateIPs(t *testing.T) {
|
|
||||||
assert := assert.New(t)
|
|
||||||
testState := testInstances()
|
|
||||||
wantIPs := []string{"192.0.2.2", "192.0.2.4", "192.0.2.6", "192.0.2.8"}
|
|
||||||
assert.ElementsMatch(wantIPs, testState.PrivateIPs())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetOne(t *testing.T) {
|
|
||||||
assert := assert.New(t)
|
|
||||||
testState := testInstances()
|
|
||||||
id, instance, err := testState.GetOne()
|
|
||||||
assert.NoError(err)
|
|
||||||
assert.Contains(testState, id)
|
|
||||||
assert.Equal(testState[id], instance)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetOthers(t *testing.T) {
|
|
||||||
assert := assert.New(t)
|
|
||||||
testCases := testInstances().IDs()
|
|
||||||
|
|
||||||
for _, id := range testCases {
|
|
||||||
others := testInstances().GetOthers(id)
|
|
||||||
assert.NotContains(others, id)
|
|
||||||
wantInstances := testInstances()
|
|
||||||
delete(wantInstances, id)
|
|
||||||
assert.ElementsMatch(others.IDs(), wantInstances.IDs())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testInstances() Instances {
|
|
||||||
return Instances{
|
|
||||||
"id-9": {
|
|
||||||
PublicIP: "192.0.2.1",
|
|
||||||
PrivateIP: "192.0.2.2",
|
|
||||||
},
|
|
||||||
"id-10": {
|
|
||||||
PublicIP: "192.0.2.3",
|
|
||||||
PrivateIP: "192.0.2.4",
|
|
||||||
},
|
|
||||||
"id-11": {
|
|
||||||
PublicIP: "192.0.2.5",
|
|
||||||
PrivateIP: "192.0.2.6",
|
|
||||||
},
|
|
||||||
"id-12": {
|
|
||||||
PublicIP: "192.0.2.7",
|
|
||||||
PrivateIP: "192.0.2.8",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
@ -52,7 +52,7 @@ func (m *Metadata) Self(ctx context.Context) (metadata.InstanceMetadata, error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetInstance retrieves an instance using its providerID.
|
// GetInstance retrieves an instance using its providerID.
|
||||||
func (m Metadata) GetInstance(ctx context.Context, providerID string) (metadata.InstanceMetadata, error) {
|
func (m *Metadata) GetInstance(ctx context.Context, providerID string) (metadata.InstanceMetadata, error) {
|
||||||
instances, err := m.List(ctx)
|
instances, err := m.List(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return metadata.InstanceMetadata{}, err
|
return metadata.InstanceMetadata{}, err
|
||||||
@ -66,29 +66,31 @@ func (m Metadata) GetInstance(ctx context.Context, providerID string) (metadata.
|
|||||||
return metadata.InstanceMetadata{}, errors.New("instance not found")
|
return metadata.InstanceMetadata{}, errors.New("instance not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
// SupportsLoadBalancer returns true if the cloud provider supports load balancers.
|
|
||||||
func (m Metadata) SupportsLoadBalancer() bool {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetLoadBalancerEndpoint returns the endpoint of the load balancer.
|
// GetLoadBalancerEndpoint returns the endpoint of the load balancer.
|
||||||
func (m Metadata) GetLoadBalancerEndpoint(ctx context.Context) (string, error) {
|
// For QEMU, the load balancer is the first control plane node returned by the metadata API.
|
||||||
panic("function *Metadata.GetLoadBalancerEndpoint not implemented")
|
func (m *Metadata) GetLoadBalancerEndpoint(ctx context.Context) (string, error) {
|
||||||
|
endpointRaw, err := m.retrieveMetadata(ctx, "/endpoint")
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
var endpoint string
|
||||||
|
err = json.Unmarshal(endpointRaw, &endpoint)
|
||||||
|
return endpoint, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// UID returns the UID of the constellation.
|
// UID returns the UID of the constellation.
|
||||||
func (m Metadata) UID(ctx context.Context) (string, error) {
|
func (m *Metadata) UID(ctx context.Context) (string, error) {
|
||||||
// We expect only one constellation to be deployed in the same QEMU / libvirt environment.
|
// We expect only one constellation to be deployed in the same QEMU / libvirt environment.
|
||||||
// the UID can be an empty string.
|
// the UID can be an empty string.
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSubnetworkCIDR retrieves the subnetwork CIDR from cloud provider metadata.
|
// GetSubnetworkCIDR retrieves the subnetwork CIDR from cloud provider metadata.
|
||||||
func (m Metadata) GetSubnetworkCIDR(ctx context.Context) (string, error) {
|
func (m *Metadata) GetSubnetworkCIDR(ctx context.Context) (string, error) {
|
||||||
return "10.244.0.0/16", nil
|
return "10.244.0.0/16", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m Metadata) retrieveMetadata(ctx context.Context, uri string) ([]byte, error) {
|
func (m *Metadata) retrieveMetadata(ctx context.Context, uri string) ([]byte, error) {
|
||||||
url := &url.URL{
|
url := &url.URL{
|
||||||
Scheme: "http",
|
Scheme: "http",
|
||||||
Host: qemuMetadataEndpoint,
|
Host: qemuMetadataEndpoint,
|
||||||
|
@ -1,74 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) Edgeless Systems GmbH
|
|
||||||
|
|
||||||
SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
package constants
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudtypes"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// IngressRulesNoDebug is the default set of ingress rules for a Constellation cluster without debug mode.
|
|
||||||
IngressRulesNoDebug = cloudtypes.Firewall{
|
|
||||||
{
|
|
||||||
Name: "bootstrapper",
|
|
||||||
Description: "bootstrapper default port",
|
|
||||||
Protocol: "tcp",
|
|
||||||
IPRange: "0.0.0.0/0",
|
|
||||||
FromPort: BootstrapperPort,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "ssh",
|
|
||||||
Description: "SSH",
|
|
||||||
Protocol: "tcp",
|
|
||||||
IPRange: "0.0.0.0/0",
|
|
||||||
FromPort: SSHPort,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "nodeport",
|
|
||||||
Description: "NodePort",
|
|
||||||
Protocol: "tcp",
|
|
||||||
IPRange: "0.0.0.0/0",
|
|
||||||
FromPort: NodePortFrom,
|
|
||||||
ToPort: NodePortTo,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "kubernetes",
|
|
||||||
Description: "Kubernetes",
|
|
||||||
Protocol: "tcp",
|
|
||||||
IPRange: "0.0.0.0/0",
|
|
||||||
FromPort: KubernetesPort,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "konnectivity",
|
|
||||||
Description: "konnectivity",
|
|
||||||
Protocol: "tcp",
|
|
||||||
IPRange: "0.0.0.0/0",
|
|
||||||
FromPort: KonnectivityPort,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "recovery",
|
|
||||||
Description: "control-plane recovery",
|
|
||||||
Protocol: "tcp",
|
|
||||||
IPRange: "0.0.0.0/0",
|
|
||||||
FromPort: RecoveryPort,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// IngressRulesDebug is the default set of ingress rules for a Constellation cluster with debug mode.
|
|
||||||
IngressRulesDebug = append(IngressRulesNoDebug, cloudtypes.Firewall{
|
|
||||||
{
|
|
||||||
Name: "debugd",
|
|
||||||
Description: "debugd",
|
|
||||||
Protocol: "tcp",
|
|
||||||
IPRange: "0.0.0.0/0",
|
|
||||||
FromPort: DebugdPort,
|
|
||||||
},
|
|
||||||
}...)
|
|
||||||
|
|
||||||
// EgressRules is the default set of egress rules for a Constellation cluster.
|
|
||||||
EgressRules = cloudtypes.Firewall{}
|
|
||||||
)
|
|
Loading…
Reference in New Issue
Block a user