mirror of
				https://github.com/siderolabs/talos.git
				synced 2025-10-31 00:11:36 +01:00 
			
		
		
		
	Fixes #4421 See documentation for details on how to use the feature. With `talosctl cluster create`, firewall can be easily test with `--with-firewall=accept|block` (default mode). Signed-off-by: Andrey Smirnov <andrey.smirnov@siderolabs.com>
		
			
				
	
	
		
			121 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			121 lines
		
	
	
		
			2.9 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/.
 | |
| 
 | |
| //go:build integration_api
 | |
| 
 | |
| package api
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"crypto/tls"
 | |
| 	"errors"
 | |
| 	"fmt"
 | |
| 	"net"
 | |
| 	"net/http"
 | |
| 	"os"
 | |
| 	"strconv"
 | |
| 	"time"
 | |
| 
 | |
| 	"github.com/cosi-project/runtime/pkg/safe"
 | |
| 	"github.com/hashicorp/go-cleanhttp"
 | |
| 	"golang.org/x/sync/errgroup"
 | |
| 
 | |
| 	"github.com/siderolabs/talos/internal/integration/base"
 | |
| 	"github.com/siderolabs/talos/pkg/machinery/client"
 | |
| 	"github.com/siderolabs/talos/pkg/machinery/constants"
 | |
| 	"github.com/siderolabs/talos/pkg/machinery/resources/network"
 | |
| )
 | |
| 
 | |
| // FirewallSuite ...
 | |
| type FirewallSuite struct {
 | |
| 	base.APISuite
 | |
| 
 | |
| 	ctx       context.Context //nolint:containedctx
 | |
| 	ctxCancel context.CancelFunc
 | |
| }
 | |
| 
 | |
| // SuiteName ...
 | |
| func (suite *FirewallSuite) SuiteName() string {
 | |
| 	return "api.FirewallSuite"
 | |
| }
 | |
| 
 | |
| // SetupTest ...
 | |
| func (suite *FirewallSuite) SetupTest() {
 | |
| 	if suite.Cluster == nil {
 | |
| 		suite.T().Skip("without full cluster state can't guarantee availability of kubelet IPs")
 | |
| 	}
 | |
| 
 | |
| 	// make sure we abort at some point in time, but give enough room for Resets
 | |
| 	suite.ctx, suite.ctxCancel = context.WithTimeout(context.Background(), 30*time.Second)
 | |
| }
 | |
| 
 | |
| // TearDownTest ...
 | |
| func (suite *FirewallSuite) TearDownTest() {
 | |
| 	if suite.ctxCancel != nil {
 | |
| 		suite.ctxCancel()
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // TestKubeletAccess verifies that without firewall kubelet API is available, and not available otherwise.
 | |
| func (suite *FirewallSuite) TestKubeletAccess() {
 | |
| 	allNodes := suite.DiscoverNodeInternalIPs(suite.ctx)
 | |
| 
 | |
| 	_, err := safe.StateGetByID[*network.NfTablesChain](client.WithNode(suite.ctx, allNodes[0]), suite.Client.COSI, "ingress")
 | |
| 	firewallEnabled := err == nil
 | |
| 
 | |
| 	eg, ctx := errgroup.WithContext(suite.ctx)
 | |
| 
 | |
| 	transport := cleanhttp.DefaultTransport()
 | |
| 	transport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
 | |
| 
 | |
| 	client := http.Client{
 | |
| 		Transport: transport,
 | |
| 	}
 | |
| 
 | |
| 	for _, node := range allNodes {
 | |
| 		node := node
 | |
| 
 | |
| 		eg.Go(func() error {
 | |
| 			attemptCtx, cancel := context.WithTimeout(ctx, time.Second)
 | |
| 			defer cancel()
 | |
| 
 | |
| 			req, err := http.NewRequestWithContext(
 | |
| 				attemptCtx,
 | |
| 				http.MethodGet,
 | |
| 				fmt.Sprintf("https://%s/healthz", net.JoinHostPort(node, strconv.Itoa(constants.KubeletPort))),
 | |
| 				nil,
 | |
| 			)
 | |
| 			if err != nil {
 | |
| 				return err
 | |
| 			}
 | |
| 
 | |
| 			resp, err := client.Do(req)
 | |
| 
 | |
| 			if resp != nil {
 | |
| 				resp.Body.Close() //nolint:errcheck
 | |
| 			}
 | |
| 
 | |
| 			if firewallEnabled {
 | |
| 				if err == nil {
 | |
| 					return fmt.Errorf("kubelet API should not be available")
 | |
| 				}
 | |
| 
 | |
| 				if !errors.Is(err, os.ErrDeadlineExceeded) && !errors.Is(err, context.DeadlineExceeded) {
 | |
| 					return fmt.Errorf("unexpected error: %w", err)
 | |
| 				}
 | |
| 			} else if err != nil {
 | |
| 				return fmt.Errorf("kubelet API should be available: %w", err)
 | |
| 			}
 | |
| 
 | |
| 			return nil
 | |
| 		})
 | |
| 	}
 | |
| 
 | |
| 	suite.Require().NoError(eg.Wait())
 | |
| }
 | |
| 
 | |
| func init() {
 | |
| 	allSuites = append(allSuites, new(FirewallSuite))
 | |
| }
 |