-
Notifications
You must be signed in to change notification settings - Fork 153
/
eip.go
134 lines (123 loc) · 3.95 KB
/
eip.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package daemon
import (
"context"
"fmt"
"net"
"github.com/AliyunContainerService/terway/pkg/aliyun"
"github.com/AliyunContainerService/terway/pkg/ipam"
"github.com/AliyunContainerService/terway/pkg/tracing"
"github.com/AliyunContainerService/terway/types"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
// eip resource manager for pod public ip address
type eipResourceManager struct {
ecs ipam.API
k8s Kubernetes
allowEipRob bool
}
func newEipResourceManager(e ipam.API, k Kubernetes, allowEipRob bool) ResourceManager {
return &eipResourceManager{
ecs: e,
k8s: k,
allowEipRob: allowEipRob,
}
}
func (e *eipResourceManager) Allocate(context *networkContext, prefer string) (types.NetworkResource, error) {
logrus.Infof("Allocate EIP: %v, %v", context.pod, context.resources)
if context.pod == nil {
return nil, fmt.Errorf("invalid pod info: %v", context.pod)
}
var (
eniID string
eniIP net.IP
err error
)
ctx := context.Context
podIP := context.pod.PodIPs.IPv4
if podIP == nil {
return nil, errors.Errorf("invalid pod ip: %v", context.pod.PodIP)
}
for _, res := range context.resources {
switch res.Type {
case types.ResourceTypeENI, types.ResourceTypeENIIP:
eniID, err = e.ecs.QueryEniIDByIP(ctx, aliyun.GetInstanceMeta().VPCID, podIP)
if err != nil {
return nil, errors.Wrapf(err, "error Query ENI by pod IP, %v", context.pod)
}
eniIP = podIP
}
}
if eniID == "" && eniIP == nil {
return nil, fmt.Errorf("pod network mode not support EIP associate")
}
eipID := context.pod.EipInfo.PodEipID
if eipID == "" {
eipID = prefer
}
eipInfo, err := e.ecs.AllocateEipAddress(ctx, context.pod.EipInfo.PodEipBandWidth, context.pod.EipInfo.PodEipChargeType,
eipID, eniID, eniIP, e.allowEipRob)
if err != nil {
return nil, errors.Errorf("error allocate eip info: %v", err)
}
context.pod.EipInfo.PodEipIP = eipInfo.Address.String()
err = e.k8s.PatchEipInfo(context.pod)
if err != nil {
var err1 error
if eipInfo.Delete {
err1 = e.ecs.ReleaseEipAddress(ctx, eipInfo.ID, eniID, eniIP)
} else {
err1 = e.ecs.UnassociateEipAddress(ctx, eipInfo.ID, eniID, eniIP.String())
}
if err1 != nil {
logrus.Errorf("error rollback eip: %v", err1)
}
return nil, errors.Errorf("error patch pod info: %v", err)
}
return eipInfo, nil
}
func (e *eipResourceManager) Release(context *networkContext, resItem types.ResourceItem) error {
if resItem.ExtraEipInfo == nil {
return nil
}
logrus.Infof("release eip: %v, %v", resItem.ID, resItem.ExtraEipInfo)
ctx := context.Context
if resItem.ExtraEipInfo.Delete {
err := e.ecs.ReleaseEipAddress(ctx, resItem.ID, resItem.ExtraEipInfo.AssociateENI, resItem.ExtraEipInfo.AssociateENIIP)
if err != nil {
return err
}
} else {
err := e.ecs.UnassociateEipAddress(ctx, resItem.ID, resItem.ExtraEipInfo.AssociateENI, resItem.ExtraEipInfo.AssociateENIIP.String())
if err != nil {
return err
}
}
return nil
}
func (e *eipResourceManager) GarbageCollection(inUseResSet map[string]types.ResourceItem, expireResSet map[string]types.ResourceItem) error {
for expireRes, expireItem := range expireResSet {
if expireItem.ExtraEipInfo == nil {
continue
}
logrus.Infof("release eip: %v, %v", expireRes, expireItem)
if expireItem.ExtraEipInfo.Delete {
err := e.ecs.ReleaseEipAddress(context.Background(), expireRes, expireItem.ExtraEipInfo.AssociateENI, expireItem.ExtraEipInfo.AssociateENIIP)
if err != nil {
return err
}
} else {
err := e.ecs.UnassociateEipAddress(context.Background(), expireRes, expireItem.ExtraEipInfo.AssociateENI, expireItem.ExtraEipInfo.AssociateENIIP.String())
if err != nil {
return err
}
}
}
return nil
}
func (e *eipResourceManager) Stat(context *networkContext, resID string) (types.NetworkResource, error) {
return nil, nil
}
func (e *eipResourceManager) GetResourceMapping() (tracing.ResourcePoolStats, error) {
return nil, errors.New("eip resource manager store network resource")
}