mirror of
https://github.com/mulgadc/spinifex.git
synced 2026-10-22 12:16:52 +00:00
cec915d11c
DefaultSGReachabilityBaseline, GuestDNSResolution, and SecurityGroupEgress each booted their own instance to check one facet of "a guest is reachable only when policy says so": ingress deny/authorize, resolver + WAN egress, and egress ACL enforcement. Merging them around one shared guest cuts three boots to one, with named t.Run stages (Deny, Authorize, Resolver, WANEgress, RevokeEgress/RestoreEgress) giving each its own attribution. The egress revoke/restore round-trip now mutates this scenario's own dedicated SG instead of the shared default SG the rest of the suite depends on, isolating its egress-rule mutation from every other test.
68 lines
2.2 KiB
Go
68 lines
2.2 KiB
Go
//go:build e2e
|
||
|
||
package single
|
||
|
||
import (
|
||
"bytes"
|
||
"os/exec"
|
||
"regexp"
|
||
"strconv"
|
||
|
||
"github.com/aws/aws-sdk-go/aws"
|
||
"github.com/aws/aws-sdk-go/service/ec2"
|
||
"github.com/mulgadc/spinifex/tests/e2e/harness"
|
||
)
|
||
|
||
// pingReceivedRE matches the busybox/iputils summary line for 1–3 echo replies
|
||
// (`3 packets received` or `1 received`). Mirrors the bash grep pattern.
|
||
var pingReceivedRE = regexp.MustCompile(`[1-3] (packets )?received`)
|
||
|
||
// pingDroppedRE matches the summary for a fully dropped probe — either
|
||
// `0 received` or `100% packet loss`. Mirrors the bash grep pattern.
|
||
var pingDroppedRE = regexp.MustCompile(`0 (packets )?received|100% packet loss`)
|
||
|
||
// allowAllEgressPermission returns the SDK shape for the default SG's stock
|
||
// `IpProtocol=-1, CidrIp=0.0.0.0/0` rule.
|
||
func allowAllEgressPermission() *ec2.IpPermission {
|
||
return &ec2.IpPermission{
|
||
IpProtocol: aws.String("-1"),
|
||
IpRanges: []*ec2.IpRange{{CidrIp: aws.String("0.0.0.0/0")}},
|
||
}
|
||
}
|
||
|
||
// authorizeAllowAllEgress is the idempotent re-add used both by the happy
|
||
// path and t.Cleanup. Returns the raw SDK error so the caller can decide
|
||
// whether `InvalidPermission.Duplicate` is fatal in its context.
|
||
func authorizeAllowAllEgress(c *harness.AWSClient, sgID string) error {
|
||
_, err := c.EC2.AuthorizeSecurityGroupEgress(&ec2.AuthorizeSecurityGroupEgressInput{
|
||
GroupId: aws.String(sgID),
|
||
IpPermissions: []*ec2.IpPermission{allowAllEgressPermission()},
|
||
})
|
||
return err
|
||
}
|
||
|
||
// runSSHCombined runs `command` over SSH against tgt and returns combined
|
||
// stdout+stderr regardless of exit status. Unlike runSSH (instance_test.go)
|
||
// it does not t.Fatal on non-zero exit — needed because `ping` legitimately
|
||
// exits non-zero when packets are dropped, which is the expected outcome of
|
||
// the revoke test.
|
||
func runSSHCombined(tgt harness.SSHTarget, command string) (string, error) {
|
||
args := []string{
|
||
"-o", "StrictHostKeyChecking=no",
|
||
"-o", "UserKnownHostsFile=/dev/null",
|
||
"-o", "LogLevel=ERROR",
|
||
"-o", "ConnectTimeout=5",
|
||
"-o", "BatchMode=yes",
|
||
"-p", strconv.Itoa(tgt.Port),
|
||
"-i", tgt.KeyPath,
|
||
tgt.User + "@" + tgt.Host,
|
||
command,
|
||
}
|
||
var combined bytes.Buffer
|
||
cmd := exec.Command("ssh", args...)
|
||
cmd.Stdout = &combined
|
||
cmd.Stderr = &combined
|
||
err := cmd.Run()
|
||
return combined.String(), err
|
||
}
|