Rolling back the port configs if failed to programIngress()

Signed-off-by: fanjiyun <fan.jiyun@zte.com.cn>
This commit is contained in:
fanjiyun 2018-02-05 14:17:07 +08:00
parent 3321709a62
commit 03ba96c5cf
2 changed files with 40 additions and 18 deletions

View File

@ -76,7 +76,7 @@ func reexecSetupResolver() {
for _, rule := range rules {
if iptables.RawCombinedOutputNative(rule...) != nil {
logrus.Errorf("setting up rule failed, %v", rule)
logrus.Errorf("set up rule failed, %v", rule)
}
}
}

View File

@ -135,8 +135,7 @@ func (n *network) addLBBackend(ip net.IP, lb *loadBalancer) {
if ep := sb.getGatewayEndpoint(); ep != nil {
gwIP = ep.Iface().Address().IP
}
filteredPorts := filterPortConfigs(lb.service.ingressPorts, false)
if err := programIngress(gwIP, filteredPorts, false); err != nil {
if err := programIngress(gwIP, lb.service.ingressPorts, false); err != nil {
logrus.Errorf("Failed to add ingress: %v", err)
return
}
@ -227,8 +226,7 @@ func (n *network) rmLBBackend(ip net.IP, lb *loadBalancer, rmService bool, fullR
if ep := sb.getGatewayEndpoint(); ep != nil {
gwIP = ep.Iface().Address().IP
}
filteredPorts := filterPortConfigs(lb.service.ingressPorts, true)
if err := programIngress(gwIP, filteredPorts, true); err != nil {
if err := programIngress(gwIP, lb.service.ingressPorts, true); err != nil {
logrus.Errorf("Failed to delete ingress: %v", err)
}
}
@ -299,8 +297,10 @@ func filterPortConfigs(ingressPorts []*PortConfig, isDelete bool) []*PortConfig
func programIngress(gwIP net.IP, ingressPorts []*PortConfig, isDelete bool) error {
addDelOpt := "-I"
rollbackAddDelOpt := "-D"
if isDelete {
addDelOpt = "-D"
rollbackAddDelOpt = "-I"
}
ingressMu.Lock()
@ -381,18 +381,35 @@ func programIngress(gwIP net.IP, ingressPorts []*PortConfig, isDelete bool) erro
}
}
for _, iPort := range ingressPorts {
//Filter the ingress ports until port rules start to be added/deleted
filteredPorts := filterPortConfigs(ingressPorts, isDelete)
rollbackRules := make([][]string, 0, len(filteredPorts)*3)
var portErr error
defer func() {
if portErr != nil && !isDelete {
filterPortConfigs(filteredPorts, !isDelete)
for _, rule := range rollbackRules {
if err := iptables.RawCombinedOutput(rule...); err != nil {
logrus.Warnf("roll back rule failed, %v: %v", rule, err)
}
}
}
}()
for _, iPort := range filteredPorts {
if iptables.ExistChain(ingressChain, iptables.Nat) {
rule := strings.Fields(fmt.Sprintf("-t nat %s %s -p %s --dport %d -j DNAT --to-destination %s:%d",
addDelOpt, ingressChain, strings.ToLower(PortConfig_Protocol_name[int32(iPort.Protocol)]), iPort.PublishedPort, gwIP, iPort.PublishedPort))
if err := iptables.RawCombinedOutput(rule...); err != nil {
errStr := fmt.Sprintf("setting up rule failed, %v: %v", rule, err)
if portErr = iptables.RawCombinedOutput(rule...); portErr != nil {
errStr := fmt.Sprintf("set up rule failed, %v: %v", rule, portErr)
if !isDelete {
return fmt.Errorf("%s", errStr)
}
logrus.Infof("%s", errStr)
}
rollbackRule := strings.Fields(fmt.Sprintf("-t nat %s %s -p %s --dport %d -j DNAT --to-destination %s:%d", rollbackAddDelOpt,
ingressChain, strings.ToLower(PortConfig_Protocol_name[int32(iPort.Protocol)]), iPort.PublishedPort, gwIP, iPort.PublishedPort))
rollbackRules = append(rollbackRules, rollbackRule)
}
// Filter table rules to allow a published service to be accessible in the local node from..
@ -400,24 +417,29 @@ func programIngress(gwIP net.IP, ingressPorts []*PortConfig, isDelete bool) erro
// 2) unmanaged containers on bridge networks
rule := strings.Fields(fmt.Sprintf("%s %s -m state -p %s --sport %d --state ESTABLISHED,RELATED -j ACCEPT",
addDelOpt, ingressChain, strings.ToLower(PortConfig_Protocol_name[int32(iPort.Protocol)]), iPort.PublishedPort))
if err := iptables.RawCombinedOutput(rule...); err != nil {
errStr := fmt.Sprintf("setting up rule failed, %v: %v", rule, err)
if portErr = iptables.RawCombinedOutput(rule...); portErr != nil {
errStr := fmt.Sprintf("set up rule failed, %v: %v", rule, portErr)
if !isDelete {
return fmt.Errorf("%s", errStr)
}
logrus.Warnf("%s", errStr)
}
rollbackRule := strings.Fields(fmt.Sprintf("%s %s -m state -p %s --sport %d --state ESTABLISHED,RELATED -j ACCEPT", rollbackAddDelOpt,
ingressChain, strings.ToLower(PortConfig_Protocol_name[int32(iPort.Protocol)]), iPort.PublishedPort))
rollbackRules = append(rollbackRules, rollbackRule)
rule = strings.Fields(fmt.Sprintf("%s %s -p %s --dport %d -j ACCEPT",
addDelOpt, ingressChain, strings.ToLower(PortConfig_Protocol_name[int32(iPort.Protocol)]), iPort.PublishedPort))
if err := iptables.RawCombinedOutput(rule...); err != nil {
errStr := fmt.Sprintf("setting up rule failed, %v: %v", rule, err)
if portErr = iptables.RawCombinedOutput(rule...); portErr != nil {
errStr := fmt.Sprintf("set up rule failed, %v: %v", rule, portErr)
if !isDelete {
return fmt.Errorf("%s", errStr)
}
logrus.Warnf("%s", errStr)
}
rollbackRule = strings.Fields(fmt.Sprintf("%s %s -p %s --dport %d -j ACCEPT", rollbackAddDelOpt,
ingressChain, strings.ToLower(PortConfig_Protocol_name[int32(iPort.Protocol)]), iPort.PublishedPort))
rollbackRules = append(rollbackRules, rollbackRule)
if err := plumbProxy(iPort, isDelete); err != nil {
logrus.Warnf("failed to create proxy for port %d: %v", iPort.PublishedPort, err)
@ -648,7 +670,7 @@ func fwMarker() {
for _, rule := range rules {
if err := iptables.RawCombinedOutputNative(rule...); err != nil {
logrus.Errorf("setting up rule failed, %v: %v", rule, err)
logrus.Errorf("set up rule failed, %v: %v", rule, err)
os.Exit(8)
}
}
@ -735,7 +757,7 @@ func redirector() {
for _, rule := range rules {
if err := iptables.RawCombinedOutputNative(rule...); err != nil {
logrus.Errorf("setting up rule failed, %v: %v", rule, err)
logrus.Errorf("set up rule failed, %v: %v", rule, err)
os.Exit(6)
}
}
@ -752,14 +774,14 @@ func redirector() {
} {
if !iptables.ExistsNative(iptables.Filter, "INPUT", rule...) {
if err := iptables.RawCombinedOutputNative(append([]string{"-A", "INPUT"}, rule...)...); err != nil {
logrus.Errorf("setting up rule failed, %v: %v", rule, err)
logrus.Errorf("set up rule failed, %v: %v", rule, err)
os.Exit(7)
}
}
rule[0] = "-s"
if !iptables.ExistsNative(iptables.Filter, "OUTPUT", rule...) {
if err := iptables.RawCombinedOutputNative(append([]string{"-A", "OUTPUT"}, rule...)...); err != nil {
logrus.Errorf("setting up rule failed, %v: %v", rule, err)
logrus.Errorf("set up rule failed, %v: %v", rule, err)
os.Exit(8)
}
}