istio
106 строк · 3.4 Кб
1// Copyright Istio Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package dependencies16
17import (18"bufio"19"fmt"20"io"21"os"22"strings"23
24"istio.io/istio/pkg/env"25"istio.io/istio/tools/istio-iptables/pkg/constants"26)
27
28var DryRunFilePath = env.Register("DRY_RUN_FILE_PATH", "", "If provided, StdoutStubDependencies will write the input from stdin to the given file.")29
30// TODO BML replace DIY mocks/state with something better
31type DependenciesStub struct {32ExecutedNormally []string33ExecutedQuietly []string34ExecutedStdin []string35ExecutedAll []string36}
37
38func (s *DependenciesStub) Run(cmd constants.IptablesCmd, iptVer *IptablesVersion, stdin io.ReadSeeker, args ...string) error {39s.execute(false /*quietly*/, cmd, iptVer, stdin, args...)40_ = s.writeAllToDryRunPath()41return nil42}
43
44func (s *DependenciesStub) RunQuietlyAndIgnore(cmd constants.IptablesCmd, iptVer *IptablesVersion, stdin io.ReadSeeker, args ...string) {45s.execute(true /*quietly*/, cmd, iptVer, stdin, args...)46_ = s.writeAllToDryRunPath()47}
48
49func (s *DependenciesStub) DetectIptablesVersion(ipV6 bool) (IptablesVersion, error) {50if ipV6 {51return IptablesVersion{52DetectedBinary: "ip6tables",53DetectedSaveBinary: "ip6tables-save",54DetectedRestoreBinary: "ip6tables-restore",55}, nil56}57return IptablesVersion{58DetectedBinary: "iptables",59DetectedSaveBinary: "iptables-save",60DetectedRestoreBinary: "iptables-restore",61}, nil62}
63
64func (s *DependenciesStub) execute(quietly bool, cmd constants.IptablesCmd, iptVer *IptablesVersion, stdin io.ReadSeeker, args ...string) {65// We are either getting iptables rules as a `stdin` blob in `iptables-save` format (if this is a restore)66if stdin != nil {67buf := bufio.NewScanner(stdin)68for buf.Scan() {69stdincmd := buf.Text()70s.ExecutedAll = append(s.ExecutedAll, stdincmd)71s.ExecutedStdin = append(s.ExecutedStdin, stdincmd)72}73} else {74// ...or as discrete individual commands75cmdline := strings.Join(append([]string{iptVer.CmdToString(cmd)}, args...), " ")76s.ExecutedAll = append(s.ExecutedAll, cmdline)77if quietly {78s.ExecutedQuietly = append(s.ExecutedQuietly, cmdline)79} else {80s.ExecutedNormally = append(s.ExecutedNormally, cmdline)81}82}83}
84
85// TODO BML this is more than a stub actually needs to do, we should be able to drop this testing hack
86// and skip writing to a file, but some tests are not *actually* doing unit testing and need this.
87func (s *DependenciesStub) writeAllToDryRunPath() error {88path := DryRunFilePath.Get()89if path != "" {90// Print the input into the given output file.91f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, 0o644)92if err != nil {93return fmt.Errorf("unable to open dry run output file %v: %v", path, err)94}95
96defer f.Close()97
98for _, line := range s.ExecutedAll {99_, err := f.WriteString(line + "\n")100if err != nil {101return fmt.Errorf("unable to write lines to dry run output file %v: %v", path, err)102}103}104}105return nil106}
107