Repository: spidernet-io/spiderpool
Pull request #1181 (2022-12-14 05:57:10)

test: Add unit tests for pkg workloadendpoint
Signed-off-by: iiiceoo <ziqian.xue@daocloud.io>


codecov[bot]: # [Codecov](https://codecov.io/gh/spidernet-io/spiderpool/pull/1181?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=spidernet-io) Report
> Merging [#1181](https://codecov.io/gh/spidernet-io/spiderpool/pull/1181?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=spidernet-io) (fd879b3) into [main](https://codecov.io/gh/spidernet-io/spiderpool/commit/053cf609ee6cf106750c9583da21acfe364d26e5?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=spidernet-io) (053cf60) will **not change** coverage.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/spidernet-io/spiderpool/pull/1181/graphs/tree.svg?width=650&height=150&src=pr&token=YKXY2E4Q8G&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=spidernet-io)](https://codecov.io/gh/spidernet-io/spiderpool/pull/1181?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=spidernet-io)

```diff
@@           Coverage Diff           @@
##             main    #1181   +/-   ##
=======================================
  Coverage   88.21%   88.21%           
=======================================
  Files          25       25           
  Lines        1510     1510           
=======================================
  Hits         1332     1332           
  Misses        154      154           
  Partials       24       24           
```

| Flag | Coverage Δ | |
|---|---|---|
| unittests | `88.21% <100.00%> (ø)` | |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=spidernet-io#carryforward-flags-in-the-pull-request-comment) to find out more.

| [Impacted Files](https://codecov.io/gh/spidernet-io/spiderpool/pull/1181?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=spidernet-io) | Coverage Δ | |
|---|---|---|
| [pkg/reservedipmanager/reservedip\_mutate.go](https://codecov.io/gh/spidernet-io/spiderpool/pull/1181/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=spidernet-io#diff-cGtnL3Jlc2VydmVkaXBtYW5hZ2VyL3Jlc2VydmVkaXBfbXV0YXRlLmdv) | `100.00% <100.00%> (ø)` | |

sonarcloud[bot]: SonarCloud Quality Gate failed.&nbsp; &nbsp; [![Quality Gate failed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/failed-16px.png 'Quality Gate failed')](https://sonarcloud.io/dashboard?id=spidernet-io_spiderpool&pullRequest=1181)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=CODE_SMELL) [7 Code Smells](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=spidernet-io_spiderpool&pullRequest=1181) No Coverage information  
[![4.6%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/5-16px.png '4.6%')](https://sonarcloud.io/component_measures?id=spidernet-io_spiderpool&pullRequest=1181&metric=new_duplicated_lines_density&view=list) [4.6% Duplication](https://sonarcloud.io/component_measures?id=spidernet-io_spiderpool&pullRequest=1181&metric=new_duplicated_lines_density&view=list)


sonarcloud[bot]: SonarCloud Quality Gate failed.&nbsp; &nbsp; [![Quality Gate failed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/failed-16px.png 'Quality Gate failed')](https://sonarcloud.io/dashboard?id=spidernet-io_spiderpool&pullRequest=1181)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=SECURITY_HOTSPOT) [![E](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/E-16px.png 'E')](https://sonarcloud.io/project/security_hotspots?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=SECURITY_HOTSPOT) [16 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=CODE_SMELL) [8 Code Smells](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=spidernet-io_spiderpool&pullRequest=1181) No Coverage information  
[![4.7%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/5-16px.png '4.7%')](https://sonarcloud.io/component_measures?id=spidernet-io_spiderpool&pullRequest=1181&metric=new_duplicated_lines_density&view=list) [4.7% Duplication](https://sonarcloud.io/component_measures?id=spidernet-io_spiderpool&pullRequest=1181&metric=new_duplicated_lines_density&view=list)


sonarcloud[bot]: SonarCloud Quality Gate failed.&nbsp; &nbsp; [![Quality Gate failed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/failed-16px.png 'Quality Gate failed')](https://sonarcloud.io/dashboard?id=spidernet-io_spiderpool&pullRequest=1181)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=SECURITY_HOTSPOT) [![E](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/E-16px.png 'E')](https://sonarcloud.io/project/security_hotspots?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=SECURITY_HOTSPOT) [16 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=CODE_SMELL) [8 Code Smells](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=spidernet-io_spiderpool&pullRequest=1181) No Coverage information  
[![4.7%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/5-16px.png '4.7%')](https://sonarcloud.io/component_measures?id=spidernet-io_spiderpool&pullRequest=1181&metric=new_duplicated_lines_density&view=list) [4.7% Duplication](https://sonarcloud.io/component_measures?id=spidernet-io_spiderpool&pullRequest=1181&metric=new_duplicated_lines_density&view=list)


sonarcloud[bot]: SonarCloud Quality Gate failed.&nbsp; &nbsp; [![Quality Gate failed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/failed-16px.png 'Quality Gate failed')](https://sonarcloud.io/dashboard?id=spidernet-io_spiderpool&pullRequest=1181)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=SECURITY_HOTSPOT) [![E](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/E-16px.png 'E')](https://sonarcloud.io/project/security_hotspots?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=SECURITY_HOTSPOT) [16 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=CODE_SMELL) [8 Code Smells](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=spidernet-io_spiderpool&pullRequest=1181) No Coverage information  
[![4.7%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/5-16px.png '4.7%')](https://sonarcloud.io/component_measures?id=spidernet-io_spiderpool&pullRequest=1181&metric=new_duplicated_lines_density&view=list) [4.7% Duplication](https://sonarcloud.io/component_measures?id=spidernet-io_spiderpool&pullRequest=1181&metric=new_duplicated_lines_density&view=list)


sonarcloud[bot]: SonarCloud Quality Gate failed.&nbsp; &nbsp; [![Quality Gate failed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/failed-16px.png 'Quality Gate failed')](https://sonarcloud.io/dashboard?id=spidernet-io_spiderpool&pullRequest=1181)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=SECURITY_HOTSPOT) [![E](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/E-16px.png 'E')](https://sonarcloud.io/project/security_hotspots?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=SECURITY_HOTSPOT) [16 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=CODE_SMELL) [8 Code Smells](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1181&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=spidernet-io_spiderpool&pullRequest=1181) No Coverage information  
[![4.7%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/5-16px.png '4.7%')](https://sonarcloud.io/component_measures?id=spidernet-io_spiderpool&pullRequest=1181&metric=new_duplicated_lines_density&view=list) [4.7% Duplication](https://sonarcloud.io/component_measures?id=spidernet-io_spiderpool&pullRequest=1181&metric=new_duplicated_lines_density&view=list)



Patch:
diff --git a/cmd/spiderpool-agent/cmd/config.go b/cmd/spiderpool-agent/cmd/config.go
index f7e74281e..f407aa29e 100644
--- a/cmd/spiderpool-agent/cmd/config.go
+++ b/cmd/spiderpool-agent/cmd/config.go
@@ -115,16 +115,16 @@ type AgentContext struct {
 	InnerCancel context.CancelFunc
 
 	// manager
-	IPAM          ipam.IPAM
-	CRDManager    ctrl.Manager
-	IPPoolManager ippoolmanagertypes.IPPoolManager
-	WEManager     workloadendpointmanager.WorkloadEndpointManager
-	RIPManager    reservedipmanager.ReservedIPManager
-	NodeManager   nodemanager.NodeManager
-	NSManager     namespacemanager.NamespaceManager
-	PodManager    podmanager.PodManager
-	StsManager    statefulsetmanager.StatefulSetManager
-	SubnetManager subnetmanagertypes.SubnetManager
+	IPAM            ipam.IPAM
+	CRDManager      ctrl.Manager
+	IPPoolManager   ippoolmanagertypes.IPPoolManager
+	EndpointManager workloadendpointmanager.WorkloadEndpointManager
+	RIPManager      reservedipmanager.ReservedIPManager
+	NodeManager     nodemanager.NodeManager
+	NSManager       namespacemanager.NamespaceManager
+	PodManager      podmanager.PodManager
+	StsManager      statefulsetmanager.StatefulSetManager
+	SubnetManager   subnetmanagertypes.SubnetManager
 
 	// handler
 	HttpServer        *server.Server
diff --git a/cmd/spiderpool-agent/cmd/daemon.go b/cmd/spiderpool-agent/cmd/daemon.go
index 0b89aee65..44c896b15 100644
--- a/cmd/spiderpool-agent/cmd/daemon.go
+++ b/cmd/spiderpool-agent/cmd/daemon.go
@@ -143,7 +143,7 @@ func DaemonMain() {
 		},
 		WaitSubnetPoolRetries: agentContext.Cfg.UpdateCRMaxRetries,
 		WaitSubnetPoolTime:    time.Duration(agentContext.Cfg.WaitSubnetPoolTime) * time.Second,
-	}, agentContext.IPPoolManager, agentContext.WEManager, agentContext.NodeManager, agentContext.NSManager, agentContext.PodManager, agentContext.StsManager, agentContext.SubnetManager)
+	}, agentContext.IPPoolManager, agentContext.EndpointManager, agentContext.NodeManager, agentContext.NSManager, agentContext.PodManager, agentContext.StsManager, agentContext.SubnetManager)
 	agentContext.IPAM = ipam
 
 	go func() {
@@ -276,31 +276,39 @@ func initAgentServiceManagers(ctx context.Context) {
 	agentContext.NSManager = nsManager
 
 	logger.Debug("Begin to initialize Pod manager")
-	podManager, err := podmanager.NewPodManager(podmanager.PodManagerConfig{
-		MaxConflictRetries:    agentContext.Cfg.UpdateCRMaxRetries,
-		ConflictRetryUnitTime: time.Duration(agentContext.Cfg.UpdateCRRetryUnitTime) * time.Millisecond,
-	}, agentContext.CRDManager.GetClient())
+	podManager, err := podmanager.NewPodManager(
+		podmanager.PodManagerConfig{
+			MaxConflictRetries:    agentContext.Cfg.UpdateCRMaxRetries,
+			ConflictRetryUnitTime: time.Duration(agentContext.Cfg.UpdateCRRetryUnitTime) * time.Millisecond,
+		},
+		agentContext.CRDManager.GetClient(),
+	)
 	if err != nil {
 		logger.Fatal(err.Error())
 	}
 	agentContext.PodManager = podManager
 
-	logger.Debug("Begin to initialize StatefulSet Manager")
+	logger.Debug("Begin to initialize StatefulSet manager")
 	statefulSetManager, err := statefulsetmanager.NewStatefulSetManager(agentContext.CRDManager.GetClient())
 	if err != nil {
 		logger.Fatal(err.Error())
 	}
 	agentContext.StsManager = statefulSetManager
 
-	logger.Debug("Begin to initialize WorkloadEndpoint Manager")
-	weManager, err := workloadendpointmanager.NewWorkloadEndpointManager(&workloadendpointmanager.EndpointManagerConfig{
-		UpdateCRConfig:    updateCRConfig,
-		MaxHistoryRecords: agentContext.Cfg.WorkloadEndpointMaxHistoryRecords,
-	}, agentContext.CRDManager, agentContext.PodManager)
+	logger.Debug("Begin to initialize Endpoint manager")
+	endpointManager, err := workloadendpointmanager.NewWorkloadEndpointManager(
+		workloadendpointmanager.EndpointManagerConfig{
+			MaxConflictRetries:    agentContext.Cfg.UpdateCRMaxRetries,
+			ConflictRetryUnitTime: time.Duration(agentContext.Cfg.UpdateCRRetryUnitTime) * time.Millisecond,
+			MaxHistoryRecords:     &agentContext.Cfg.WorkloadEndpointMaxHistoryRecords,
+		},
+		agentContext.CRDManager.GetClient(),
+		agentContext.PodManager,
+	)
 	if err != nil {
 		logger.Fatal(err.Error())
 	}
-	agentContext.WEManager = weManager
+	agentContext.EndpointManager = endpointManager
 
 	logger.Debug("Begin to initialize ReservedIP manager")
 	rIPManager, err := reservedipmanager.NewReservedIPManager(agentContext.CRDManager.GetClient())
diff --git a/cmd/spiderpool-controller/cmd/config.go b/cmd/spiderpool-controller/cmd/config.go
index 6d28a1d98..df42179e9 100644
--- a/cmd/spiderpool-controller/cmd/config.go
+++ b/cmd/spiderpool-controller/cmd/config.go
@@ -153,17 +153,17 @@ type ControllerContext struct {
 	ClientSet *kubernetes.Clientset
 
 	// manager
-	CRDManager    ctrl.Manager
-	SubnetManager subnetmanagertypes.SubnetManager
-	IPPoolManager ippoolmanagertypes.IPPoolManager
-	WEPManager    workloadendpointmanager.WorkloadEndpointManager
-	RIPManager    reservedipmanager.ReservedIPManager
-	NodeManager   nodemanager.NodeManager
-	NSManager     namespacemanager.NamespaceManager
-	PodManager    podmanager.PodManager
-	GCManager     gcmanager.GCManager
-	StsManager    statefulsetmanager.StatefulSetManager
-	Leader        election.SpiderLeaseElector
+	CRDManager      ctrl.Manager
+	SubnetManager   subnetmanagertypes.SubnetManager
+	IPPoolManager   ippoolmanagertypes.IPPoolManager
+	EndpointManager workloadendpointmanager.WorkloadEndpointManager
+	RIPManager      reservedipmanager.ReservedIPManager
+	NodeManager     nodemanager.NodeManager
+	NSManager       namespacemanager.NamespaceManager
+	PodManager      podmanager.PodManager
+	GCManager       gcmanager.GCManager
+	StsManager      statefulsetmanager.StatefulSetManager
+	Leader          election.SpiderLeaseElector
 
 	// handler
 	HttpServer        *server.Server
diff --git a/cmd/spiderpool-controller/cmd/daemon.go b/cmd/spiderpool-controller/cmd/daemon.go
index 3f9583f48..a48ebbbd2 100644
--- a/cmd/spiderpool-controller/cmd/daemon.go
+++ b/cmd/spiderpool-controller/cmd/daemon.go
@@ -233,35 +233,42 @@ func initControllerServiceManagers(ctx context.Context) {
 	controllerContext.NSManager = nsManager
 
 	logger.Debug("Begin to initialize Pod manager")
-	podManager, err := podmanager.NewPodManager(podmanager.PodManagerConfig{
-		MaxConflictRetries:    controllerContext.Cfg.UpdateCRMaxRetries,
-		ConflictRetryUnitTime: time.Duration(controllerContext.Cfg.UpdateCRRetryUnitTime) * time.Millisecond,
-	}, controllerContext.CRDManager.GetClient())
+	podManager, err := podmanager.NewPodManager(
+		podmanager.PodManagerConfig{
+			MaxConflictRetries:    controllerContext.Cfg.UpdateCRMaxRetries,
+			ConflictRetryUnitTime: time.Duration(controllerContext.Cfg.UpdateCRRetryUnitTime) * time.Millisecond,
+		},
+		controllerContext.CRDManager.GetClient(),
+	)
 	if err != nil {
 		logger.Fatal(err.Error())
 	}
 	controllerContext.PodManager = podManager
 
-	logger.Info("Begin to initialize StatefulSet Manager")
+	logger.Info("Begin to initialize StatefulSet manager")
 	statefulSetManager, err := statefulsetmanager.NewStatefulSetManager(controllerContext.CRDManager.GetClient())
 	if err != nil {
 		logger.Fatal(err.Error())
 	}
 	controllerContext.StsManager = statefulSetManager
 
-	logger.Info("Begin to initialize WorkloadEndpoint Manager")
-	wepManager, err := workloadendpointmanager.NewWorkloadEndpointManager(&workloadendpointmanager.EndpointManagerConfig{
-		UpdateCRConfig:    updateCRConfig,
-		MaxHistoryRecords: controllerContext.Cfg.WorkloadEndpointMaxHistoryRecords,
-	}, controllerContext.CRDManager, controllerContext.PodManager)
+	logger.Debug("Begin to initialize Endpoint manager")
+	endpointManager, err := workloadendpointmanager.NewWorkloadEndpointManager(
+		workloadendpointmanager.EndpointManagerConfig{
+			MaxConflictRetries:    controllerContext.Cfg.UpdateCRMaxRetries,
+			ConflictRetryUnitTime: time.Duration(controllerContext.Cfg.UpdateCRRetryUnitTime) * time.Millisecond,
+			MaxHistoryRecords:     &controllerContext.Cfg.WorkloadEndpointMaxHistoryRecords,
+		},
+		controllerContext.CRDManager.GetClient(),
+		controllerContext.PodManager,
+	)
 	if err != nil {
 		logger.Fatal(err.Error())
 	}
-	controllerContext.WEPManager = wepManager
+	controllerContext.EndpointManager = endpointManager
 
-	logger.Info("Begin to set up Endpoint webhook")
-	err = controllerContext.WEPManager.SetupWebhook()
-	if err != nil {
+	logger.Debug("Begin to set up Endpoint webhook")
+	if err := (&workloadendpointmanager.WorkloadEndpointWebhook{}).SetupWebhookWithManager(controllerContext.CRDManager); err != nil {
 		logger.Fatal(err.Error())
 	}
 
@@ -274,7 +281,7 @@ func initControllerServiceManagers(ctx context.Context) {
 
 	logger.Debug("Begin to set up ReservedIP webhook")
 	if err := (&reservedipmanager.ReservedIPWebhook{
-		ReservedIPManager: rIPManager,
+		ReservedIPManager: controllerContext.RIPManager,
 		EnableIPv4:        controllerContext.Cfg.EnableIPv4,
 		EnableIPv6:        controllerContext.Cfg.EnableIPv6,
 	}).SetupWebhookWithManager(controllerContext.CRDManager); err != nil {
@@ -347,7 +354,7 @@ func initGCManager(ctx context.Context) {
 	// EnableStatefulSet was determined by configmap
 	gcIPConfig.EnableStatefulSet = controllerContext.Cfg.EnableStatefulSet
 
-	gcManager, err := gcmanager.NewGCManager(ctx, controllerContext.ClientSet, gcIPConfig, controllerContext.WEPManager,
+	gcManager, err := gcmanager.NewGCManager(ctx, controllerContext.ClientSet, gcIPConfig, controllerContext.EndpointManager,
 		controllerContext.IPPoolManager, controllerContext.PodManager, controllerContext.StsManager, controllerContext.Leader)
 	if nil != err {
 		logger.Fatal(err.Error())
diff --git a/go.mod b/go.mod
index 44e2d766f..54abe2060 100644
--- a/go.mod
+++ b/go.mod
@@ -49,6 +49,7 @@ require (
 require (
 	github.com/agiledragon/gomonkey/v2 v2.9.0
 	github.com/golang/mock v1.6.0
+	github.com/moby/moby v20.10.21+incompatible
 	github.com/openkruise/kruise-api v1.3.0
 	go.uber.org/multierr v1.8.0
 )
diff --git a/go.sum b/go.sum
index 7eba032a3..cf6296244 100644
--- a/go.sum
+++ b/go.sum
@@ -439,6 +439,8 @@ github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR
 github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
 github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
 github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
+github.com/moby/moby v20.10.21+incompatible h1:LfdCNzNpDYtOTtlO5wxLcUEk0nyM3KqPyeIyXVdvl/U=
+github.com/moby/moby v20.10.21+incompatible/go.mod h1:fDXVQ6+S340veQPv35CzDahGBmHsiclFwfEygB/TWMc=
 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
diff --git a/pkg/gcmanager/scanAll_IPPool.go b/pkg/gcmanager/scanAll_IPPool.go
index 79639c782..a3183b8d1 100644
--- a/pkg/gcmanager/scanAll_IPPool.go
+++ b/pkg/gcmanager/scanAll_IPPool.go
@@ -16,6 +16,7 @@ import (
 	"github.com/spidernet-io/spiderpool/pkg/logutils"
 	metrics "github.com/spidernet-io/spiderpool/pkg/metric"
 	"github.com/spidernet-io/spiderpool/pkg/types"
+	"github.com/spidernet-io/spiderpool/pkg/workloadendpointmanager"
 )
 
 // monitorGCSignal will monitor signal from CLI, DefaultGCInterval
@@ -151,15 +152,15 @@ func (s *SpiderGC) executeScanAll(ctx context.Context) {
 					}
 				}
 			} else {
-				// case: The pod in IPPool's ip-allocationDetail is also exist in k8s, but the IP corresponding allocation containerID is different with wep current containerID
-				isCurrentContainerID, err := s.wepMgr.CheckCurrentContainerID(ctx, podYaml.Namespace, podYaml.Name, poolIPAllocation.ContainerID)
-				if nil != err {
-					scanAllLogger.Sugar().Errorf("failed to check IP '%s' allocation '%+v' containerID whether is same with wep '%s/%s' current containerID or not, error: %v",
-						poolIP, poolIPAllocation, podYaml.Namespace, podYaml.Name, err)
+				endpoint, err := s.wepMgr.GetEndpointByName(ctx, podYaml.Namespace, podYaml.Name)
+				if err != nil {
+					scanAllLogger.Sugar().Errorf("failed to get Endpoint '%s/%s': %v", podYaml.Namespace, podYaml.Name, err)
 					continue
 				}
 
-				if !isCurrentContainerID {
+				// case: The pod in IPPool's ip-allocationDetail is also exist in k8s, but the IP corresponding allocation containerID is different with wep current containerID
+				allocation, _ := workloadendpointmanager.RetrieveIPAllocation(poolIPAllocation.ContainerID, poolIPAllocation.NIC, false, endpoint)
+				if allocation == nil {
 					wrappedLog := scanAllLogger.With(zap.String("gc-reason", "IPPoolAllocation containerID is different with wep current containerID"))
 					// release IP but no need to remove wep finalizer
 					err = s.ippoolMgr.ReleaseIP(ctx, pool.Name, []types.IPAndCID{{
diff --git a/pkg/gcmanager/tracePod_worker.go b/pkg/gcmanager/tracePod_worker.go
index 927581b13..d8787c507 100644
--- a/pkg/gcmanager/tracePod_worker.go
+++ b/pkg/gcmanager/tracePod_worker.go
@@ -104,7 +104,7 @@ func (s *SpiderGC) releaseIPPoolIPExecutor(ctx context.Context, workerIndex int)
 
 			// delete StatefulSet wep (other controller wep has OwnerReference, its lifecycle is same with pod)
 			if endpoint.Status.OwnerControllerType == constant.OwnerStatefulSet {
-				err = s.wepMgr.Delete(ctx, endpoint)
+				err = s.wepMgr.DeleteEndpoint(ctx, endpoint)
 				if nil != err {
 					loggerReleaseIP.Sugar().Errorf("failed to delete StatefulSet wep '%s/%s', error: '%v'",
 						podCache.Namespace, podCache.PodName, err)
diff --git a/pkg/ipam/ipam.go b/pkg/ipam/ipam.go
index 5a9b720b7..7199fb979 100644
--- a/pkg/ipam/ipam.go
+++ b/pkg/ipam/ipam.go
@@ -177,7 +177,7 @@ func (i *ipam) retrieveStsIPAllocation(ctx context.Context, containerID, nic str
 	}
 
 	// Refresh Endpoint current IP allocation.
-	if err := i.weManager.UpdateCurrentStatus(ctx, containerID, pod); err != nil {
+	if err := i.weManager.ReallocateCurrentIPAllocation(ctx, containerID, pod.Spec.NodeName, pod.Namespace, pod.Name); err != nil {
 		return nil, fmt.Errorf("failed to update the current IP allocation of StatefulSet: %w", err)
 	}
 
@@ -220,9 +220,15 @@ func (i *ipam) allocateInStandardMode(ctx context.Context, addArgs *models.IpamA
 	}
 
 	// TODO(iiiceoo): Comment why containerID should be written first.
-	endpoint, err = i.weManager.MarkIPAllocation(ctx, *addArgs.ContainerID, endpoint, pod)
-	if err != nil {
-		return nil, fmt.Errorf("failed to mark IP allocation: %v", err)
+	if endpoint == nil {
+		endpoint, err = i.weManager.MarkIPAllocation(ctx, *addArgs.ContainerID, pod)
+		if err != nil {
+			return nil, fmt.Errorf("failed to mark IP allocation: %v", err)
+		}
+	} else {
+		if err := i.weManager.ReMarkIPAllocation(ctx, *addArgs.ContainerID, pod, endpoint); err != nil {
+			return nil, fmt.Errorf("failed to remark IP allocation: %v", err)
+		}
 	}
 
 	results, err := i.allocateForAllNICs(ctx, toBeAllocatedSet, *addArgs.ContainerID, endpoint, pod)
@@ -335,7 +341,7 @@ func (i *ipam) allocateForOneNIC(ctx context.Context, t *ToBeAllocated, containe
 			ContainerID: containerID,
 			IPs:         patch,
 		}, endpoint); err != nil {
-			return results, fmt.Errorf("failed to update IP allocation detail %+v of Endpoint %s/%s: %v", patch, endpoint.Namespace, endpoint.Name, err)
+			return results, fmt.Errorf("failed to patch IP allocation detail %+v to Endpoint %s/%s: %v", patch, endpoint.Namespace, endpoint.Name, err)
 		}
 	}
 
diff --git a/pkg/podmanager/mock/pod_manager_mock.go b/pkg/podmanager/mock/pod_manager_mock.go
new file mode 100644
index 000000000..5df9a809f
--- /dev/null
+++ b/pkg/podmanager/mock/pod_manager_mock.go
@@ -0,0 +1,121 @@
+// Copyright 2022 Authors of spidernet-io
+// SPDX-License-Identifier: Apache-2.0
+
+// Code generated by MockGen. DO NOT EDIT.
+// Source: ./pkg/podmanager/pod_manager.go
+
+// Package mock_podmanager is a generated GoMock package.
+package mock_podmanager
+
+import (
+	context "context"
+	reflect "reflect"
+
+	gomock "github.com/golang/mock/gomock"
+	v1 "k8s.io/api/core/v1"
+	v10 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	client "sigs.k8s.io/controller-runtime/pkg/client"
+)
+
+// MockPodManager is a mock of PodManager interface.
+type MockPodManager struct {
+	ctrl     *gomock.Controller
+	recorder *MockPodManagerMockRecorder
+}
+
+// MockPodManagerMockRecorder is the mock recorder for MockPodManager.
+type MockPodManagerMockRecorder struct {
+	mock *MockPodManager
+}
+
+// NewMockPodManager creates a new mock instance.
+func NewMockPodManager(ctrl *gomock.Controller) *MockPodManager {
+	mock := &MockPodManager{ctrl: ctrl}
+	mock.recorder = &MockPodManagerMockRecorder{mock}
+	return mock
+}
+
+// EXPECT returns an object that allows the caller to indicate expected use.
+func (m *MockPodManager) EXPECT() *MockPodManagerMockRecorder {
+	return m.recorder
+}
+
+// GetPodByName mocks base method.
+func (m *MockPodManager) GetPodByName(ctx context.Context, namespace, podName string) (*v1.Pod, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetPodByName", ctx, namespace, podName)
+	ret0, _ := ret[0].(*v1.Pod)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetPodByName indicates an expected call of GetPodByName.
+func (mr *MockPodManagerMockRecorder) GetPodByName(ctx, namespace, podName interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPodByName", reflect.TypeOf((*MockPodManager)(nil).GetPodByName), ctx, namespace, podName)
+}
+
+// GetPodTopController mocks base method.
+func (m *MockPodManager) GetPodTopController(ctx context.Context, pod *v1.Pod) (string, v10.Object, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetPodTopController", ctx, pod)
+	ret0, _ := ret[0].(string)
+	ret1, _ := ret[1].(v10.Object)
+	ret2, _ := ret[2].(error)
+	return ret0, ret1, ret2
+}
+
+// GetPodTopController indicates an expected call of GetPodTopController.
+func (mr *MockPodManagerMockRecorder) GetPodTopController(ctx, pod interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPodTopController", reflect.TypeOf((*MockPodManager)(nil).GetPodTopController), ctx, pod)
+}
+
+// ListPods mocks base method.
+func (m *MockPodManager) ListPods(ctx context.Context, opts ...client.ListOption) (*v1.PodList, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ListPods", varargs...)
+	ret0, _ := ret[0].(*v1.PodList)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListPods indicates an expected call of ListPods.
+func (mr *MockPodManagerMockRecorder) ListPods(ctx interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListPods", reflect.TypeOf((*MockPodManager)(nil).ListPods), varargs...)
+}
+
+// MatchLabelSelector mocks base method.
+func (m *MockPodManager) MatchLabelSelector(ctx context.Context, namespace, podName string, labelSelector *v10.LabelSelector) (bool, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "MatchLabelSelector", ctx, namespace, podName, labelSelector)
+	ret0, _ := ret[0].(bool)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// MatchLabelSelector indicates an expected call of MatchLabelSelector.
+func (mr *MockPodManagerMockRecorder) MatchLabelSelector(ctx, namespace, podName, labelSelector interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MatchLabelSelector", reflect.TypeOf((*MockPodManager)(nil).MatchLabelSelector), ctx, namespace, podName, labelSelector)
+}
+
+// MergeAnnotations mocks base method.
+func (m *MockPodManager) MergeAnnotations(ctx context.Context, namespace, podName string, annotations map[string]string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "MergeAnnotations", ctx, namespace, podName, annotations)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// MergeAnnotations indicates an expected call of MergeAnnotations.
+func (mr *MockPodManagerMockRecorder) MergeAnnotations(ctx, namespace, podName, annotations interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MergeAnnotations", reflect.TypeOf((*MockPodManager)(nil).MergeAnnotations), ctx, namespace, podName, annotations)
+}
diff --git a/pkg/reservedipmanager/reservedip_mutate.go b/pkg/reservedipmanager/reservedip_mutate.go
index b24781b4c..363010575 100644
--- a/pkg/reservedipmanager/reservedip_mutate.go
+++ b/pkg/reservedipmanager/reservedip_mutate.go
@@ -20,7 +20,7 @@ func (rw *ReservedIPWebhook) mutateReservedIP(ctx context.Context, rIP *spiderpo
 	logger.Info("Start to mutate ReservedIP")
 
 	if rIP.DeletionTimestamp != nil {
-		logger.Info("Deleting ReservedIP, noting to mutate")
+		logger.Info("Terminating ReservedIP, noting to mutate")
 		return nil
 	}
 
diff --git a/pkg/workloadendpointmanager/config.go b/pkg/workloadendpointmanager/config.go
index 963ada5e9..2bf95a293 100644
--- a/pkg/workloadendpointmanager/config.go
+++ b/pkg/workloadendpointmanager/config.go
@@ -3,9 +3,35 @@
 
 package workloadendpointmanager
 
-import "github.com/spidernet-io/spiderpool/pkg/config"
+import (
+	"time"
+
+	corev1 "k8s.io/api/core/v1"
+	"k8s.io/apimachinery/pkg/runtime"
+	utilruntime "k8s.io/apimachinery/pkg/util/runtime"
+)
+
+const (
+	defaultMaxHistoryRecords = 100
+)
 
 type EndpointManagerConfig struct {
-	config.UpdateCRConfig
-	MaxHistoryRecords int
+	MaxConflictRetries    int
+	ConflictRetryUnitTime time.Duration
+	scheme                *runtime.Scheme
+	MaxHistoryRecords     *int
+}
+
+func setDefaultsForPodManagerConfig(config EndpointManagerConfig) EndpointManagerConfig {
+	if config.scheme == nil {
+		config.scheme = runtime.NewScheme()
+		utilruntime.Must(corev1.AddToScheme(config.scheme))
+	}
+
+	if config.MaxHistoryRecords == nil {
+		maxHistoryRecords := defaultMaxHistoryRecords
+		config.MaxHistoryRecords = &maxHistoryRecords
+	}
+
+	return config
 }
diff --git a/pkg/workloadendpointmanager/utils.go b/pkg/workloadendpointmanager/utils.go
index a4109fb8c..eff8c6205 100644
--- a/pkg/workloadendpointmanager/utils.go
+++ b/pkg/workloadendpointmanager/utils.go
@@ -11,71 +11,41 @@ import (
 	"github.com/spidernet-io/spiderpool/pkg/types"
 )
 
-func RetrieveIPAllocation(containerID, nic string, includeHistory bool, we *spiderpoolv1.SpiderEndpoint) (*spiderpoolv1.PodIPAllocation, bool) {
-	if we == nil || we.Status.Current == nil {
+func RetrieveIPAllocation(containerID, nic string, includeHistory bool, endpoint *spiderpoolv1.SpiderEndpoint) (allocation *spiderpoolv1.PodIPAllocation, currently bool) {
+	if endpoint == nil {
 		return nil, false
 	}
-	if we.Status.Current.ContainerID != containerID {
+	if endpoint.Status.Current == nil {
 		return nil, false
 	}
-	for _, d := range we.Status.Current.IPs {
-		if d.NIC == nic {
-			return we.Status.Current, true
-		}
-	}
 
-	if !includeHistory {
-		return nil, false
-	}
-	if len(we.Status.History) == 0 {
-		return nil, false
-	}
-	for _, a := range we.Status.History[1:] {
-		if a.ContainerID != containerID {
-			continue
-		}
-		for _, d := range a.IPs {
+	if endpoint.Status.Current.ContainerID == containerID {
+		for _, d := range endpoint.Status.Current.IPs {
 			if d.NIC == nic {
-				return &a, false
+				return endpoint.Status.Current, true
 			}
 		}
-		break
-	}
-
-	return nil, false
-}
-
-// TODO(iiiceoo): refactor
-func mergeIPDetails(target, delta *spiderpoolv1.IPAllocationDetail) {
-	if target.IPv4 == nil {
-		target.IPv4 = delta.IPv4
-	}
-
-	if target.IPv4Pool == nil {
-		target.IPv4Pool = delta.IPv4Pool
 	}
 
-	if target.IPv4Gateway == nil {
-		target.IPv4Gateway = delta.IPv4Gateway
-	}
-
-	if target.IPv6 == nil {
-		target.IPv6 = delta.IPv6
-	}
-
-	if target.IPv6Pool == nil {
-		target.IPv6Pool = delta.IPv6Pool
+	if !includeHistory || len(endpoint.Status.History) <= 1 {
+		return nil, false
 	}
 
-	if target.IPv6Gateway == nil {
-		target.IPv6Gateway = delta.IPv6Gateway
+	for _, a := range endpoint.Status.History[1:] {
+		if a.ContainerID == containerID {
+			for _, d := range a.IPs {
+				if d.NIC == nic {
+					return &a, false
+				}
+			}
+		}
 	}
 
-	target.Routes = append(target.Routes, delta.Routes...)
+	return nil, false
 }
 
 // ListAllHistoricalIPs collect wep history IPs and classify them with each pool name.
-func ListAllHistoricalIPs(se *spiderpoolv1.SpiderEndpoint) map[string][]types.IPAndCID {
+func ListAllHistoricalIPs(endpoint *spiderpoolv1.SpiderEndpoint) map[string][]types.IPAndCID {
 	// key: IPPool name
 	// value: usedIP and container ID
 	wepHistoryIPs := make(map[string][]types.IPAndCID)
@@ -84,7 +54,7 @@ func ListAllHistoricalIPs(se *spiderpoolv1.SpiderEndpoint) map[string][]types.IP
 		if poolName != nil {
 			if ipAndCIDR == nil {
 				logutils.Logger.Sugar().Errorf("SpiderEndpoint data broken, pod '%s/%s' containerID '%s' used ippool '%s' with no ip",
-					se.Namespace, se.Name, containerID, *poolName)
+					endpoint.Namespace, endpoint.Name, containerID, *poolName)
 
 				return
 			}
@@ -102,7 +72,7 @@ func ListAllHistoricalIPs(se *spiderpoolv1.SpiderEndpoint) map[string][]types.IP
 	}
 
 	// circle to traverse each allocation
-	for _, PodIPAllocation := range se.Status.History {
+	for _, PodIPAllocation := range endpoint.Status.History {
 		// circle to traverse each NIC
 		for _, ipAllocationDetail := range PodIPAllocation.IPs {
 			// collect IPv4
diff --git a/pkg/workloadendpointmanager/workloadendpoint_manager.go b/pkg/workloadendpointmanager/workloadendpoint_manager.go
index a1a10bb03..a8d8d4936 100644
--- a/pkg/workloadendpointmanager/workloadendpoint_manager.go
+++ b/pkg/workloadendpointmanager/workloadendpoint_manager.go
@@ -8,14 +8,12 @@ import (
 	"errors"
 	"fmt"
 	"math/rand"
-	"strings"
 	"time"
 
 	corev1 "k8s.io/api/core/v1"
 	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	apitypes "k8s.io/apimachinery/pkg/types"
-	ctrl "sigs.k8s.io/controller-runtime"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
 
@@ -26,209 +24,285 @@ import (
 )
 
 type WorkloadEndpointManager interface {
-	SetupWebhook() error
 	GetEndpointByName(ctx context.Context, namespace, podName string) (*spiderpoolv1.SpiderEndpoint, error)
 	ListEndpoints(ctx context.Context, opts ...client.ListOption) (*spiderpoolv1.SpiderEndpointList, error)
-	Delete(ctx context.Context, wep *spiderpoolv1.SpiderEndpoint) error
-	MarkIPAllocation(ctx context.Context, containerID string, we *spiderpoolv1.SpiderEndpoint, pod *corev1.Pod) (*spiderpoolv1.SpiderEndpoint, error)
-	PatchIPAllocation(ctx context.Context, allocation *spiderpoolv1.PodIPAllocation, we *spiderpoolv1.SpiderEndpoint) error
-	ClearCurrentIPAllocation(ctx context.Context, containerID string, we *spiderpoolv1.SpiderEndpoint) error
+	DeleteEndpoint(ctx context.Context, endpoint *spiderpoolv1.SpiderEndpoint) error
 	RemoveFinalizer(ctx context.Context, namespace, podName string) error
-	IsIPBelongWEPCurrent(ctx context.Context, namespace, podName, poolIP string) (bool, error)
-	CheckCurrentContainerID(ctx context.Context, namespace, podName, containerID string) (bool, error)
-	UpdateCurrentStatus(ctx context.Context, containerID string, pod *corev1.Pod) error
+	MarkIPAllocation(ctx context.Context, containerID string, pod *corev1.Pod) (*spiderpoolv1.SpiderEndpoint, error)
+	ReMarkIPAllocation(ctx context.Context, containerID string, pod *corev1.Pod, endpoint *spiderpoolv1.SpiderEndpoint) error
+	PatchIPAllocation(ctx context.Context, allocation *spiderpoolv1.PodIPAllocation, endpoint *spiderpoolv1.SpiderEndpoint) error
+	ClearCurrentIPAllocation(ctx context.Context, containerID string, endpoint *spiderpoolv1.SpiderEndpoint) error
+	ReallocateCurrentIPAllocation(ctx context.Context, containerID, nodeName, namespace, podName string) error
 }
 
 type workloadEndpointManager struct {
-	config     *EndpointManagerConfig
+	config     EndpointManagerConfig
 	client     client.Client
-	runtimeMgr ctrl.Manager
 	podManager podmanager.PodManager
 }
 
-func NewWorkloadEndpointManager(c *EndpointManagerConfig, mgr ctrl.Manager, podManager podmanager.PodManager) (WorkloadEndpointManager, error) {
-	if c == nil {
-		return nil, errors.New("endpoint manager config must be specified")
-	}
-	if mgr == nil {
-		return nil, errors.New("k8s manager must be specified")
+func NewWorkloadEndpointManager(config EndpointManagerConfig, client client.Client, podManager podmanager.PodManager) (WorkloadEndpointManager, error) {
+	if client == nil {
+		return nil, fmt.Errorf("k8s client %w", constant.ErrMissingRequiredParam)
 	}
 	if podManager == nil {
-		return nil, errors.New("pod manager must be specified")
+		return nil, fmt.Errorf("pod manager %w", constant.ErrMissingRequiredParam)
 	}
 
 	return &workloadEndpointManager{
-		config:     c,
-		client:     mgr.GetClient(),
-		runtimeMgr: mgr,
+		config:     setDefaultsForPodManagerConfig(config),
+		client:     client,
 		podManager: podManager,
 	}, nil
 }
 
 func (em *workloadEndpointManager) GetEndpointByName(ctx context.Context, namespace, podName string) (*spiderpoolv1.SpiderEndpoint, error) {
-	var we spiderpoolv1.SpiderEndpoint
-	if err := em.client.Get(ctx, apitypes.NamespacedName{Namespace: namespace, Name: podName}, &we); nil != err {
+	var endpoint spiderpoolv1.SpiderEndpoint
+	if err := em.client.Get(ctx, apitypes.NamespacedName{Namespace: namespace, Name: podName}, &endpoint); nil != err {
 		return nil, err
 	}
 
-	return &we, nil
+	return &endpoint, nil
 }
 
 func (em *workloadEndpointManager) ListEndpoints(ctx context.Context, opts ...client.ListOption) (*spiderpoolv1.SpiderEndpointList, error) {
-	var weList spiderpoolv1.SpiderEndpointList
-	if err := em.client.List(ctx, &weList, opts...); err != nil {
+	var endpointList spiderpoolv1.SpiderEndpointList
+	if err := em.client.List(ctx, &endpointList, opts...); err != nil {
 		return nil, err
 	}
 
-	return &weList, nil
+	return &endpointList, nil
 }
 
-func (em *workloadEndpointManager) MarkIPAllocation(ctx context.Context, containerID string, we *spiderpoolv1.SpiderEndpoint, pod *corev1.Pod) (*spiderpoolv1.SpiderEndpoint, error) {
-	logger := logutils.FromContext(ctx)
-
-	allocation := &spiderpoolv1.PodIPAllocation{
-		ContainerID:  containerID,
-		Node:         &pod.Spec.NodeName,
-		CreationTime: &metav1.Time{Time: time.Now()},
+func (em *workloadEndpointManager) DeleteEndpoint(ctx context.Context, endpoint *spiderpoolv1.SpiderEndpoint) error {
+	if err := em.client.Delete(ctx, endpoint); err != nil {
+		return client.IgnoreNotFound(err)
 	}
 
-	if we == nil {
-		newWE := &spiderpoolv1.SpiderEndpoint{
-			ObjectMeta: metav1.ObjectMeta{
-				Name:      pod.Name,
-				Namespace: pod.Namespace,
-			},
-		}
+	return nil
+}
 
-		ownerKind, owner, err := em.podManager.GetPodTopController(ctx, pod)
+func (em *workloadEndpointManager) RemoveFinalizer(ctx context.Context, namespace, podName string) error {
+	for i := 0; i <= em.config.MaxConflictRetries; i++ {
+		endpoint, err := em.GetEndpointByName(ctx, namespace, podName)
 		if err != nil {
-			return nil, err
+			return client.IgnoreNotFound(err)
 		}
 
-		// We don't set ownerReference for Endpoint when the pod belongs to StatefulSet
-		// Once the StatefulSet pod restarts, we can retrieve the corresponding data immediately.
-		// And we don't need to wait the corresponding Endpoint clean up to create a new one if ownerReference exists.
-		if ownerKind != constant.OwnerStatefulSet {
-			if err := controllerutil.SetOwnerReference(pod, newWE, em.runtimeMgr.GetScheme()); err != nil {
-				return nil, err
-			}
+		if !controllerutil.ContainsFinalizer(endpoint, constant.SpiderFinalizer) {
+			return nil
 		}
-		controllerutil.AddFinalizer(newWE, constant.SpiderFinalizer)
 
-		if err := em.client.Create(ctx, newWE); err != nil {
-			return nil, err
+		controllerutil.RemoveFinalizer(endpoint, constant.SpiderFinalizer)
+		if err := em.client.Update(ctx, endpoint); err != nil {
+			if !apierrors.IsConflict(err) {
+				return err
+			}
+			if i == em.config.MaxConflictRetries {
+				return fmt.Errorf("%w (%d times), failed to remove finalizer %s from Endpoint %s/%s", constant.ErrRetriesExhausted, em.config.MaxConflictRetries, constant.SpiderFinalizer, namespace, podName)
+			}
+			time.Sleep(time.Duration(rand.Intn(1<<(i+1))) * em.config.ConflictRetryUnitTime)
+			continue
 		}
+		break
+	}
 
-		newWE.Status.Current = allocation
-		newWE.Status.History = []spiderpoolv1.PodIPAllocation{*allocation}
-		newWE.Status.OwnerControllerType = ownerKind
-		if owner != nil {
-			newWE.Status.OwnerControllerName = owner.GetName()
-		}
-		if err := em.client.Status().Update(ctx, newWE); err != nil {
+	return nil
+}
+
+func (em *workloadEndpointManager) MarkIPAllocation(ctx context.Context, containerID string, pod *corev1.Pod) (*spiderpoolv1.SpiderEndpoint, error) {
+	if pod == nil {
+		return nil, fmt.Errorf("pod %w", constant.ErrMissingRequiredParam)
+	}
+
+	endpoint := &spiderpoolv1.SpiderEndpoint{
+		ObjectMeta: metav1.ObjectMeta{
+			Name:      pod.Name,
+			Namespace: pod.Namespace,
+		},
+	}
+
+	ownerKind, owner, err := em.podManager.GetPodTopController(ctx, pod)
+	if err != nil {
+		return nil, err
+	}
+
+	// Do not set ownerReference for Endpoint when its corresponding Pod is
+	// controlled by StatefulSet. Once the Pod of StatefulSet is recreated,
+	// we can immediately retrieve the old IP allocation results from the
+	// Endpoint without worrying about the cascading deletion of the Endpoint.
+	if ownerKind != constant.OwnerStatefulSet {
+		if err := controllerutil.SetOwnerReference(pod, endpoint, em.config.scheme); err != nil {
 			return nil, err
 		}
-		return newWE, nil
+	}
+	controllerutil.AddFinalizer(endpoint, constant.SpiderFinalizer)
+	if err := em.client.Create(ctx, endpoint); err != nil {
+		return nil, err
+	}
+
+	allocation := &spiderpoolv1.PodIPAllocation{
+		ContainerID:  containerID,
+		Node:         &pod.Spec.NodeName,
+		CreationTime: &metav1.Time{Time: time.Now()},
+	}
+
+	endpoint.Status.Current = allocation
+	endpoint.Status.History = []spiderpoolv1.PodIPAllocation{*allocation}
+	endpoint.Status.OwnerControllerType = ownerKind
+	if owner != nil {
+		endpoint.Status.OwnerControllerName = owner.GetName()
+	}
+	if err := em.client.Status().Update(ctx, endpoint); err != nil {
+		return nil, err
+	}
+
+	return endpoint, nil
+}
+
+func (em *workloadEndpointManager) ReMarkIPAllocation(ctx context.Context, containerID string, pod *corev1.Pod, endpoint *spiderpoolv1.SpiderEndpoint) error {
+	logger := logutils.FromContext(ctx)
+
+	if pod == nil {
+		return fmt.Errorf("pod %w", constant.ErrMissingRequiredParam)
+	}
+	if endpoint == nil {
+		return fmt.Errorf("endpoint %w", constant.ErrMissingRequiredParam)
 	}
 
 	// Create -> Delete -> Create a Pod with the same namespace and name in
 	// a short time will cause some unexpected phenomena discussed in
 	// https://github.com/spidernet-io/spiderpool/issues/1187.
-	if we.DeletionTimestamp != nil {
+	if endpoint.DeletionTimestamp != nil {
 		// We can use GVK + Pod name (Same name as Endpoint) for more accurate
 		// judgment, but this is unnecessary at present, because Endpoint has
 		// only one Owner.
-		ownerPod := we.GetOwnerReferences()[0]
+		ownerPod := endpoint.GetOwnerReferences()[0]
 		// Beware of deleting the normal Endpoint manually.
 		if ownerPod.UID != pod.GetUID() {
-			return nil, fmt.Errorf("currently, the IP addresses of the Pod %s/%s (uid: %s) is being recycled. You may create two Pods with the same namespace and name in a very short time", we.Namespace, ownerPod.Name, string(ownerPod.UID))
+			return fmt.Errorf("currently, the IP addresses of the Pod %s/%s (uid: %s) is being recycled. You may create two Pods with the same namespace and name in a very short time", endpoint.Namespace, ownerPod.Name, string(ownerPod.UID))
 		}
 	}
 
-	if we.Status.Current != nil && we.Status.Current.ContainerID == containerID {
-		return we, nil
+	if endpoint.Status.Current != nil && endpoint.Status.Current.ContainerID == containerID {
+		return nil
 	}
 
-	we.Status.Current = allocation
-	we.Status.History = append([]spiderpoolv1.PodIPAllocation{*allocation}, we.Status.History...)
-	if len(we.Status.History) > em.config.MaxHistoryRecords {
-		logger.Sugar().Warnf("threshold of historical IP allocation records(<=%d) exceeded", em.config.MaxHistoryRecords)
-		we.Status.History = we.Status.History[:em.config.MaxHistoryRecords]
+	allocation := &spiderpoolv1.PodIPAllocation{
+		ContainerID:  containerID,
+		Node:         &pod.Spec.NodeName,
+		CreationTime: &metav1.Time{Time: time.Now()},
 	}
 
-	if err := em.client.Status().Update(ctx, we); err != nil {
-		return nil, err
+	endpoint.Status.Current = allocation
+	endpoint.Status.History = append([]spiderpoolv1.PodIPAllocation{*allocation}, endpoint.Status.History...)
+	if len(endpoint.Status.History) > *em.config.MaxHistoryRecords {
+		logger.Sugar().Warnf("threshold of historical IP allocation records(<=%d) exceeded", em.config.MaxHistoryRecords)
+		endpoint.Status.History = endpoint.Status.History[:*em.config.MaxHistoryRecords]
 	}
 
-	return we, nil
+	return em.client.Status().Update(ctx, endpoint)
 }
 
-func (em *workloadEndpointManager) PatchIPAllocation(ctx context.Context, allocation *spiderpoolv1.PodIPAllocation, we *spiderpoolv1.SpiderEndpoint) error {
-	if we == nil || we.Status.Current == nil {
+func (em *workloadEndpointManager) PatchIPAllocation(ctx context.Context, allocation *spiderpoolv1.PodIPAllocation, endpoint *spiderpoolv1.SpiderEndpoint) error {
+	if endpoint == nil {
+		return fmt.Errorf("endpoint %w", constant.ErrMissingRequiredParam)
+	}
+
+	if allocation == nil {
+		return fmt.Errorf("allocation %w", constant.ErrMissingRequiredParam)
+	}
+
+	if endpoint.Status.Current == nil {
 		return errors.New("patch a unmarked Endpoint")
 	}
 
-	if we.Status.Current.ContainerID != allocation.ContainerID {
-		return fmt.Errorf("patch a mismarked Endpoint with IP allocation: %v", *we.Status.Current)
+	if len(endpoint.Status.History) == 0 ||
+		endpoint.Status.History[0].ContainerID != endpoint.Status.Current.ContainerID {
+		return errors.New("data of the Endpoint is corrupt")
+	}
+
+	if endpoint.Status.Current.ContainerID != allocation.ContainerID {
+		return errors.New("patch a mismarked Endpoint")
 	}
 
 	var merged bool
-	for i, d := range we.Status.Current.IPs {
+	for i, d := range endpoint.Status.Current.IPs {
 		if d.NIC == allocation.IPs[0].NIC {
-			mergeIPDetails(&we.Status.Current.IPs[i], &allocation.IPs[0])
-			mergeIPDetails(&we.Status.History[0].IPs[i], &allocation.IPs[0])
+			mergeIPAllocationDetails(&endpoint.Status.Current.IPs[i], &allocation.IPs[0])
+			mergeIPAllocationDetails(&endpoint.Status.History[0].IPs[i], &allocation.IPs[0])
 			merged = true
 			break
 		}
 	}
 
 	if !merged {
-		we.Status.Current.IPs = append(we.Status.Current.IPs, allocation.IPs...)
-		we.Status.History[0].IPs = append(we.Status.History[0].IPs, allocation.IPs...)
+		endpoint.Status.Current.IPs = append(endpoint.Status.Current.IPs, allocation.IPs...)
+		endpoint.Status.History[0].IPs = append(endpoint.Status.History[0].IPs, allocation.IPs...)
 	}
 
-	return em.client.Status().Update(ctx, we)
+	return em.client.Status().Update(ctx, endpoint)
 }
 
-func (em *workloadEndpointManager) ClearCurrentIPAllocation(ctx context.Context, containerID string, we *spiderpoolv1.SpiderEndpoint) error {
-	if we == nil || we.Status.Current == nil {
+func mergeIPAllocationDetails(target, delta *spiderpoolv1.IPAllocationDetail) {
+	if target.IPv4 == nil {
+		target.IPv4 = delta.IPv4
+	}
+	if target.IPv4Pool == nil {
+		target.IPv4Pool = delta.IPv4Pool
+	}
+	if target.IPv4Gateway == nil {
+		target.IPv4Gateway = delta.IPv4Gateway
+	}
+	if target.IPv6 == nil {
+		target.IPv6 = delta.IPv6
+	}
+	if target.IPv6Pool == nil {
+		target.IPv6Pool = delta.IPv6Pool
+	}
+	if target.IPv6Gateway == nil {
+		target.IPv6Gateway = delta.IPv6Gateway
+	}
+	target.Routes = append(target.Routes, delta.Routes...)
+}
+
+func (em *workloadEndpointManager) ClearCurrentIPAllocation(ctx context.Context, containerID string, endpoint *spiderpoolv1.SpiderEndpoint) error {
+	if endpoint == nil || endpoint.Status.Current == nil {
 		return nil
 	}
 
-	if we.Status.Current.ContainerID != containerID {
+	if endpoint.Status.Current.ContainerID != containerID {
 		return nil
 	}
 
-	we.Status.Current = nil
-	if err := em.client.Status().Update(ctx, we); err != nil {
-		if apierrors.IsNotFound(err) {
-			return nil
-		}
-		return err
+	endpoint.Status.Current = nil
+	if err := em.client.Status().Update(ctx, endpoint); err != nil {
+		return client.IgnoreNotFound(err)
 	}
 
 	return nil
 }
 
-// RemoveFinalizer removes a specific finalizer field in finalizers string array.
-func (em *workloadEndpointManager) RemoveFinalizer(ctx context.Context, namespace, podName string) error {
+func (em *workloadEndpointManager) ReallocateCurrentIPAllocation(ctx context.Context, containerID, nodeName, namespace, podName string) error {
 	for i := 0; i <= em.config.MaxConflictRetries; i++ {
 		endpoint, err := em.GetEndpointByName(ctx, namespace, podName)
-		if err != nil {
+		if nil != err {
 			return err
 		}
 
-		if !controllerutil.ContainsFinalizer(endpoint, constant.SpiderFinalizer) {
+		if endpoint.Status.Current.ContainerID == containerID {
 			return nil
 		}
 
-		controllerutil.RemoveFinalizer(endpoint, constant.SpiderFinalizer)
-		if err := em.client.Update(ctx, endpoint); err != nil {
+		endpoint.Status.Current.ContainerID = containerID
+		*endpoint.Status.Current.Node = nodeName
+		endpoint.Status.History = append([]spiderpoolv1.PodIPAllocation{*endpoint.Status.Current}, endpoint.Status.History...)
+		if err = em.client.Status().Update(ctx, endpoint); err != nil {
 			if !apierrors.IsConflict(err) {
 				return err
 			}
 			if i == em.config.MaxConflictRetries {
-				return fmt.Errorf("%w(<=%d) to remove finalizer '%s' from Endpoint %s", constant.ErrRetriesExhausted, em.config.MaxConflictRetries, constant.SpiderFinalizer, podName)
+				return fmt.Errorf("%w (%d times), failed to reallocate the Endpoint %s/%s of StatefulSet", constant.ErrRetriesExhausted, em.config.MaxConflictRetries, namespace, podName)
 			}
 			time.Sleep(time.Duration(rand.Intn(1<<(i+1))) * em.config.ConflictRetryUnitTime)
 			continue
@@ -238,105 +312,3 @@ func (em *workloadEndpointManager) RemoveFinalizer(ctx context.Context, namespac
 
 	return nil
 }
-
-// IsIPBelongWEPCurrent will check the given IP whether belong to the wep current IPs.
-func (em *workloadEndpointManager) IsIPBelongWEPCurrent(ctx context.Context, namespace, podName, poolIP string) (bool, error) {
-	wep, err := em.GetEndpointByName(ctx, namespace, podName)
-	if err != nil {
-		return false, err
-	}
-
-	isBelongWEPCurrent := false
-	if wep.Status.Current != nil {
-		// wep will record the IP address and CIDR and the given arg poolIP doesn't contain CIDR
-		for _, wepCurrentAllocationDetail := range wep.Status.Current.IPs {
-			var currentIPv4, currentIPv6 string
-
-			if wepCurrentAllocationDetail.IPv4 != nil {
-				currentIPv4AndCIDR := *wepCurrentAllocationDetail.IPv4
-				currentIPv4, _, _ = strings.Cut(currentIPv4AndCIDR, "/")
-			}
-
-			if wepCurrentAllocationDetail.IPv6 != nil {
-				currentIPv6AndCIDR := *wepCurrentAllocationDetail.IPv6
-				currentIPv6, _, _ = strings.Cut(currentIPv6AndCIDR, "/")
-			}
-
-			// if the given poolIP is same with the current IP, just break
-			if poolIP == currentIPv4 || poolIP == currentIPv6 {
-				isBelongWEPCurrent = true
-				break
-			}
-		}
-	}
-
-	return isBelongWEPCurrent, nil
-}
-
-// CheckCurrentContainerID will check whether the current containerID of SpiderEndpoint is same with the given args or not
-func (em *workloadEndpointManager) CheckCurrentContainerID(ctx context.Context, namespace, podName, containerID string) (bool, error) {
-	wep, err := em.GetEndpointByName(ctx, namespace, podName)
-	if err != nil {
-		return false, err
-	}
-
-	// data broken
-	if len(wep.Status.History) == 0 {
-		return false, fmt.Errorf("WEP '%s/%s' data broken, no current data, details: '%+v'", namespace, podName, wep)
-	}
-
-	if wep.Status.Current != nil && wep.Status.Current.ContainerID == containerID {
-		return true, nil
-	}
-
-	return false, nil
-}
-
-func (r *workloadEndpointManager) Delete(ctx context.Context, sep *spiderpoolv1.SpiderEndpoint) error {
-	err := r.client.Delete(ctx, sep)
-
-	return client.IgnoreNotFound(err)
-}
-
-// UpdateCurrentStatus serves for StatefulSet pod re-create
-func (em *workloadEndpointManager) UpdateCurrentStatus(ctx context.Context, containerID string, pod *corev1.Pod) error {
-	for i := 0; i <= em.config.MaxConflictRetries; i++ {
-		sep, err := em.GetEndpointByName(ctx, pod.Namespace, pod.Name)
-		if nil != err {
-			return err
-		}
-
-		// refresh containerID and NodeName
-		var hasChange bool
-		if sep.Status.Current.ContainerID != containerID {
-			sep.Status.Current.ContainerID = containerID
-
-			if *sep.Status.Current.Node != pod.Spec.NodeName {
-				*sep.Status.Current.Node = pod.Spec.NodeName
-			}
-			hasChange = true
-		}
-
-		if hasChange {
-			currentPodIPAllocation := *sep.Status.Current
-			sep.Status.History = append([]spiderpoolv1.PodIPAllocation{currentPodIPAllocation}, sep.Status.History...)
-
-			err = em.client.Status().Update(ctx, sep)
-			if nil != err {
-				if !apierrors.IsConflict(err) {
-					return err
-				}
-
-				if i == em.config.MaxConflictRetries {
-					return fmt.Errorf("%w(<=%d) to re-allocate StatefulSet SpiderEndpoint '%s/%s'", constant.ErrRetriesExhausted, em.config.MaxConflictRetries, pod.Namespace, pod.Name)
-				}
-
-				time.Sleep(time.Duration(rand.Intn(1<<(i+1))) * em.config.ConflictRetryUnitTime)
-				continue
-			}
-		}
-		break
-	}
-
-	return nil
-}
diff --git a/pkg/workloadendpointmanager/workloadendpoint_mutate.go b/pkg/workloadendpointmanager/workloadendpoint_mutate.go
new file mode 100644
index 000000000..74380a970
--- /dev/null
+++ b/pkg/workloadendpointmanager/workloadendpoint_mutate.go
@@ -0,0 +1,31 @@
+// Copyright 2022 Authors of spidernet-io
+// SPDX-License-Identifier: Apache-2.0
+
+package workloadendpointmanager
+
+import (
+	"context"
+
+	"github.com/spidernet-io/spiderpool/pkg/constant"
+	"github.com/spidernet-io/spiderpool/pkg/logutils"
+	"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
+
+	spiderpoolv1 "github.com/spidernet-io/spiderpool/pkg/k8s/apis/spiderpool.spidernet.io/v1"
+)
+
+func (ew *WorkloadEndpointWebhook) mutateWorkloadEndpoint(ctx context.Context, endpoint *spiderpoolv1.SpiderEndpoint) error {
+	logger := logutils.FromContext(ctx)
+	logger.Info("Start to mutate Endpoint")
+
+	if endpoint.DeletionTimestamp != nil {
+		logger.Info("Terminating Endpoint, noting to mutate")
+		return nil
+	}
+
+	if !controllerutil.ContainsFinalizer(endpoint, constant.SpiderFinalizer) {
+		controllerutil.AddFinalizer(endpoint, constant.SpiderFinalizer)
+		logger.Sugar().Infof("Add finalizer %s", constant.SpiderFinalizer)
+	}
+
+	return nil
+}
diff --git a/pkg/workloadendpointmanager/workloadendpoint_webhook.go b/pkg/workloadendpointmanager/workloadendpoint_webhook.go
index 36b9558c5..0a589f2b0 100644
--- a/pkg/workloadendpointmanager/workloadendpoint_webhook.go
+++ b/pkg/workloadendpointmanager/workloadendpoint_webhook.go
@@ -5,57 +5,46 @@ package workloadendpointmanager
 
 import (
 	"context"
-	"fmt"
 
 	"go.uber.org/zap"
-	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	"k8s.io/apimachinery/pkg/runtime"
 	ctrl "sigs.k8s.io/controller-runtime"
-	"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
 	"sigs.k8s.io/controller-runtime/pkg/webhook"
 
-	"github.com/spidernet-io/spiderpool/pkg/constant"
 	spiderpoolv1 "github.com/spidernet-io/spiderpool/pkg/k8s/apis/spiderpool.spidernet.io/v1"
 	"github.com/spidernet-io/spiderpool/pkg/logutils"
 )
 
-var webhookLogger *zap.Logger
+var WebhookLogger *zap.Logger
 
-func (wm *workloadEndpointManager) SetupWebhook() error {
-	if webhookLogger == nil {
-		webhookLogger = logutils.Logger.Named("Endpoint-Webhook")
+type WorkloadEndpointWebhook struct {
+}
+
+func (ew *WorkloadEndpointWebhook) SetupWebhookWithManager(mgr ctrl.Manager) error {
+	if WebhookLogger == nil {
+		WebhookLogger = logutils.Logger.Named("Endpoint-Webhook")
 	}
 
-	return ctrl.NewWebhookManagedBy(wm.runtimeMgr).
+	return ctrl.NewWebhookManagedBy(mgr).
 		For(&spiderpoolv1.SpiderEndpoint{}).
-		WithDefaulter(wm).
+		WithDefaulter(ew).
 		Complete()
 }
 
-var _ webhook.CustomDefaulter = (*workloadEndpointManager)(nil)
+var _ webhook.CustomDefaulter = (*WorkloadEndpointWebhook)(nil)
 
 // Default implements webhook.CustomDefaulter so a webhook will be registered for the type.
-func (rm *workloadEndpointManager) Default(ctx context.Context, obj runtime.Object) error {
-	endpoint, ok := obj.(*spiderpoolv1.SpiderEndpoint)
-	if !ok {
-		return apierrors.NewBadRequest(fmt.Sprintf("mutating webhook of Endpoint got an object with mismatched GVK: %+v", obj.GetObjectKind().GroupVersionKind()))
-	}
+func (ew *WorkloadEndpointWebhook) Default(ctx context.Context, obj runtime.Object) error {
+	endpoint := obj.(*spiderpoolv1.SpiderEndpoint)
 
-	logger := webhookLogger.Named("Mutating").With(
+	logger := WebhookLogger.Named("Mutating").With(
 		zap.String("EndpointName", endpoint.Name),
 		zap.String("Operation", "DEFAULT"),
 	)
-	logger.Info("Start to mutate Endpoint")
 	logger.Sugar().Debugf("Request Endpoint: %+v", *endpoint)
 
-	if endpoint.DeletionTimestamp != nil {
-		logger.Info("Deleting Endpoint, noting to mutate")
-		return nil
-	}
-
-	if !controllerutil.ContainsFinalizer(endpoint, constant.SpiderFinalizer) {
-		controllerutil.AddFinalizer(endpoint, constant.SpiderFinalizer)
-		logger.Sugar().Infof("Add finalizer %s", constant.SpiderFinalizer)
+	if err := ew.mutateWorkloadEndpoint(logutils.IntoContext(ctx, logger), endpoint); err != nil {
+		logger.Sugar().Errorf("Failed to mutate Endpoint: %v", err)
 	}
 
 	return nil
diff --git a/vendor/github.com/moby/moby/AUTHORS b/vendor/github.com/moby/moby/AUTHORS
new file mode 100644
index 000000000..dffacff11
--- /dev/null
+++ b/vendor/github.com/moby/moby/AUTHORS
@@ -0,0 +1,2175 @@
+# This file lists all individuals having contributed content to the repository.
+# For how it is generated, see `hack/generate-authors.sh`.
+
+Aanand Prasad <aanand.prasad@gmail.com>
+Aaron Davidson <aaron@databricks.com>
+Aaron Feng <aaron.feng@gmail.com>
+Aaron Hnatiw <aaron@griddio.com>
+Aaron Huslage <huslage@gmail.com>
+Aaron L. Xu <liker.xu@foxmail.com>
+Aaron Lehmann <aaron.lehmann@docker.com>
+Aaron Welch <welch@packet.net>
+Aaron.L.Xu <likexu@harmonycloud.cn>
+Abel Muiño <amuino@gmail.com>
+Abhijeet Kasurde <akasurde@redhat.com>
+Abhinandan Prativadi <abhi@docker.com>
+Abhinav Ajgaonkar <abhinav316@gmail.com>
+Abhishek Chanda <abhishek.becs@gmail.com>
+Abhishek Sharma <abhishek@asharma.me>
+Abin Shahab <ashahab@altiscale.com>
+Adam Avilla <aavilla@yp.com>
+Adam Dobrawy <naczelnik@jawnosc.tk>
+Adam Eijdenberg <adam.eijdenberg@gmail.com>
+Adam Kunk <adam.kunk@tiaa-cref.org>
+Adam Miller <admiller@redhat.com>
+Adam Mills <adam@armills.info>
+Adam Pointer <adam.pointer@skybettingandgaming.com>
+Adam Singer <financeCoding@gmail.com>
+Adam Walz <adam@adamwalz.net>
+Addam Hardy <addam.hardy@gmail.com>
+Aditi Rajagopal <arajagopal@us.ibm.com>
+Aditya <aditya@netroy.in>
+Adnan Khan <adnkha@amazon.com>
+Adolfo Ochagavía <aochagavia92@gmail.com>
+Adria Casas <adriacasas88@gmail.com>
+Adrian Moisey <adrian@changeover.za.net>
+Adrian Mouat <adrian.mouat@gmail.com>
+Adrian Oprea <adrian@codesi.nz>
+Adrien Folie <folie.adrien@gmail.com>
+Adrien Gallouët <adrien@gallouet.fr>
+Ahmed Kamal <email.ahmedkamal@googlemail.com>
+Ahmet Alp Balkan <ahmetb@microsoft.com>
+Aidan Feldman <aidan.feldman@gmail.com>
+Aidan Hobson Sayers <aidanhs@cantab.net>
+AJ Bowen <aj@soulshake.net>
+Ajey Charantimath <ajey.charantimath@gmail.com>
+ajneu <ajneu@users.noreply.github.com>
+Akash Gupta <akagup@microsoft.com>
+Akhil Mohan <akhil.mohan@mayadata.io>
+Akihiro Matsushima <amatsusbit@gmail.com>
+Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
+Akim Demaille <akim.demaille@docker.com>
+Akira Koyasu <mail@akirakoyasu.net>
+Akshay Karle <akshay.a.karle@gmail.com>
+Al Tobey <al@ooyala.com>
+alambike <alambike@gmail.com>
+Alan Hoyle <alan@alanhoyle.com>
+Alan Scherger <flyinprogrammer@gmail.com>
+Alan Thompson <cloojure@gmail.com>
+Albert Callarisa <shark234@gmail.com>
+Albert Zhang <zhgwenming@gmail.com>
+Albin Kerouanton <albin@akerouanton.name>
+Alejandro González Hevia <alejandrgh11@gmail.com>
+Aleksa Sarai <asarai@suse.de>
+Aleksandrs Fadins <aleks@s-ko.net>
+Alena Prokharchyk <alena@rancher.com>
+Alessandro Boch <aboch@tetrationanalytics.com>
+Alessio Biancalana <dottorblaster@gmail.com>
+Alex Chan <alex@alexwlchan.net>
+Alex Chen <alexchenunix@gmail.com>
+Alex Coventry <alx@empirical.com>
+Alex Crawford <alex.crawford@coreos.com>
+Alex Ellis <alexellis2@gmail.com>
+Alex Gaynor <alex.gaynor@gmail.com>
+Alex Goodman <wagoodman@gmail.com>
+Alex Olshansky <i@creagenics.com>
+Alex Samorukov <samm@os2.kiev.ua>
+Alex Warhawk <ax.warhawk@gmail.com>
+Alexander Artemenko <svetlyak.40wt@gmail.com>
+Alexander Boyd <alex@opengroove.org>
+Alexander Larsson <alexl@redhat.com>
+Alexander Midlash <amidlash@docker.com>
+Alexander Morozov <lk4d4@docker.com>
+Alexander Shopov <ash@kambanaria.org>
+Alexandre Beslic <alexandre.beslic@gmail.com>
+Alexandre Garnier <zigarn@gmail.com>
+Alexandre González <agonzalezro@gmail.com>
+Alexandre Jomin <alexandrejomin@gmail.com>
+Alexandru Sfirlogea <alexandru.sfirlogea@gmail.com>
+Alexei Margasov <alexei38@yandex.ru>
+Alexey Guskov <lexag@mail.ru>
+Alexey Kotlyarov <alexey@infoxchange.net.au>
+Alexey Shamrin <shamrin@gmail.com>
+Alexis THOMAS <fr.alexisthomas@gmail.com>
+Alfred Landrum <alfred.landrum@docker.com>
+Ali Dehghani <ali.dehghani.g@gmail.com>
+Alicia Lauerman <alicia@eta.im>
+Alihan Demir <alihan_6153@hotmail.com>
+Allen Madsen <blatyo@gmail.com>
+Allen Sun <allensun.shl@alibaba-inc.com>
+almoehi <almoehi@users.noreply.github.com>
+Alvaro Saurin <alvaro.saurin@gmail.com>
+Alvin Deng <alvin.q.deng@utexas.edu>
+Alvin Richards <alvin.richards@docker.com>
+amangoel <amangoel@gmail.com>
+Amen Belayneh <amenbelayneh@gmail.com>
+Amir Goldstein <amir73il@aquasec.com>
+Amit Bakshi <ambakshi@gmail.com>
+Amit Krishnan <amit.krishnan@oracle.com>
+Amit Shukla <amit.shukla@docker.com>
+Amr Gawish <amr.gawish@gmail.com>
+Amy Lindburg <amy.lindburg@docker.com>
+Anand Patil <anand.prabhakar.patil@gmail.com>
+AnandkumarPatel <anandkumarpatel@gmail.com>
+Anatoly Borodin <anatoly.borodin@gmail.com>
+Anca Iordache <anca.iordache@docker.com>
+Anchal Agrawal <aagrawa4@illinois.edu>
+Anda Xu <anda.xu@docker.com>
+Anders Janmyr <anders@janmyr.com>
+Andre Dublin <81dublin@gmail.com>
+Andre Granovsky <robotciti@live.com>
+Andrea Denisse Gómez <crypto.andrea@protonmail.ch>
+Andrea Luzzardi <aluzzardi@gmail.com>
+Andrea Turli <andrea.turli@gmail.com>
+Andreas Elvers <andreas@work.de>
+Andreas Köhler <andi5.py@gmx.net>
+Andreas Savvides <andreas@editd.com>
+Andreas Tiefenthaler <at@an-ti.eu>
+Andrei Gherzan <andrei@resin.io>
+Andrei Vagin <avagin@gmail.com>
+Andrew C. Bodine <acbodine@us.ibm.com>
+Andrew Clay Shafer <andrewcshafer@gmail.com>
+Andrew Duckworth <grillopress@gmail.com>
+Andrew France <andrew@avito.co.uk>
+Andrew Gerrand <adg@golang.org>
+Andrew Guenther <guenther.andrew.j@gmail.com>
+Andrew He <he.andrew.mail@gmail.com>
+Andrew Hsu <andrewhsu@docker.com>
+Andrew Kuklewicz <kookster@gmail.com>
+Andrew Macgregor <andrew.macgregor@agworld.com.au>
+Andrew Macpherson <hopscotch23@gmail.com>
+Andrew Martin <sublimino@gmail.com>
+Andrew McDonnell <bugs@andrewmcdonnell.net>
+Andrew Munsell <andrew@wizardapps.net>
+Andrew Pennebaker <andrew.pennebaker@gmail.com>
+Andrew Po <absourd.noise@gmail.com>
+Andrew Weiss <andrew.weiss@docker.com>
+Andrew Williams <williams.andrew@gmail.com>
+Andrews Medina <andrewsmedina@gmail.com>
+Andrey Kolomentsev <andrey.kolomentsev@docker.com>
+Andrey Petrov <andrey.petrov@shazow.net>
+Andrey Stolbovsky <andrey.stolbovsky@gmail.com>
+André Martins <aanm90@gmail.com>
+andy <ztao@tibco-support.com>
+Andy Chambers <anchambers@paypal.com>
+andy diller <dillera@gmail.com>
+Andy Goldstein <agoldste@redhat.com>
+Andy Kipp <andy@rstudio.com>
+Andy Rothfusz <github@developersupport.net>
+Andy Smith <github@anarkystic.com>
+Andy Wilson <wilson.andrew.j+github@gmail.com>
+Anes Hasicic <anes.hasicic@gmail.com>
+Anil Belur <askb23@gmail.com>
+Anil Madhavapeddy <anil@recoil.org>
+Ankit Jain <ajatkj@yahoo.co.in>
+Ankush Agarwal <ankushagarwal11@gmail.com>
+Anonmily <michelle@michelleliu.io>
+Anran Qiao <anran.qiao@daocloud.io>
+Anshul Pundir <anshul.pundir@docker.com>
+Anthon van der Neut <anthon@mnt.org>
+Anthony Baire <Anthony.Baire@irisa.fr>
+Anthony Bishopric <git@anthonybishopric.com>
+Anthony Dahanne <anthony.dahanne@gmail.com>
+Anthony Sottile <asottile@umich.edu>
+Anton Löfgren <anton.lofgren@gmail.com>
+Anton Nikitin <anton.k.nikitin@gmail.com>
+Anton Polonskiy <anton.polonskiy@gmail.com>
+Anton Tiurin <noxiouz@yandex.ru>
+Antonio Murdaca <antonio.murdaca@gmail.com>
+Antonis Kalipetis <akalipetis@gmail.com>
+Antony Messerli <amesserl@rackspace.com>
+Anuj Bahuguna <anujbahuguna.dev@gmail.com>
+Anusha Ragunathan <anusha.ragunathan@docker.com>
+apocas <petermdias@gmail.com>
+Arash Deshmeh <adeshmeh@ca.ibm.com>
+ArikaChen <eaglesora@gmail.com>
+Arko Dasgupta <arko.dasgupta@docker.com>
+Arnaud Lefebvre <a.lefebvre@outlook.fr>
+Arnaud Porterie <arnaud.porterie@docker.com>
+Arnaud Rebillout <arnaud.rebillout@collabora.com>
+Arthur Barr <arthur.barr@uk.ibm.com>
+Arthur Gautier <baloo@gandi.net>
+Artur Meyster <arthurfbi@yahoo.com>
+Arun Gupta <arun.gupta@gmail.com>
+Asad Saeeduddin <masaeedu@gmail.com>
+Asbjørn Enge <asbjorn@hanafjedle.net>
+averagehuman <averagehuman@users.noreply.github.com>
+Avi Das <andas222@gmail.com>
+Avi Kivity <avi@scylladb.com>
+Avi Miller <avi.miller@oracle.com>
+Avi Vaid <avaid1996@gmail.com>
+ayoshitake <airandfingers@gmail.com>
+Azat Khuyiyakhmetov <shadow_uz@mail.ru>
+Bardia Keyoumarsi <bkeyouma@ucsc.edu>
+Barnaby Gray <barnaby@pickle.me.uk>
+Barry Allard <barry.allard@gmail.com>
+Bartłomiej Piotrowski <b@bpiotrowski.pl>
+Bastiaan Bakker <bbakker@xebia.com>
+bdevloed <boris.de.vloed@gmail.com>
+Ben Bonnefoy <frenchben@docker.com>
+Ben Firshman <ben@firshman.co.uk>
+Ben Golub <ben.golub@dotcloud.com>
+Ben Gould <ben@bengould.co.uk>
+Ben Hall <ben@benhall.me.uk>
+Ben Sargent <ben@brokendigits.com>
+Ben Severson <BenSeverson@users.noreply.github.com>
+Ben Toews <mastahyeti@gmail.com>
+Ben Wiklund <ben@daisyowl.com>
+Benjamin Atkin <ben@benatkin.com>
+Benjamin Baker <Benjamin.baker@utexas.edu>
+Benjamin Boudreau <boudreau.benjamin@gmail.com>
+Benjamin Yolken <yolken@stripe.com>
+Benny Ng <benny.tpng@gmail.com>
+Benoit Chesneau <bchesneau@gmail.com>
+Bernerd Schaefer <bj.schaefer@gmail.com>
+Bernhard M. Wiedemann <bwiedemann@suse.de>
+Bert Goethals <bert@bertg.be>
+Bertrand Roussel <broussel@sierrawireless.com>
+Bevisy Zhang <binbin36520@gmail.com>
+Bharath Thiruveedula <bharath_ves@hotmail.com>
+Bhiraj Butala <abhiraj.butala@gmail.com>
+Bhumika Bayani <bhumikabayani@gmail.com>
+Bilal Amarni <bilal.amarni@gmail.com>
+Bill Wang <ozbillwang@gmail.com>
+Bily Zhang <xcoder@tenxcloud.com>
+Bin Liu <liubin0329@gmail.com>
+Bingshen Wang <bingshen.wbs@alibaba-inc.com>
+Blake Geno <blakegeno@gmail.com>
+Boaz Shuster <ripcurld.github@gmail.com>
+bobby abbott <ttobbaybbob@gmail.com>
+Boqin Qin <bobbqqin@gmail.com>
+Boris Pruessmann <boris@pruessmann.org>
+Boshi Lian <farmer1992@gmail.com>
+Bouke Haarsma <bouke@webatoom.nl>
+Boyd Hemphill <boyd@feedmagnet.com>
+boynux <boynux@gmail.com>
+Bradley Cicenas <bradley.cicenas@gmail.com>
+Bradley Wright <brad@intranation.com>
+Brandon Liu <bdon@bdon.org>
+Brandon Philips <brandon.philips@coreos.com>
+Brandon Rhodes <brandon@rhodesmill.org>
+Brendan Dixon <brendand@microsoft.com>
+Brent Salisbury <brent.salisbury@docker.com>
+Brett Higgins <brhiggins@arbor.net>
+Brett Kochendorfer <brett.kochendorfer@gmail.com>
+Brett Randall <javabrett@gmail.com>
+Brian (bex) Exelbierd <bexelbie@redhat.com>
+Brian Bland <brian.bland@docker.com>
+Brian DeHamer <brian@dehamer.com>
+Brian Dorsey <brian@dorseys.org>
+Brian Flad <bflad417@gmail.com>
+Brian Goff <cpuguy83@gmail.com>
+Brian McCallister <brianm@skife.org>
+Brian Olsen <brian@maven-group.org>
+Brian Schwind <brianmschwind@gmail.com>
+Brian Shumate <brian@couchbase.com>
+Brian Torres-Gil <brian@dralth.com>
+Brian Trump <btrump@yelp.com>
+Brice Jaglin <bjaglin@teads.tv>
+Briehan Lombaard <briehan.lombaard@gmail.com>
+Brielle Broder <bbroder@google.com>
+Bruno Bigras <bigras.bruno@gmail.com>
+Bruno Binet <bruno.binet@gmail.com>
+Bruno Gazzera <bgazzera@paginar.com>
+Bruno Renié <brutasse@gmail.com>
+Bruno Tavares <btavare@thoughtworks.com>
+Bryan Bess <squarejaw@bsbess.com>
+Bryan Boreham <bjboreham@gmail.com>
+Bryan Matsuo <bryan.matsuo@gmail.com>
+Bryan Murphy <bmurphy1976@gmail.com>
+Burke Libbey <burke@libbey.me>
+Byung Kang <byung.kang.ctr@amrdec.army.mil>
+Caleb Spare <cespare@gmail.com>
+Calen Pennington <cale@edx.org>
+Cameron Boehmer <cameron.boehmer@gmail.com>
+Cameron Spear <cameronspear@gmail.com>
+Campbell Allen <campbell.allen@gmail.com>
+Candid Dauth <cdauth@cdauth.eu>
+Cao Weiwei <cao.weiwei30@zte.com.cn>
+Carl Henrik Lunde <chlunde@ping.uio.no>
+Carl Loa Odin <carlodin@gmail.com>
+Carl X. Su <bcbcarl@gmail.com>
+Carlo Mion <mion00@gmail.com>
+Carlos Alexandro Becker <caarlos0@gmail.com>
+Carlos de Paula <me@carlosedp.com>
+Carlos Sanchez <carlos@apache.org>
+Carol Fager-Higgins <carol.fager-higgins@docker.com>
+Cary <caryhartline@users.noreply.github.com>
+Casey Bisson <casey.bisson@joyent.com>
+Catalin Pirvu <pirvu.catalin94@gmail.com>
+Ce Gao <ce.gao@outlook.com>
+Cedric Davies <cedricda@microsoft.com>
+Cezar Sa Espinola <cezarsa@gmail.com>
+Chad Swenson <chadswen@gmail.com>
+Chance Zibolski <chance.zibolski@gmail.com>
+Chander Govindarajan <chandergovind@gmail.com>
+Chanhun Jeong <keyolk@gmail.com>
+Chao Wang <wangchao.fnst@cn.fujitsu.com>
+Charles Chan <charleswhchan@users.noreply.github.com>
+Charles Hooper <charles.hooper@dotcloud.com>
+Charles Law <claw@conduce.com>
+Charles Lindsay <chaz@chazomatic.us>
+Charles Merriam <charles.merriam@gmail.com>
+Charles Sarrazin <charles@sarraz.in>
+Charles Smith <charles.smith@docker.com>
+Charlie Drage <charlie@charliedrage.com>
+Charlie Lewis <charliel@lab41.org>
+Chase Bolt <chase.bolt@gmail.com>
+ChaYoung You <yousbe@gmail.com>
+Chen Chao <cc272309126@gmail.com>
+Chen Chuanliang <chen.chuanliang@zte.com.cn>
+Chen Hanxiao <chenhanxiao@cn.fujitsu.com>
+Chen Min <chenmin46@huawei.com>
+Chen Mingjie <chenmingjie0828@163.com>
+Chen Qiu <cheney-90@hotmail.com>
+Cheng-mean Liu <soccerl@microsoft.com>
+Chengfei Shang <cfshang@alauda.io>
+Chengguang Xu <cgxu519@gmx.com>
+chenyuzhu <chenyuzhi@oschina.cn>
+Chetan Birajdar <birajdar.chetan@gmail.com>
+Chewey <prosto-chewey@users.noreply.github.com>
+Chia-liang Kao <clkao@clkao.org>
+chli <chli@freewheel.tv>
+Cholerae Hu <choleraehyq@gmail.com>
+Chris Alfonso <calfonso@redhat.com>
+Chris Armstrong <chris@opdemand.com>
+Chris Dias <cdias@microsoft.com>
+Chris Dituri <csdituri@gmail.com>
+Chris Fordham <chris@fordham-nagy.id.au>
+Chris Gavin <chris@chrisgavin.me>
+Chris Gibson <chris@chrisg.io>
+Chris Khoo <chris.khoo@gmail.com>
+Chris McKinnel <chris.mckinnel@tangentlabs.co.uk>
+Chris McKinnel <chrismckinnel@gmail.com>
+Chris Price <cprice@mirantis.com>
+Chris Seto <chriskseto@gmail.com>
+Chris Snow <chsnow123@gmail.com>
+Chris St. Pierre <chris.a.st.pierre@gmail.com>
+Chris Stivers <chris@stivers.us>
+Chris Swan <chris.swan@iee.org>
+Chris Telfer <ctelfer@docker.com>
+Chris Wahl <github@wahlnetwork.com>
+Chris Weyl <cweyl@alumni.drew.edu>
+Chris White <me@cwprogram.com>
+Christian Berendt <berendt@b1-systems.de>
+Christian Brauner <christian.brauner@ubuntu.com>
+Christian Böhme <developement@boehme3d.de>
+Christian Muehlhaeuser <muesli@gmail.com>
+Christian Persson <saser@live.se>
+Christian Rotzoll <ch.rotzoll@gmail.com>
+Christian Simon <simon@swine.de>
+Christian Stefanescu <st.chris@gmail.com>
+Christophe Mehay <cmehay@online.net>
+Christophe Troestler <christophe.Troestler@umons.ac.be>
+Christophe Vidal <kriss@krizalys.com>
+Christopher Biscardi <biscarch@sketcht.com>
+Christopher Crone <christopher.crone@docker.com>
+Christopher Currie <codemonkey+github@gmail.com>
+Christopher Jones <tophj@linux.vnet.ibm.com>
+Christopher Latham <sudosurootdev@gmail.com>
+Christopher Rigor <crigor@gmail.com>
+Christy Norman <christy@linux.vnet.ibm.com>
+Chun Chen <ramichen@tencent.com>
+Ciro S. Costa <ciro.costa@usp.br>
+Clayton Coleman <ccoleman@redhat.com>
+Clinton Kitson <clintonskitson@gmail.com>
+Cody Roseborough <crrosebo@amazon.com>
+Coenraad Loubser <coenraad@wish.org.za>
+Colin Dunklau <colin.dunklau@gmail.com>
+Colin Hebert <hebert.colin@gmail.com>
+Colin Panisset <github@clabber.com>
+Colin Rice <colin@daedrum.net>
+Colin Walters <walters@verbum.org>
+Collin Guarino <collin.guarino@gmail.com>
+Colm Hally <colmhally@gmail.com>
+companycy <companycy@gmail.com>
+Corbin Coleman <corbin.coleman@docker.com>
+Corey Farrell <git@cfware.com>
+Cory Forsyth <cory.forsyth@gmail.com>
+cressie176 <github@stephen-cresswell.net>
+CrimsonGlory <CrimsonGlory@users.noreply.github.com>
+Cristian Ariza <dev@cristianrz.com>
+Cristian Staretu <cristian.staretu@gmail.com>
+cristiano balducci <cristiano.balducci@gmail.com>
+Cristina Yenyxe Gonzalez Garcia <cristina.yenyxe@gmail.com>
+Cruceru Calin-Cristian <crucerucalincristian@gmail.com>
+CUI Wei <ghostplant@qq.com>
+Cyprian Gracz <cyprian.gracz@micro-jumbo.eu>
+Cyril F <cyrilf7x@gmail.com>
+Daan van Berkel <daan.v.berkel.1980@gmail.com>
+Daehyeok Mun <daehyeok@gmail.com>
+Dafydd Crosby <dtcrsby@gmail.com>
+dalanlan <dalanlan925@gmail.com>
+Damian Smyth <damian@dsau.co>
+Damien Nadé <github@livna.org>
+Damien Nozay <damien.nozay@gmail.com>
+Damjan Georgievski <gdamjan@gmail.com>
+Dan Anolik <dan@anolik.net>
+Dan Buch <d.buch@modcloth.com>
+Dan Cotora <dan@bluevision.ro>
+Dan Feldman <danf@jfrog.com>
+Dan Griffin <dgriffin@peer1.com>
+Dan Hirsch <thequux@upstandinghackers.com>
+Dan Keder <dan.keder@gmail.com>
+Dan Levy <dan@danlevy.net>
+Dan McPherson <dmcphers@redhat.com>
+Dan Stine <sw@stinemail.com>
+Dan Williams <me@deedubs.com>
+Dani Hodovic <dani.hodovic@gmail.com>
+Dani Louca <dani.louca@docker.com>
+Daniel Antlinger <d.antlinger@gmx.at>
+Daniel Black <daniel@linux.ibm.com>
+Daniel Dao <dqminh@cloudflare.com>
+Daniel Exner <dex@dragonslave.de>
+Daniel Farrell <dfarrell@redhat.com>
+Daniel Garcia <daniel@danielgarcia.info>
+Daniel Gasienica <daniel@gasienica.ch>
+Daniel Grunwell <mwgrunny@gmail.com>
+Daniel Helfand <helfand.4@gmail.com>
+Daniel Hiltgen <daniel.hiltgen@docker.com>
+Daniel J Walsh <dwalsh@redhat.com>
+Daniel Menet <membership@sontags.ch>
+Daniel Mizyrycki <daniel.mizyrycki@dotcloud.com>
+Daniel Nephin <dnephin@docker.com>
+Daniel Norberg <dano@spotify.com>
+Daniel Nordberg <dnordberg@gmail.com>
+Daniel Robinson <gottagetmac@gmail.com>
+Daniel S <dan.streby@gmail.com>
+Daniel Sweet <danieljsweet@icloud.com>
+Daniel Von Fange <daniel@leancoder.com>
+Daniel Watkins <daniel@daniel-watkins.co.uk>
+Daniel X Moore <yahivin@gmail.com>
+Daniel YC Lin <dlin.tw@gmail.com>
+Daniel Zhang <jmzwcn@gmail.com>
+Danny Berger <dpb587@gmail.com>
+Danny Milosavljevic <dannym@scratchpost.org>
+Danny Yates <danny@codeaholics.org>
+Danyal Khaliq <danyal.khaliq@tenpearls.com>
+Darren Coxall <darren@darrencoxall.com>
+Darren Shepherd <darren.s.shepherd@gmail.com>
+Darren Stahl <darst@microsoft.com>
+Dattatraya Kumbhar <dattatraya.kumbhar@gslab.com>
+Davanum Srinivas <davanum@gmail.com>
+Dave Barboza <dbarboza@datto.com>
+Dave Goodchild <buddhamagnet@gmail.com>
+Dave Henderson <dhenderson@gmail.com>
+Dave MacDonald <mindlapse@gmail.com>
+Dave Tucker <dt@docker.com>
+David Anderson <dave@natulte.net>
+David Calavera <david.calavera@gmail.com>
+David Chung <david.chung@docker.com>
+David Corking <dmc-source@dcorking.com>
+David Cramer <davcrame@cisco.com>
+David Currie <david_currie@uk.ibm.com>
+David Davis <daviddavis@redhat.com>
+David Dooling <dooling@gmail.com>
+David Gageot <david@gageot.net>
+David Gebler <davidgebler@gmail.com>
+David Glasser <glasser@davidglasser.net>
+David Lawrence <david.lawrence@docker.com>
+David Lechner <david@lechnology.com>
+David M. Karr <davidmichaelkarr@gmail.com>
+David Mackey <tdmackey@booleanhaiku.com>
+David Mat <david@davidmat.com>
+David Mcanulty <github@hellspark.com>
+David McKay <david@rawkode.com>
+David P Hilton <david.hilton.p@gmail.com>
+David Pelaez <pelaez89@gmail.com>
+David R. Jenni <david.r.jenni@gmail.com>
+David Röthlisberger <david@rothlis.net>
+David Sheets <dsheets@docker.com>
+David Sissitka <me@dsissitka.com>
+David Trott <github@davidtrott.com>
+David Wang <00107082@163.com>
+David Williamson <david.williamson@docker.com>
+David Xia <dxia@spotify.com>
+David Young <yangboh@cn.ibm.com>
+Davide Ceretti <davide.ceretti@hogarthww.com>
+Dawn Chen <dawnchen@google.com>
+dbdd <wangtong2712@gmail.com>
+dcylabs <dcylabs@gmail.com>
+Debayan De <debayande@users.noreply.github.com>
+Deborah Gertrude Digges <deborah.gertrude.digges@gmail.com>
+deed02392 <georgehafiz@gmail.com>
+Deep Debroy <ddebroy@docker.com>
+Deng Guangxing <dengguangxing@huawei.com>
+Deni Bertovic <deni@kset.org>
+Denis Defreyne <denis@soundcloud.com>
+Denis Gladkikh <denis@gladkikh.email>
+Denis Ollier <larchunix@users.noreply.github.com>
+Dennis Chen <barracks510@gmail.com>
+Dennis Chen <dennis.chen@arm.com>
+Dennis Docter <dennis@d23.nl>
+Derek <crq@kernel.org>
+Derek <crquan@gmail.com>
+Derek Ch <denc716@gmail.com>
+Derek McGowan <derek@mcgstyle.net>
+Deric Crago <deric.crago@gmail.com>
+Deshi Xiao <dxiao@redhat.com>
+devmeyster <arthurfbi@yahoo.com>
+Devon Estes <devon.estes@klarna.com>
+Devvyn Murphy <devvyn@devvyn.com>
+Dharmit Shah <shahdharmit@gmail.com>
+Dhawal Yogesh Bhanushali <dbhanushali@vmware.com>
+Diego Romero <idiegoromero@gmail.com>
+Diego Siqueira <dieg0@live.com>
+Dieter Reuter <dieter.reuter@me.com>
+Dillon Dixon <dillondixon@gmail.com>
+Dima Stopel <dima@twistlock.com>
+Dimitri John Ledkov <dimitri.j.ledkov@intel.com>
+Dimitris Mandalidis <dimitris.mandalidis@gmail.com>
+Dimitris Rozakis <dimrozakis@gmail.com>
+Dimitry Andric <d.andric@activevideo.com>
+Dinesh Subhraveti <dineshs@altiscale.com>
+Ding Fei <dingfei@stars.org.cn>
+Diogo Monica <diogo@docker.com>
+DiuDiugirl <sophia.wang@pku.edu.cn>
+Djibril Koné <kone.djibril@gmail.com>
+dkumor <daniel@dkumor.com>
+Dmitri Logvinenko <dmitri.logvinenko@gmail.com>
+Dmitri Shuralyov <shurcooL@gmail.com>
+Dmitry Demeshchuk <demeshchuk@gmail.com>
+Dmitry Gusev <dmitry.gusev@gmail.com>
+Dmitry Kononenko <d@dm42.ru>
+Dmitry Sharshakov <d3dx12.xx@gmail.com>
+Dmitry Shyshkin <dmitry@shyshkin.org.ua>
+Dmitry Smirnov <onlyjob@member.fsf.org>
+Dmitry V. Krivenok <krivenok.dmitry@gmail.com>
+Dmitry Vorobev <dimahabr@gmail.com>
+Dolph Mathews <dolph.mathews@gmail.com>
+Dominic Tubach <dominic.tubach@to.com>
+Dominic Yin <yindongchao@inspur.com>
+Dominik Dingel <dingel@linux.vnet.ibm.com>
+Dominik Finkbeiner <finkes93@gmail.com>
+Dominik Honnef <dominik@honnef.co>
+Don Kirkby <donkirkby@users.noreply.github.com>
+Don Kjer <don.kjer@gmail.com>
+Don Spaulding <donspauldingii@gmail.com>
+Donald Huang <don.hcd@gmail.com>
+Dong Chen <dongluo.chen@docker.com>
+Donghwa Kim <shanytt@gmail.com>
+Donovan Jones <git@gamma.net.nz>
+Doron Podoleanu <doronp@il.ibm.com>
+Doug Davis <dug@us.ibm.com>
+Doug MacEachern <dougm@vmware.com>
+Doug Tangren <d.tangren@gmail.com>
+Douglas Curtis <dougcurtis1@gmail.com>
+Dr Nic Williams <drnicwilliams@gmail.com>
+dragon788 <dragon788@users.noreply.github.com>
+Dražen Lučanin <kermit666@gmail.com>
+Drew Erny <derny@mirantis.com>
+Drew Hubl <drew.hubl@gmail.com>
+Dustin Sallings <dustin@spy.net>
+Ed Costello <epc@epcostello.com>
+Edmund Wagner <edmund-wagner@web.de>
+Eiichi Tsukata <devel@etsukata.com>
+Eike Herzbach <eike@herzbach.net>
+Eivin Giske Skaaren <eivinsn@axis.com>
+Eivind Uggedal <eivind@uggedal.com>
+Elan Ruusamäe <glen@pld-linux.org>
+Elango Sivanandam <elango.siva@docker.com>
+Elena Morozova <lelenanam@gmail.com>
+Eli Uriegas <eli.uriegas@docker.com>
+Elias Faxö <elias.faxo@tre.se>
+Elias Probst <mail@eliasprobst.eu>
+Elijah Zupancic <elijah@zupancic.name>
+eluck <mail@eluck.me>
+Elvir Kuric <elvirkuric@gmail.com>
+Emil Davtyan <emil2k@gmail.com>
+Emil Hernvall <emil@quench.at>
+Emily Maier <emily@emilymaier.net>
+Emily Rose <emily@contactvibe.com>
+Emir Ozer <emirozer@yandex.com>
+Enguerran <engcolson@gmail.com>
+Eohyung Lee <liquidnuker@gmail.com>
+epeterso <epeterson@breakpoint-labs.com>
+Eric Barch <barch@tomesoftware.com>
+Eric Curtin <ericcurtin17@gmail.com>
+Eric G. Noriega <enoriega@vizuri.com>
+Eric Hanchrow <ehanchrow@ine.com>
+Eric Lee <thenorthsecedes@gmail.com>
+Eric Myhre <hash@exultant.us>
+Eric Paris <eparis@redhat.com>
+Eric Rafaloff <erafaloff@gmail.com>
+Eric Rosenberg <ehaydenr@gmail.com>
+Eric Sage <eric.david.sage@gmail.com>
+Eric Soderstrom <ericsoderstrom@gmail.com>
+Eric Yang <windfarer@gmail.com>
+Eric-Olivier Lamey <eo@lamey.me>
+Erica Windisch <erica@windisch.us>
+Erik Bray <erik.m.bray@gmail.com>
+Erik Dubbelboer <erik@dubbelboer.com>
+Erik Hollensbe <github@hollensbe.org>
+Erik Inge Bolsø <knan@redpill-linpro.com>
+Erik Kristensen <erik@erikkristensen.com>
+Erik St. Martin <alakriti@gmail.com>
+Erik Weathers <erikdw@gmail.com>
+Erno Hopearuoho <erno.hopearuoho@gmail.com>
+Erwin van der Koogh <info@erronis.nl>
+Ethan Bell <ebgamer29@gmail.com>
+Ethan Mosbaugh <ethan@replicated.com>
+Euan Kemp <euan.kemp@coreos.com>
+Eugen Krizo <eugen.krizo@gmail.com>
+Eugene Yakubovich <eugene.yakubovich@coreos.com>
+Evan Allrich <evan@unguku.com>
+Evan Carmi <carmi@users.noreply.github.com>
+Evan Hazlett <ejhazlett@gmail.com>
+Evan Krall <krall@yelp.com>
+Evan Phoenix <evan@fallingsnow.net>
+Evan Wies <evan@neomantra.net>
+Evelyn Xu <evelynhsu21@gmail.com>
+Everett Toews <everett.toews@rackspace.com>
+Evgeniy Makhrov <e.makhrov@corp.badoo.com>
+Evgeny Shmarnev <shmarnev@gmail.com>
+Evgeny Vereshchagin <evvers@ya.ru>
+Ewa Czechowska <ewa@ai-traders.com>
+Eystein Måløy Stenberg <eystein.maloy.stenberg@cfengine.com>
+ezbercih <cem.ezberci@gmail.com>
+Ezra Silvera <ezra@il.ibm.com>
+Fabian Kramm <kramm@covexo.com>
+Fabian Lauer <kontakt@softwareschmiede-saar.de>
+Fabian Raetz <fabian.raetz@gmail.com>
+Fabiano Rosas <farosas@br.ibm.com>
+Fabio Falci <fabiofalci@gmail.com>
+Fabio Kung <fabio.kung@gmail.com>
+Fabio Rapposelli <fabio@vmware.com>
+Fabio Rehm <fgrehm@gmail.com>
+Fabrizio Regini <freegenie@gmail.com>
+Fabrizio Soppelsa <fsoppelsa@mirantis.com>
+Faiz Khan <faizkhan00@gmail.com>
+falmp <chico.lopes@gmail.com>
+Fangming Fang <fangming.fang@arm.com>
+Fangyuan Gao <21551127@zju.edu.cn>
+fanjiyun <fan.jiyun@zte.com.cn>
+Fareed Dudhia <fareeddudhia@googlemail.com>
+Fathi Boudra <fathi.boudra@linaro.org>
+Federico Gimenez <fgimenez@coit.es>
+Felipe Oliveira <felipeweb.programador@gmail.com>
+Felipe Ruhland <felipe.ruhland@gmail.com>
+Felix Abecassis <fabecassis@nvidia.com>
+Felix Geisendörfer <felix@debuggable.com>
+Felix Hupfeld <felix@quobyte.com>
+Felix Rabe <felix@rabe.io>
+Felix Ruess <felix.ruess@gmail.com>
+Felix Schindler <fschindler@weluse.de>
+Feng Yan <fy2462@gmail.com>
+Fengtu Wang <wangfengtu@huawei.com>
+Ferenc Szabo <pragmaticfrank@gmail.com>
+Fernando <fermayo@gmail.com>
+Fero Volar <alian@alian.info>
+Ferran Rodenas <frodenas@gmail.com>
+Filipe Brandenburger <filbranden@google.com>
+Filipe Oliveira <contato@fmoliveira.com.br>
+Flavio Castelli <fcastelli@suse.com>
+Flavio Crisciani <flavio.crisciani@docker.com>
+Florian <FWirtz@users.noreply.github.com>
+Florian Klein <florian.klein@free.fr>
+Florian Maier <marsmensch@users.noreply.github.com>
+Florian Noeding <noeding@adobe.com>
+Florian Schmaus <flo@geekplace.eu>
+Florian Weingarten <flo@hackvalue.de>
+Florin Asavoaie <florin.asavoaie@gmail.com>
+Florin Patan <florinpatan@gmail.com>
+fonglh <fonglh@gmail.com>
+Foysal Iqbal <foysal.iqbal.fb@gmail.com>
+Francesc Campoy <campoy@google.com>
+Francesco Mari <mari.francesco@gmail.com>
+Francis Chuang <francis.chuang@boostport.com>
+Francisco Carriedo <fcarriedo@gmail.com>
+Francisco Souza <f@souza.cc>
+Frank Groeneveld <frank@ivaldi.nl>
+Frank Herrmann <fgh@4gh.tv>
+Frank Macreery <frank@macreery.com>
+Frank Rosquin <frank.rosquin+github@gmail.com>
+frankyang <yyb196@gmail.com>
+Fred Lifton <fred.lifton@docker.com>
+Frederick F. Kautz IV <fkautz@redhat.com>
+Frederik Loeffert <frederik@zitrusmedia.de>
+Frederik Nordahl Jul Sabroe <frederikns@gmail.com>
+Freek Kalter <freek@kalteronline.org>
+Frieder Bluemle <frieder.bluemle@gmail.com>
+Fu JinLin <withlin@yeah.net>
+Félix Baylac-Jacqué <baylac.felix@gmail.com>
+Félix Cantournet <felix.cantournet@cloudwatt.com>
+Gabe Rosenhouse <gabe@missionst.com>
+Gabor Nagy <mail@aigeruth.hu>
+Gabriel Linder <linder.gabriel@gmail.com>
+Gabriel Monroy <gabriel@opdemand.com>
+Gabriel Nicolas Avellaneda <avellaneda.gabriel@gmail.com>
+Gaetan de Villele <gdevillele@gmail.com>
+Galen Sampson <galen.sampson@gmail.com>
+Gang Qiao <qiaohai8866@gmail.com>
+Gareth Rushgrove <gareth@morethanseven.net>
+Garrett Barboza <garrett@garrettbarboza.com>
+Gary Schaetz <gary@schaetzkc.com>
+Gaurav <gaurav.gosec@gmail.com>
+Gaurav Singh <gaurav1086@gmail.com>
+Gaël PORTAY <gael.portay@savoirfairelinux.com>
+Genki Takiuchi <genki@s21g.com>
+GennadySpb <lipenkov@gmail.com>
+Geoffrey Bachelet <grosfrais@gmail.com>
+Geon Kim <geon0250@gmail.com>
+George Kontridze <george@bugsnag.com>
+George MacRorie <gmacr31@gmail.com>
+George Xie <georgexsh@gmail.com>
+Georgi Hristozov <georgi@forkbomb.nl>
+Gereon Frey <gereon.frey@dynport.de>
+German DZ <germ@ndz.com.ar>
+Gert van Valkenhoef <g.h.m.van.valkenhoef@rug.nl>
+Gerwim Feiken <g.feiken@tfe.nl>
+Ghislain Bourgeois <ghislain.bourgeois@gmail.com>
+Giampaolo Mancini <giampaolo@trampolineup.com>
+Gianluca Borello <g.borello@gmail.com>
+Gildas Cuisinier <gildas.cuisinier@gcuisinier.net>
+Giovan Isa Musthofa <giovanism@outlook.co.id>
+gissehel <public-devgit-dantus@gissehel.org>
+Giuseppe Mazzotta <gdm85@users.noreply.github.com>
+Gleb Fotengauer-Malinovskiy <glebfm@altlinux.org>
+Gleb M Borisov <borisov.gleb@gmail.com>
+Glyn Normington <gnormington@gopivotal.com>
+GoBella <caili_welcome@163.com>
+Goffert van Gool <goffert@phusion.nl>
+Goldwyn Rodrigues <rgoldwyn@suse.com>
+Gopikannan Venugopalsamy <gopikannan.venugopalsamy@gmail.com>
+Gosuke Miyashita <gosukenator@gmail.com>
+Gou Rao <gou@portworx.com>
+Govinda Fichtner <govinda.fichtner@googlemail.com>
+Grant Millar <rid@cylo.io>
+Grant Reaber <grant.reaber@gmail.com>
+Graydon Hoare <graydon@pobox.com>
+Greg Fausak <greg@tacodata.com>
+Greg Pflaum <gpflaum@users.noreply.github.com>
+Greg Stephens <greg@udon.org>
+Greg Thornton <xdissent@me.com>
+Grzegorz Jaśkiewicz <gj.jaskiewicz@gmail.com>
+Guilhem Lettron <guilhem+github@lettron.fr>
+Guilherme Salgado <gsalgado@gmail.com>
+Guillaume Dufour <gdufour.prestataire@voyages-sncf.com>
+Guillaume J. Charmes <guillaume.charmes@docker.com>
+guoxiuyan <guoxiuyan@huawei.com>
+Guri <odg0318@gmail.com>
+Gurjeet Singh <gurjeet@singh.im>
+Guruprasad <lgp171188@gmail.com>
+Gustav Sinder <gustav.sinder@gmail.com>
+gwx296173 <gaojing3@huawei.com>
+Günter Zöchbauer <guenter@gzoechbauer.com>
+Haichao Yang <yang.haichao@zte.com.cn>
+haikuoliu <haikuo@amazon.com>
+Hakan Özler <hakan.ozler@kodcu.com>
+Hamish Hutchings <moredhel@aoeu.me>
+Hannes Ljungberg <hannes@5monkeys.se>
+Hans Kristian Flaatten <hans@starefossen.com>
+Hans Rødtang <hansrodtang@gmail.com>
+Hao Shu Wei <haosw@cn.ibm.com>
+Hao Zhang <21521210@zju.edu.cn>
+Harald Albers <github@albersweb.de>
+Harald Niesche <harald@niesche.de>
+Harley Laue <losinggeneration@gmail.com>
+Harold Cooper <hrldcpr@gmail.com>
+Harrison Turton <harrisonturton@gmail.com>
+Harry Zhang <harryz@hyper.sh>
+Harshal Patil <harshal.patil@in.ibm.com>
+Harshal Patil <harshalp@linux.vnet.ibm.com>
+He Simei <hesimei@zju.edu.cn>
+He Xiaoxi <tossmilestone@gmail.com>
+He Xin <he_xinworld@126.com>
+heartlock <21521209@zju.edu.cn>
+Hector Castro <hectcastro@gmail.com>
+Helen Xie <chenjg@harmonycloud.cn>
+Henning Sprang <henning.sprang@gmail.com>
+Hiroshi Hatake <hatake@clear-code.com>
+Hiroyuki Sasagawa <hs19870702@gmail.com>
+Hobofan <goisser94@gmail.com>
+Hollie Teal <hollie@docker.com>
+Hong Xu <hong@topbug.net>
+Hongbin Lu <hongbin034@gmail.com>
+Hongxu Jia <hongxu.jia@windriver.com>
+Honza Pokorny <me@honza.ca>
+Hsing-Hui Hsu <hsinghui@amazon.com>
+hsinko <21551195@zju.edu.cn>
+Hu Keping <hukeping@huawei.com>
+Hu Tao <hutao@cn.fujitsu.com>
+HuanHuan Ye <logindaveye@gmail.com>
+Huanzhong Zhang <zhanghuanzhong90@gmail.com>
+Huayi Zhang <irachex@gmail.com>
+Hugo Duncan <hugo@hugoduncan.org>
+Hugo Marisco <0x6875676f@gmail.com>
+Hunter Blanks <hunter@twilio.com>
+huqun <huqun@zju.edu.cn>
+Huu Nguyen <huu@prismskylabs.com>
+hyeongkyu.lee <hyeongkyu.lee@navercorp.com>
+Hyzhou Zhy <hyzhou.zhy@alibaba-inc.com>
+Iago López Galeiras <iago@kinvolk.io>
+Ian Babrou <ibobrik@gmail.com>
+Ian Bishop <ianbishop@pace7.com>
+Ian Bull <irbull@gmail.com>
+Ian Calvert <ianjcalvert@gmail.com>
+Ian Campbell <ian.campbell@docker.com>
+Ian Chen <ianre657@gmail.com>
+Ian Lee <IanLee1521@gmail.com>
+Ian Main <imain@redhat.com>
+Ian Philpot <ian.philpot@microsoft.com>
+Ian Truslove <ian.truslove@gmail.com>
+Iavael <iavaelooeyt@gmail.com>
+Icaro Seara <icaro.seara@gmail.com>
+Ignacio Capurro <icapurrofagian@gmail.com>
+Igor Dolzhikov <bluesriverz@gmail.com>
+Igor Karpovich <i.karpovich@currencysolutions.com>
+Iliana Weller <iweller@amazon.com>
+Ilkka Laukkanen <ilkka@ilkka.io>
+Ilya Dmitrichenko <errordeveloper@gmail.com>
+Ilya Gusev <mail@igusev.ru>
+Ilya Khlopotov <ilya.khlopotov@gmail.com>
+imre Fitos <imre.fitos+github@gmail.com>
+inglesp <peter.inglesby@gmail.com>
+Ingo Gottwald <in.gottwald@gmail.com>
+Innovimax <innovimax@gmail.com>
+Isaac Dupree <antispam@idupree.com>
+Isabel Jimenez <contact.isabeljimenez@gmail.com>
+Isaiah Grace <irgkenya4@gmail.com>
+Isao Jonas <isao.jonas@gmail.com>
+Iskander Sharipov <quasilyte@gmail.com>
+Ivan Babrou <ibobrik@gmail.com>
+Ivan Fraixedes <ifcdev@gmail.com>
+Ivan Grcic <igrcic@gmail.com>
+Ivan Markin <sw@nogoegst.net>
+J Bruni <joaohbruni@yahoo.com.br>
+J. Nunn <jbnunn@gmail.com>
+Jack Danger Canty <jackdanger@squareup.com>
+Jack Laxson <jackjrabbit@gmail.com>
+Jacob Atzen <jacob@jacobatzen.dk>
+Jacob Edelman <edelman.jd@gmail.com>
+Jacob Tomlinson <jacob@tom.linson.uk>
+Jacob Vallejo <jakeev@amazon.com>
+Jacob Wen <jian.w.wen@oracle.com>
+Jaime Cepeda <jcepedavillamayor@gmail.com>
+Jaivish Kothari <janonymous.codevulture@gmail.com>
+Jake Champlin <jake.champlin.27@gmail.com>
+Jake Moshenko <jake@devtable.com>
+Jake Sanders <jsand@google.com>
+jakedt <jake@devtable.com>
+James Allen <jamesallen0108@gmail.com>
+James Carey <jecarey@us.ibm.com>
+James Carr <james.r.carr@gmail.com>
+James DeFelice <james.defelice@ishisystems.com>
+James Harrison Fisher <jameshfisher@gmail.com>
+James Kyburz <james.kyburz@gmail.com>
+James Kyle <james@jameskyle.org>
+James Lal <james@lightsofapollo.com>
+James Mills <prologic@shortcircuit.net.au>
+James Nesbitt <jnesbitt@mirantis.com>
+James Nugent <james@jen20.com>
+James Turnbull <james@lovedthanlost.net>
+James Watkins-Harvey <jwatkins@progi-media.com>
+Jamie Hannaford <jamie@limetree.org>
+Jamshid Afshar <jafshar@yahoo.com>
+Jan Chren <dev.rindeal@gmail.com>
+Jan Keromnes <janx@linux.com>
+Jan Koprowski <jan.koprowski@gmail.com>
+Jan Pazdziora <jpazdziora@redhat.com>
+Jan Toebes <jan@toebes.info>
+Jan-Gerd Tenberge <janten@gmail.com>
+Jan-Jaap Driessen <janjaapdriessen@gmail.com>
+Jana Radhakrishnan <mrjana@docker.com>
+Jannick Fahlbusch <git@jf-projects.de>
+Januar Wayong <januar@gmail.com>
+Jared Biel <jared.biel@bolderthinking.com>
+Jared Hocutt <jaredh@netapp.com>
+Jaroslaw Zabiello <hipertracker@gmail.com>
+jaseg <jaseg@jaseg.net>
+Jasmine Hegman <jasmine@jhegman.com>
+Jason A. Donenfeld <Jason@zx2c4.com>
+Jason Divock <jdivock@gmail.com>
+Jason Giedymin <jasong@apache.org>
+Jason Green <Jason.Green@AverInformatics.Com>
+Jason Hall <imjasonh@gmail.com>
+Jason Heiss <jheiss@aput.net>
+Jason Livesay <ithkuil@gmail.com>
+Jason McVetta <jason.mcvetta@gmail.com>
+Jason Plum <jplum@devonit.com>
+Jason Shepherd <jason@jasonshepherd.net>
+Jason Smith <jasonrichardsmith@gmail.com>
+Jason Sommer <jsdirv@gmail.com>
+Jason Stangroome <jason@codeassassin.com>
+jaxgeller <jacksongeller@gmail.com>
+Jay <imjching@hotmail.com>
+Jay <teguhwpurwanto@gmail.com>
+Jay Kamat <github@jgkamat.33mail.com>
+Jean Rouge <rougej+github@gmail.com>
+Jean-Baptiste Barth <jeanbaptiste.barth@gmail.com>
+Jean-Baptiste Dalido <jeanbaptiste@appgratis.com>
+Jean-Christophe Berthon <huygens@berthon.eu>
+Jean-Paul Calderone <exarkun@twistedmatrix.com>
+Jean-Pierre Huynh <jean-pierre.huynh@ounet.fr>
+Jean-Tiare Le Bigot <jt@yadutaf.fr>
+Jeeva S. Chelladhurai <sjeeva@gmail.com>
+Jeff Anderson <jeff@docker.com>
+Jeff Hajewski <jeff.hajewski@gmail.com>
+Jeff Johnston <jeff.johnston.mn@gmail.com>
+Jeff Lindsay <progrium@gmail.com>
+Jeff Mickey <j@codemac.net>
+Jeff Minard <jeff@creditkarma.com>
+Jeff Nickoloff <jeff.nickoloff@gmail.com>
+Jeff Silberman <jsilberm@gmail.com>
+Jeff Welch <whatthejeff@gmail.com>
+Jeffrey Bolle <jeffreybolle@gmail.com>
+Jeffrey Morgan <jmorganca@gmail.com>
+Jeffrey van Gogh <jvg@google.com>
+Jenny Gebske <jennifer@gebske.de>
+Jeremy Chambers <jeremy@thehipbot.com>
+Jeremy Grosser <jeremy@synack.me>
+Jeremy Price <jprice.rhit@gmail.com>
+Jeremy Qian <vanpire110@163.com>
+Jeremy Unruh <jeremybunruh@gmail.com>
+Jeremy Yallop <yallop@docker.com>
+Jeroen Franse <jeroenfranse@gmail.com>
+Jeroen Jacobs <github@jeroenj.be>
+Jesse Dearing <jesse.dearing@gmail.com>
+Jesse Dubay <jesse@thefortytwo.net>
+Jessica Frazelle <jess@oxide.computer>
+Jezeniel Zapanta <jpzapanta22@gmail.com>
+Jhon Honce <jhonce@redhat.com>
+Ji.Zhilong <zhilongji@gmail.com>
+Jian Liao <jliao@alauda.io>
+Jian Zhang <zhangjian.fnst@cn.fujitsu.com>
+Jiang Jinyang <jjyruby@gmail.com>
+Jie Luo <luo612@zju.edu.cn>
+Jie Ma <jienius@outlook.com>
+Jihyun Hwang <jhhwang@telcoware.com>
+Jilles Oldenbeuving <ojilles@gmail.com>
+Jim Alateras <jima@comware.com.au>
+Jim Ehrismann <jim.ehrismann@docker.com>
+Jim Galasyn <jim.galasyn@docker.com>
+Jim Minter <jminter@redhat.com>
+Jim Perrin <jperrin@centos.org>
+Jimmy Cuadra <jimmy@jimmycuadra.com>
+Jimmy Puckett <jimmy.puckett@spinen.com>
+Jimmy Song <rootsongjc@gmail.com>
+Jinsoo Park <cellpjs@gmail.com>
+Jintao Zhang <zhangjintao9020@gmail.com>
+Jiri Appl <jiria@microsoft.com>
+Jiri Popelka <jpopelka@redhat.com>
+Jiuyue Ma <majiuyue@huawei.com>
+Jiří Župka <jzupka@redhat.com>
+Joao Fernandes <joao.fernandes@docker.com>
+Joao Trindade <trindade.joao@gmail.com>
+Joe Beda <joe.github@bedafamily.com>
+Joe Doliner <jdoliner@pachyderm.io>
+Joe Ferguson <joe@infosiftr.com>
+Joe Gordon <joe.gordon0@gmail.com>
+Joe Shaw <joe@joeshaw.org>
+Joe Van Dyk <joe@tanga.com>
+Joel Friedly <joelfriedly@gmail.com>
+Joel Handwell <joelhandwell@gmail.com>
+Joel Hansson <joel.hansson@ecraft.com>
+Joel Wurtz <jwurtz@jolicode.com>
+Joey Geiger <jgeiger@gmail.com>
+Joey Geiger <jgeiger@users.noreply.github.com>
+Joey Gibson <joey@joeygibson.com>
+Joffrey F <joffrey@docker.com>
+Johan Euphrosine <proppy@google.com>
+Johan Rydberg <johan.rydberg@gmail.com>
+Johanan Lieberman <johanan.lieberman@gmail.com>
+Johannes 'fish' Ziemke <github@freigeist.org>
+John Costa <john.costa@gmail.com>
+John Feminella <jxf@jxf.me>
+John Gardiner Myers <jgmyers@proofpoint.com>
+John Gossman <johngos@microsoft.com>
+John Harris <john@johnharris.io>
+John Howard <github@lowenna.com>
+John Laswell <john.n.laswell@gmail.com>
+John Maguire <jmaguire@duosecurity.com>
+John Mulhausen <john@docker.com>
+John OBrien III <jobrieniii@yahoo.com>
+John Starks <jostarks@microsoft.com>
+John Stephens <johnstep@docker.com>
+John Tims <john.k.tims@gmail.com>
+John V. Martinez <jvmatl@gmail.com>
+John Warwick <jwarwick@gmail.com>
+John Willis <john.willis@docker.com>
+Jon Johnson <jonjohnson@google.com>
+Jon Surrell <jon.surrell@gmail.com>
+Jon Wedaman <jweede@gmail.com>
+Jonas Dohse <jonas@dohse.ch>
+Jonas Heinrich <Jonas@JonasHeinrich.com>
+Jonas Pfenniger <jonas@pfenniger.name>
+Jonathan A. Schweder <jonathanschweder@gmail.com>
+Jonathan A. Sternberg <jonathansternberg@gmail.com>
+Jonathan Boulle <jonathanboulle@gmail.com>
+Jonathan Camp <jonathan@irondojo.com>
+Jonathan Choy <jonathan.j.choy@gmail.com>
+Jonathan Dowland <jon+github@alcopop.org>
+Jonathan Lebon <jlebon@redhat.com>
+Jonathan Lomas <jonathan@floatinglomas.ca>
+Jonathan McCrohan <jmccrohan@gmail.com>
+Jonathan Mueller <j.mueller@apoveda.ch>
+Jonathan Pares <jonathanpa@users.noreply.github.com>
+Jonathan Rudenberg <jonathan@titanous.com>
+Jonathan Stoppani <jonathan.stoppani@divio.com>
+Jonh Wendell <jonh.wendell@redhat.com>
+Joni Sar <yoni@cocycles.com>
+Joost Cassee <joost@cassee.net>
+Jordan Arentsen <blissdev@gmail.com>
+Jordan Jennings <jjn2009@gmail.com>
+Jordan Sissel <jls@semicomplete.com>
+Jorge Marin <chipironcin@users.noreply.github.com>
+Jorit Kleine-Möllhoff <joppich@bricknet.de>
+Jose Diaz-Gonzalez <email@josediazgonzalez.com>
+Joseph Anthony Pasquale Holsten <joseph@josephholsten.com>
+Joseph Hager <ajhager@gmail.com>
+Joseph Kern <jkern@semafour.net>
+Joseph Rothrock <rothrock@rothrock.org>
+Josh <jokajak@gmail.com>
+Josh Bodah <jb3689@yahoo.com>
+Josh Bonczkowski <josh.bonczkowski@gmail.com>
+Josh Chorlton <jchorlton@gmail.com>
+Josh Eveleth <joshe@opendns.com>
+Josh Hawn <josh.hawn@docker.com>
+Josh Horwitz <horwitz@addthis.com>
+Josh Poimboeuf <jpoimboe@redhat.com>
+Josh Soref <jsoref@gmail.com>
+Josh Wilson <josh.wilson@fivestars.com>
+Josiah Kiehl <jkiehl@riotgames.com>
+José Tomás Albornoz <jojo@eljojo.net>
+Joyce Jang <mail@joycejang.com>
+JP <jpellerin@leapfrogonline.com>
+Julian Taylor <jtaylor.debian@googlemail.com>
+Julien Barbier <write0@gmail.com>
+Julien Bisconti <veggiemonk@users.noreply.github.com>
+Julien Bordellier <julienbordellier@gmail.com>
+Julien Dubois <julien.dubois@gmail.com>
+Julien Kassar <github@kassisol.com>
+Julien Maitrehenry <julien.maitrehenry@me.com>
+Julien Pervillé <julien.perville@perfect-memory.com>
+Julien Pivotto <roidelapluie@inuits.eu>
+Julio Guerra <julio@sqreen.com>
+Julio Montes <imc.coder@gmail.com>
+Jun-Ru Chang <jrjang@gmail.com>
+Jussi Nummelin <jussi.nummelin@gmail.com>
+Justas Brazauskas <brazauskasjustas@gmail.com>
+Justen Martin <jmart@the-coder.com>
+Justin Cormack <justin.cormack@docker.com>
+Justin Force <justin.force@gmail.com>
+Justin Menga <justin.menga@gmail.com>
+Justin Plock <jplock@users.noreply.github.com>
+Justin Simonelis <justin.p.simonelis@gmail.com>
+Justin Terry <juterry@microsoft.com>
+Justyn Temme <justyntemme@gmail.com>
+Jyrki Puttonen <jyrkiput@gmail.com>
+Jérémy Leherpeur <amenophis@leherpeur.net>
+Jérôme Petazzoni <jerome.petazzoni@docker.com>
+Jörg Thalheim <joerg@higgsboson.tk>
+K. Heller <pestophagous@gmail.com>
+Kai Blin <kai@samba.org>
+Kai Qiang Wu (Kennan) <wkq5325@gmail.com>
+Kamil Domański <kamil@domanski.co>
+Kamjar Gerami <kami.gerami@gmail.com>
+Kanstantsin Shautsou <kanstantsin.sha@gmail.com>
+Kara Alexandra <kalexandra@us.ibm.com>
+Karan Lyons <karan@karanlyons.com>
+Kareem Khazem <karkhaz@karkhaz.com>
+kargakis <kargakis@users.noreply.github.com>
+Karl Grzeszczak <karlgrz@gmail.com>
+Karol Duleba <mr.fuxi@gmail.com>
+Karthik Karanth <karanth.karthik@gmail.com>
+Karthik Nayak <karthik.188@gmail.com>
+Kasper Fabæch Brandt <poizan@poizan.dk>
+Kate Heddleston <kate.heddleston@gmail.com>
+Katie McLaughlin <katie@glasnt.com>
+Kato Kazuyoshi <kato.kazuyoshi@gmail.com>
+Katrina Owen <katrina.owen@gmail.com>
+Kawsar Saiyeed <kawsar.saiyeed@projiris.com>
+Kay Yan <kay.yan@daocloud.io>
+kayrus <kay.diam@gmail.com>
+Kazuhiro Sera <seratch@gmail.com>
+Ke Li <kel@splunk.com>
+Ke Xu <leonhartx.k@gmail.com>
+Kei Ohmura <ohmura.kei@gmail.com>
+Keith Hudgins <greenman@greenman.org>
+Keli Hu <dev@keli.hu>
+Ken Cochrane <kencochrane@gmail.com>
+Ken Herner <kherner@progress.com>
+Ken ICHIKAWA <ichikawa.ken@jp.fujitsu.com>
+Ken Reese <krrgithub@gmail.com>
+Kenfe-Mickaël Laventure <mickael.laventure@gmail.com>
+Kenjiro Nakayama <nakayamakenjiro@gmail.com>
+Kent Johnson <kentoj@gmail.com>
+Kenta Tada <Kenta.Tada@sony.com>
+Kevin "qwazerty" Houdebert <kevin.houdebert@gmail.com>
+Kevin Burke <kev@inburke.com>
+Kevin Clark <kevin.clark@gmail.com>
+Kevin Feyrer <kevin.feyrer@btinternet.com>
+Kevin J. Lynagh <kevin@keminglabs.com>
+Kevin Jing Qiu <kevin@idempotent.ca>
+Kevin Kern <kaiwentan@harmonycloud.cn>
+Kevin Menard <kevin@nirvdrum.com>
+Kevin Meredith <kevin.m.meredith@gmail.com>
+Kevin P. Kucharczyk <kevinkucharczyk@gmail.com>
+Kevin Parsons <kevpar@microsoft.com>
+Kevin Richardson <kevin@kevinrichardson.co>
+Kevin Shi <kshi@andrew.cmu.edu>
+Kevin Wallace <kevin@pentabarf.net>
+Kevin Yap <me@kevinyap.ca>
+Keyvan Fatehi <keyvanfatehi@gmail.com>
+kies <lleelm@gmail.com>
+Kim BKC Carlbacker <kim.carlbacker@gmail.com>
+Kim Eik <kim@heldig.org>
+Kimbro Staken <kstaken@kstaken.com>
+Kir Kolyshkin <kolyshkin@gmail.com>
+Kiran Gangadharan <kiran.daredevil@gmail.com>
+Kirill SIbirev <l0kix2@gmail.com>
+knappe <tyler.knappe@gmail.com>
+Kohei Tsuruta <coheyxyz@gmail.com>
+Koichi Shiraishi <k@zchee.io>
+Konrad Kleine <konrad.wilhelm.kleine@gmail.com>
+Konstantin Gribov <grossws@gmail.com>
+Konstantin L <sw.double@gmail.com>
+Konstantin Pelykh <kpelykh@zettaset.com>
+Krasi Georgiev <krasi@vip-consult.solutions>
+Krasimir Georgiev <support@vip-consult.co.uk>
+Kris-Mikael Krister <krismikael@protonmail.com>
+Kristian Haugene <kristian.haugene@capgemini.com>
+Kristina Zabunova <triara.xiii@gmail.com>
+Krystian Wojcicki <kwojcicki@sympatico.ca>
+Kun Zhang <zkazure@gmail.com>
+Kunal Kushwaha <kushwaha_kunal_v7@lab.ntt.co.jp>
+Kunal Tyagi <tyagi.kunal@live.com>
+Kyle Conroy <kyle.j.conroy@gmail.com>
+Kyle Linden <linden.kyle@gmail.com>
+Kyle Wuolle <kyle.wuolle@gmail.com>
+kyu <leehk1227@gmail.com>
+Lachlan Coote <lcoote@vmware.com>
+Lai Jiangshan <jiangshanlai@gmail.com>
+Lajos Papp <lajos.papp@sequenceiq.com>
+Lakshan Perera <lakshan@laktek.com>
+Lalatendu Mohanty <lmohanty@redhat.com>
+Lance Chen <cyen0312@gmail.com>
+Lance Kinley <lkinley@loyaltymethods.com>
+Lars Butler <Lars.Butler@gmail.com>
+Lars Kellogg-Stedman <lars@redhat.com>
+Lars R. Damerow <lars@pixar.com>
+Lars-Magnus Skog <ralphtheninja@riseup.net>
+Laszlo Meszaros <lacienator@gmail.com>
+Laura Frank <ljfrank@gmail.com>
+Laurent Erignoux <lerignoux@gmail.com>
+Laurie Voss <github@seldo.com>
+Leandro Siqueira <leandro.siqueira@gmail.com>
+Lee Chao <932819864@qq.com>
+Lee, Meng-Han <sunrisedm4@gmail.com>
+leeplay <hyeongkyu.lee@navercorp.com>
+Lei Gong <lgong@alauda.io>
+Lei Jitang <leijitang@huawei.com>
+Len Weincier <len@cloudafrica.net>
+Lennie <github@consolejunkie.net>
+Leo Gallucci <elgalu3@gmail.com>
+Leszek Kowalski <github@leszekkowalski.pl>
+Levi Blackstone <levi.blackstone@rackspace.com>
+Levi Gross <levi@levigross.com>
+Lewis Daly <lewisdaly@me.com>
+Lewis Marshall <lewis@lmars.net>
+Lewis Peckover <lew+github@lew.io>
+Li Yi <denverdino@gmail.com>
+Liam Macgillavry <liam@kumina.nl>
+Liana Lo <liana.lixia@gmail.com>
+Liang Mingqiang <mqliang.zju@gmail.com>
+Liang-Chi Hsieh <viirya@gmail.com>
+Liao Qingwei <liaoqingwei@huawei.com>
+Lifubang <lifubang@acmcoder.com>
+Lihua Tang <lhtang@alauda.io>
+Lily Guo <lily.guo@docker.com>
+limsy <seongyeol37@gmail.com>
+Lin Lu <doraalin@163.com>
+LingFaKe <lingfake@huawei.com>
+Linus Heckemann <lheckemann@twig-world.com>
+Liran Tal <liran.tal@gmail.com>
+Liron Levin <liron@twistlock.com>
+Liu Bo <bo.li.liu@oracle.com>
+Liu Hua <sdu.liu@huawei.com>
+liwenqi <vikilwq@zju.edu.cn>
+lixiaobing10051267 <li.xiaobing1@zte.com.cn>
+Liz Zhang <lizzha@microsoft.com>
+LIZAO LI <lzlarryli@gmail.com>
+Lizzie Dixon <_@lizzie.io>
+Lloyd Dewolf <foolswisdom@gmail.com>
+Lokesh Mandvekar <lsm5@fedoraproject.org>
+longliqiang88 <394564827@qq.com>
+Lorenz Leutgeb <lorenz.leutgeb@gmail.com>
+Lorenzo Fontana <fontanalorenz@gmail.com>
+Lotus Fenn <fenn.lotus@gmail.com>
+Louis Delossantos <ldelossa.ld@gmail.com>
+Louis Opter <kalessin@kalessin.fr>
+Luca Favatella <luca.favatella@erlang-solutions.com>
+Luca Marturana <lucamarturana@gmail.com>
+Luca Orlandi <luca.orlandi@gmail.com>
+Luca-Bogdan Grigorescu <Luca-Bogdan Grigorescu>
+Lucas Chan <lucas-github@lucaschan.com>
+Lucas Chi <lucas@teacherspayteachers.com>
+Lucas Molas <lmolas@fundacionsadosky.org.ar>
+Lucas Silvestre <lukas.silvestre@gmail.com>
+Luciano Mores <leslau@gmail.com>
+Luis Martínez de Bartolomé Izquierdo <lmartinez@biicode.com>
+Luiz Svoboda <luizek@gmail.com>
+Lukas Heeren <lukas-heeren@hotmail.com>
+Lukas Waslowski <cr7pt0gr4ph7@gmail.com>
+lukaspustina <lukas.pustina@centerdevice.com>
+Lukasz Zajaczkowski <Lukasz.Zajaczkowski@ts.fujitsu.com>
+Luke Marsden <me@lukemarsden.net>
+Lyn <energylyn@zju.edu.cn>
+Lynda O'Leary <lyndaoleary29@gmail.com>
+Lénaïc Huard <lhuard@amadeus.com>
+Ma Müller <mueller-ma@users.noreply.github.com>
+Ma Shimiao <mashimiao.fnst@cn.fujitsu.com>
+Mabin <bin.ma@huawei.com>
+Madhan Raj Mookkandy <MadhanRaj.Mookkandy@microsoft.com>
+Madhav Puri <madhav.puri@gmail.com>
+Madhu Venugopal <madhu@socketplane.io>
+Mageee <fangpuyi@foxmail.com>
+Mahesh Tiyyagura <tmahesh@gmail.com>
+malnick <malnick@gmail..com>
+Malte Janduda <mail@janduda.net>
+Manfred Touron <m@42.am>
+Manfred Zabarauskas <manfredas@zabarauskas.com>
+Manjunath A Kumatagi <mkumatag@in.ibm.com>
+Mansi Nahar <mmn4185@rit.edu>
+Manuel Meurer <manuel@krautcomputing.com>
+Manuel Rüger <manuel@rueg.eu>
+Manuel Woelker <github@manuel.woelker.org>
+mapk0y <mapk0y@gmail.com>
+Marc Abramowitz <marc@marc-abramowitz.com>
+Marc Kuo <kuomarc2@gmail.com>
+Marc Tamsky <mtamsky@gmail.com>
+Marcel Edmund Franke <marcel.edmund.franke@gmail.com>
+Marcelo Horacio Fortino <info@fortinux.com>
+Marcelo Salazar <chelosalazar@gmail.com>
+Marco Hennings <marco.hennings@freiheit.com>
+Marcus Cobden <mcobden@cisco.com>
+Marcus Farkas <toothlessgear@finitebox.com>
+Marcus Linke <marcus.linke@gmx.de>
+Marcus Martins <marcus@docker.com>
+Marcus Ramberg <marcus@nordaaker.com>
+Marek Goldmann <marek.goldmann@gmail.com>
+Marian Marinov <mm@yuhu.biz>
+Marianna Tessel <mtesselh@gmail.com>
+Mario Loriedo <mario.loriedo@gmail.com>
+Marius Gundersen <me@mariusgundersen.net>
+Marius Sturm <marius@graylog.com>
+Marius Voila <marius.voila@gmail.com>
+Mark Allen <mrallen1@yahoo.com>
+Mark Jeromin <mark.jeromin@sysfrog.net>
+Mark McGranaghan <mmcgrana@gmail.com>
+Mark McKinstry <mmckinst@umich.edu>
+Mark Milstein <mark@epiloque.com>
+Mark Oates <fl0yd@me.com>
+Mark Parker <godefroi@users.noreply.github.com>
+Mark West <markewest@gmail.com>
+Markan Patel <mpatel678@gmail.com>
+Marko Mikulicic <mmikulicic@gmail.com>
+Marko Tibold <marko@tibold.nl>
+Markus Fix <lispmeister@gmail.com>
+Markus Kortlang <hyp3rdino@googlemail.com>
+Martijn Dwars <ikben@martijndwars.nl>
+Martijn van Oosterhout <kleptog@svana.org>
+Martin Honermeyer <maze@strahlungsfrei.de>
+Martin Kelly <martin@surround.io>
+Martin Mosegaard Amdisen <martin.amdisen@praqma.com>
+Martin Muzatko <martin@happy-css.com>
+Martin Redmond <redmond.martin@gmail.com>
+Mary Anthony <mary.anthony@docker.com>
+Masahito Zembutsu <zembutsu@users.noreply.github.com>
+Masato Ohba <over.rye@gmail.com>
+Masayuki Morita <minamijoyo@gmail.com>
+Mason Malone <mason.malone@gmail.com>
+Mateusz Sulima <sulima.mateusz@gmail.com>
+Mathias Monnerville <mathias@monnerville.com>
+Mathieu Champlon <mathieu.champlon@docker.com>
+Mathieu Le Marec - Pasquet <kiorky@cryptelium.net>
+Mathieu Parent <math.parent@gmail.com>
+Matt Apperson <me@mattapperson.com>
+Matt Bachmann <bachmann.matt@gmail.com>
+Matt Bentley <matt.bentley@docker.com>
+Matt Haggard <haggardii@gmail.com>
+Matt Hoyle <matt@deployable.co>
+Matt McCormick <matt.mccormick@kitware.com>
+Matt Moore <mattmoor@google.com>
+Matt Richardson <matt@redgumtech.com.au>
+Matt Rickard <mrick@google.com>
+Matt Robenolt <matt@ydekproductions.com>
+Matt Schurenko <matt.schurenko@gmail.com>
+Matt Williams <mattyw@me.com>
+Matthew Heon <mheon@redhat.com>
+Matthew Lapworth <matthewl@bit-shift.net>
+Matthew Mayer <matthewkmayer@gmail.com>
+Matthew Mosesohn <raytrac3r@gmail.com>
+Matthew Mueller <mattmuelle@gmail.com>
+Matthew Riley <mattdr@google.com>
+Matthias Klumpp <matthias@tenstral.net>
+Matthias Kühnle <git.nivoc@neverbox.com>
+Matthias Rampke <mr@soundcloud.com>
+Matthieu Hauglustaine <matt.hauglustaine@gmail.com>
+Mattias Jernberg <nostrad@gmail.com>
+Mauricio Garavaglia <mauricio@medallia.com>
+mauriyouth <mauriyouth@gmail.com>
+Max Harmathy <max.harmathy@web.de>
+Max Shytikov <mshytikov@gmail.com>
+Maxim Fedchyshyn <sevmax@gmail.com>
+Maxim Ivanov <ivanov.maxim@gmail.com>
+Maxim Kulkin <mkulkin@mirantis.com>
+Maxim Treskin <zerthurd@gmail.com>
+Maxime Petazzoni <max@signalfuse.com>
+Maximiliano Maccanti <maccanti@amazon.com>
+Maxwell <csuhp007@gmail.com>
+Meaglith Ma <genedna@gmail.com>
+meejah <meejah@meejah.ca>
+Megan Kostick <mkostick@us.ibm.com>
+Mehul Kar <mehul.kar@gmail.com>
+Mei ChunTao <mei.chuntao@zte.com.cn>
+Mengdi Gao <usrgdd@gmail.com>
+Mert Yazıcıoğlu <merty@users.noreply.github.com>
+mgniu <mgniu@dataman-inc.com>
+Micah Zoltu <micah@newrelic.com>
+Michael A. Smith <michael@smith-li.com>
+Michael Bridgen <mikeb@squaremobius.net>
+Michael Brown <michael@netdirect.ca>
+Michael Chiang <mchiang@docker.com>
+Michael Crosby <michael@docker.com>
+Michael Currie <mcurrie@bruceforceresearch.com>
+Michael Friis <friism@gmail.com>
+Michael Gorsuch <gorsuch@github.com>
+Michael Grauer <michael.grauer@kitware.com>
+Michael Holzheu <holzheu@linux.vnet.ibm.com>
+Michael Hudson-Doyle <michael.hudson@canonical.com>
+Michael Huettermann <michael@huettermann.net>
+Michael Irwin <mikesir87@gmail.com>
+Michael Käufl <docker@c.michael-kaeufl.de>
+Michael Neale <michael.neale@gmail.com>
+Michael Nussbaum <michael.nussbaum@getbraintree.com>
+Michael Prokop <github@michael-prokop.at>
+Michael Scharf <github@scharf.gr>
+Michael Spetsiotis <michael_spets@hotmail.com>
+Michael Stapelberg <michael+gh@stapelberg.de>
+Michael Steinert <mike.steinert@gmail.com>
+Michael Thies <michaelthies78@gmail.com>
+Michael West <mwest@mdsol.com>
+Michael Zhao <michael.zhao@arm.com>
+Michal Fojtik <mfojtik@redhat.com>
+Michal Gebauer <mishak@mishak.net>
+Michal Jemala <michal.jemala@gmail.com>
+Michal Minář <miminar@redhat.com>
+Michal Wieczorek <wieczorek-michal@wp.pl>
+Michaël Pailloncy <mpapo.dev@gmail.com>
+Michał Czeraszkiewicz <czerasz@gmail.com>
+Michał Gryko <github@odkurzacz.org>
+Michiel de Jong <michiel@unhosted.org>
+Mickaël Fortunato <morsi.morsicus@gmail.com>
+Mickaël Remars <mickael@remars.com>
+Miguel Angel Fernández <elmendalerenda@gmail.com>
+Miguel Morales <mimoralea@gmail.com>
+Mihai Borobocea <MihaiBorob@gmail.com>
+Mihuleacc Sergiu <mihuleac.sergiu@gmail.com>
+Mike Brown <brownwm@us.ibm.com>
+Mike Bush <mpbush@gmail.com>
+Mike Casas <mkcsas0@gmail.com>
+Mike Chelen <michael.chelen@gmail.com>
+Mike Danese <mikedanese@google.com>
+Mike Dillon <mike@embody.org>
+Mike Dougherty <mike.dougherty@docker.com>
+Mike Estes <mike.estes@logos.com>
+Mike Gaffney <mike@uberu.com>
+Mike Goelzer <mike.goelzer@docker.com>
+Mike Leone <mleone896@gmail.com>
+Mike Lundy <mike@fluffypenguin.org>
+Mike MacCana <mike.maccana@gmail.com>
+Mike Naberezny <mike@naberezny.com>
+Mike Snitzer <snitzer@redhat.com>
+mikelinjie <294893458@qq.com>
+Mikhail Sobolev <mss@mawhrin.net>
+Miklos Szegedi <miklos.szegedi@cloudera.com>
+Milind Chawre <milindchawre@gmail.com>
+Miloslav Trmač <mitr@redhat.com>
+mingqing <limingqing@cyou-inc.com>
+Mingzhen Feng <fmzhen@zju.edu.cn>
+Misty Stanley-Jones <misty@docker.com>
+Mitch Capper <mitch.capper@gmail.com>
+Mizuki Urushida <z11111001011@gmail.com>
+mlarcher <github@ringabell.org>
+Mohammad Banikazemi <mb@us.ibm.com>
+Mohammad Nasirifar <farnasirim@gmail.com>
+Mohammed Aaqib Ansari <maaquib@gmail.com>
+Mohit Soni <mosoni@ebay.com>
+Moorthy RS <rsmoorthy@gmail.com>
+Morgan Bauer <mbauer@us.ibm.com>
+Morgante Pell <morgante.pell@morgante.net>
+Morgy93 <thomas@ulfertsprygoda.de>
+Morten Siebuhr <sbhr@sbhr.dk>
+Morton Fox <github@qslw.com>
+Moysés Borges <moysesb@gmail.com>
+mrfly <mr.wrfly@gmail.com>
+Mrunal Patel <mrunalp@gmail.com>
+Muayyad Alsadi <alsadi@gmail.com>
+Mustafa Akın <mustafa91@gmail.com>
+Muthukumar R <muthur@gmail.com>
+Máximo Cuadros <mcuadros@gmail.com>
+Médi-Rémi Hashim <medimatrix@users.noreply.github.com>
+Nace Oroz <orkica@gmail.com>
+Nahum Shalman <nshalman@omniti.com>
+Nakul Pathak <nakulpathak3@hotmail.com>
+Nalin Dahyabhai <nalin@redhat.com>
+Nan Monnand Deng <monnand@gmail.com>
+Naoki Orii <norii@cs.cmu.edu>
+Natalie Parker <nparker@omnifone.com>
+Natanael Copa <natanael.copa@docker.com>
+Natasha Jarus <linuxmercedes@gmail.com>
+Nate Brennand <nate.brennand@clever.com>
+Nate Eagleson <nate@nateeag.com>
+Nate Jones <nate@endot.org>
+Nathan Hsieh <hsieh.nathan@gmail.com>
+Nathan Kleyn <nathan@nathankleyn.com>
+Nathan LeClaire <nathan.leclaire@docker.com>
+Nathan McCauley <nathan.mccauley@docker.com>
+Nathan Williams <nathan@teamtreehouse.com>
+Naveed Jamil <naveed.jamil@tenpearls.com>
+Neal McBurnett <neal@mcburnett.org>
+Neil Horman <nhorman@tuxdriver.com>
+Neil Peterson <neilpeterson@outlook.com>
+Nelson Chen <crazysim@gmail.com>
+Neyazul Haque <nuhaque@gmail.com>
+Nghia Tran <nghia@google.com>
+Niall O'Higgins <niallo@unworkable.org>
+Nicholas E. Rabenau <nerab@gmx.at>
+Nick Adcock <nick.adcock@docker.com>
+Nick DeCoursin <n.decoursin@foodpanda.com>
+Nick Irvine <nfirvine@nfirvine.com>
+Nick Neisen <nwneisen@gmail.com>
+Nick Parker <nikaios@gmail.com>
+Nick Payne <nick@kurai.co.uk>
+Nick Russo <nicholasjamesrusso@gmail.com>
+Nick Stenning <nick.stenning@digital.cabinet-office.gov.uk>
+Nick Stinemates <nick@stinemates.org>
+NickrenREN <yuquan.ren@easystack.cn>
+Nicola Kabar <nicolaka@gmail.com>
+Nicolas Borboën <ponsfrilus@gmail.com>
+Nicolas De Loof <nicolas.deloof@gmail.com>
+Nicolas Dudebout <nicolas.dudebout@gatech.edu>
+Nicolas Goy <kuon@goyman.com>
+Nicolas Kaiser <nikai@nikai.net>
+Nicolas Sterchele <sterchele.nicolas@gmail.com>
+Nicolas V Castet <nvcastet@us.ibm.com>
+Nicolás Hock Isaza <nhocki@gmail.com>
+Nigel Poulton <nigelpoulton@hotmail.com>
+Nik Nyby <nikolas@gnu.org>
+Nikhil Chawla <chawlanikhil24@gmail.com>
+NikolaMandic <mn080202@gmail.com>
+Nikolas Garofil <nikolas.garofil@uantwerpen.be>
+Nikolay Edigaryev <edigaryev@gmail.com>
+Nikolay Milovanov <nmil@itransformers.net>
+Nirmal Mehta <nirmalkmehta@gmail.com>
+Nishant Totla <nishanttotla@gmail.com>
+NIWA Hideyuki <niwa.niwa@nifty.ne.jp>
+Noah Meyerhans <nmeyerha@amazon.com>
+Noah Treuhaft <noah.treuhaft@docker.com>
+NobodyOnSE <ich@sektor.selfip.com>
+noducks <onemannoducks@gmail.com>
+Nolan Darilek <nolan@thewordnerd.info>
+Noriki Nakamura <noriki.nakamura@miraclelinux.com>
+nponeccop <andy.melnikov@gmail.com>
+Nuutti Kotivuori <naked@iki.fi>
+nzwsch <hi@nzwsch.com>
+O.S. Tezer <ostezer@gmail.com>
+objectified <objectified@gmail.com>
+Odin Ugedal <odin@ugedal.com>
+Oguz Bilgic <fisyonet@gmail.com>
+Oh Jinkyun <tintypemolly@gmail.com>
+Ohad Schneider <ohadschn@users.noreply.github.com>
+ohmystack <jun.jiang02@ele.me>
+Ole Reifschneider <mail@ole-reifschneider.de>
+Oliver Neal <ItsVeryWindy@users.noreply.github.com>
+Oliver Reason <oli@overrateddev.co>
+Olivier Gambier <dmp42@users.noreply.github.com>
+Olle Jonsson <olle.jonsson@gmail.com>
+Olli Janatuinen <olli.janatuinen@gmail.com>
+Olly Pomeroy <oppomeroy@gmail.com>
+Omri Shiv <Omri.Shiv@teradata.com>
+Oriol Francès <oriolfa@gmail.com>
+Oskar Niburski <oskarniburski@gmail.com>
+Otto Kekäläinen <otto@seravo.fi>
+Ouyang Liduo <oyld0210@163.com>
+Ovidio Mallo <ovidio.mallo@gmail.com>
+Panagiotis Moustafellos <pmoust@elastic.co>
+Paolo G. Giarrusso <p.giarrusso@gmail.com>
+Pascal <pascalgn@users.noreply.github.com>
+Pascal Bach <pascal.bach@siemens.com>
+Pascal Borreli <pascal@borreli.com>
+Pascal Hartig <phartig@rdrei.net>
+Patrick Böänziger <patrick.baenziger@bsi-software.com>
+Patrick Devine <patrick.devine@docker.com>
+Patrick Hemmer <patrick.hemmer@gmail.com>
+Patrick Stapleton <github@gdi2290.com>
+Patrik Cyvoct <patrik@ptrk.io>
+pattichen <craftsbear@gmail.com>
+Paul <paul9869@gmail.com>
+paul <paul@inkling.com>
+Paul Annesley <paul@annesley.cc>
+Paul Bellamy <paul.a.bellamy@gmail.com>
+Paul Bowsher <pbowsher@globalpersonals.co.uk>
+Paul Furtado <pfurtado@hubspot.com>
+Paul Hammond <paul@paulhammond.org>
+Paul Jimenez <pj@place.org>
+Paul Kehrer <paul.l.kehrer@gmail.com>
+Paul Lietar <paul@lietar.net>
+Paul Liljenberg <liljenberg.paul@gmail.com>
+Paul Morie <pmorie@gmail.com>
+Paul Nasrat <pnasrat@gmail.com>
+Paul Weaver <pauweave@cisco.com>
+Paulo Ribeiro <paigr.io@gmail.com>
+Pavel Lobashov <ShockwaveNN@gmail.com>
+Pavel Matěja <pavel@verotel.cz>
+Pavel Pletenev <cpp.create@gmail.com>
+Pavel Pospisil <pospispa@gmail.com>
+Pavel Sutyrin <pavel.sutyrin@gmail.com>
+Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
+Pavlos Ratis <dastergon@gentoo.org>
+Pavol Vargovcik <pallly.vargovcik@gmail.com>
+Pawel Konczalski <mail@konczalski.de>
+Peeyush Gupta <gpeeyush@linux.vnet.ibm.com>
+Peggy Li <peggyli.224@gmail.com>
+Pei Su <sillyousu@gmail.com>
+Peng Tao <bergwolf@gmail.com>
+Penghan Wang <ph.wang@daocloud.io>
+Per Weijnitz <per.weijnitz@gmail.com>
+perhapszzy@sina.com <perhapszzy@sina.com>
+Peter Bourgon <peter@bourgon.org>
+Peter Braden <peterbraden@peterbraden.co.uk>
+Peter Bücker <peter.buecker@pressrelations.de>
+Peter Choi <phkchoi89@gmail.com>
+Peter Dave Hello <hsu@peterdavehello.org>
+Peter Edge <peter.edge@gmail.com>
+Peter Ericson <pdericson@gmail.com>
+Peter Esbensen <pkesbensen@gmail.com>
+Peter Jaffe <pjaffe@nevo.com>
+Peter Kang <peter@spell.run>
+Peter Malmgren <ptmalmgren@gmail.com>
+Peter Salvatore <peter@psftw.com>
+Peter Volpe <petervo@redhat.com>
+Peter Waller <p@pwaller.net>
+Petr Švihlík <svihlik.petr@gmail.com>
+Phil <underscorephil@gmail.com>
+Phil Estes <estesp@linux.vnet.ibm.com>
+Phil Spitler <pspitler@gmail.com>
+Philip Alexander Etling <paetling@gmail.com>
+Philip Monroe <phil@philmonroe.com>
+Philipp Gillé <philipp.gille@gmail.com>
+Philipp Wahala <philipp.wahala@gmail.com>
+Philipp Weissensteiner <mail@philippweissensteiner.com>
+Phillip Alexander <git@phillipalexander.io>
+phineas <phin@phineas.io>
+pidster <pid@pidster.com>
+Piergiuliano Bossi <pgbossi@gmail.com>
+Pierre <py@poujade.org>
+Pierre Carrier <pierre@meteor.com>
+Pierre Dal-Pra <dalpra.pierre@gmail.com>
+Pierre Wacrenier <pierre.wacrenier@gmail.com>
+Pierre-Alain RIVIERE <pariviere@ippon.fr>
+Piotr Bogdan <ppbogdan@gmail.com>
+pixelistik <pixelistik@users.noreply.github.com>
+Porjo <porjo38@yahoo.com.au>
+Poul Kjeldager Sørensen <pks@s-innovations.net>
+Pradeep Chhetri <pradeep@indix.com>
+Pradip Dhara <pradipd@microsoft.com>
+Prasanna Gautam <prasannagautam@gmail.com>
+Pratik Karki <prertik@outlook.com>
+Prayag Verma <prayag.verma@gmail.com>
+Priya Wadhwa <priyawadhwa@google.com>
+Projjol Banerji <probaner23@gmail.com>
+Przemek Hejman <przemyslaw.hejman@gmail.com>
+Pure White <daniel48@126.com>
+pysqz <randomq@126.com>
+Qiang Huang <h.huangqiang@huawei.com>
+Qinglan Peng <qinglanpeng@zju.edu.cn>
+qudongfang <qudongfang@gmail.com>
+Quentin Brossard <qbrossard@gmail.com>
+Quentin Perez <qperez@ocs.online.net>
+Quentin Tayssier <qtayssier@gmail.com>
+r0n22 <cameron.regan@gmail.com>
+Radostin Stoyanov <rstoyanov1@gmail.com>
+Rafal Jeczalik <rjeczalik@gmail.com>
+Rafe Colton <rafael.colton@gmail.com>
+Raghavendra K T <raghavendra.kt@linux.vnet.ibm.com>
+Raghuram Devarakonda <draghuram@gmail.com>
+Raja Sami <raja.sami@tenpearls.com>
+Rajat Pandit <rp@rajatpandit.com>
+Rajdeep Dua <dua_rajdeep@yahoo.com>
+Ralf Sippl <ralf.sippl@gmail.com>
+Ralle <spam@rasmusa.net>
+Ralph Bean <rbean@redhat.com>
+Ramkumar Ramachandra <artagnon@gmail.com>
+Ramon Brooker <rbrooker@aetherealmind.com>
+Ramon van Alteren <ramon@vanalteren.nl>
+RaviTeja Pothana <ravi-teja@live.com>
+Ray Tsang <rayt@google.com>
+ReadmeCritic <frankensteinbot@gmail.com>
+Recursive Madman <recursive.madman@gmx.de>
+Reficul <xuzhenglun@gmail.com>
+Regan McCooey <rmccooey27@aol.com>
+Remi Rampin <remirampin@gmail.com>
+Remy Suen <remy.suen@gmail.com>
+Renato Riccieri Santos Zannon <renato.riccieri@gmail.com>
+Renaud Gaubert <rgaubert@nvidia.com>
+Rhys Hiltner <rhys@twitch.tv>
+Ri Xu <xuri.me@gmail.com>
+Ricardo N Feliciano <FelicianoTech@gmail.com>
+Rich Moyse <rich@moyse.us>
+Rich Seymour <rseymour@gmail.com>
+Richard <richard.scothern@gmail.com>
+Richard Burnison <rburnison@ebay.com>
+Richard Harvey <richard@squarecows.com>
+Richard Mathie <richard.mathie@amey.co.uk>
+Richard Metzler <richard@paadee.com>
+Richard Scothern <richard.scothern@gmail.com>
+Richo Healey <richo@psych0tik.net>
+Rick Bradley <rick@users.noreply.github.com>
+Rick van de Loo <rickvandeloo@gmail.com>
+Rick Wieman <git@rickw.nl>
+Rik Nijessen <rik@keefo.nl>
+Riku Voipio <riku.voipio@linaro.org>
+Riley Guerin <rileytg.dev@gmail.com>
+Ritesh H Shukla <sritesh@vmware.com>
+Riyaz Faizullabhoy <riyaz.faizullabhoy@docker.com>
+Rob Gulewich <rgulewich@netflix.com>
+Rob Vesse <rvesse@dotnetrdf.org>
+Robert Bachmann <rb@robertbachmann.at>
+Robert Bittle <guywithnose@gmail.com>
+Robert Obryk <robryk@gmail.com>
+Robert Schneider <mail@shakeme.info>
+Robert Stern <lexandro2000@gmail.com>
+Robert Terhaar <rterhaar@atlanticdynamic.com>
+Robert Wallis <smilingrob@gmail.com>
+Robert Wang <robert@arctic.tw>
+Roberto G. Hashioka <roberto.hashioka@docker.com>
+Roberto Muñoz Fernández <robertomf@gmail.com>
+Robin Naundorf <r.naundorf@fh-muenster.de>
+Robin Schneider <ypid@riseup.net>
+Robin Speekenbrink <robin@kingsquare.nl>
+Robin Thoni <robin@rthoni.com>
+robpc <rpcann@gmail.com>
+Rodolfo Carvalho <rhcarvalho@gmail.com>
+Rodrigo Vaz <rodrigo.vaz@gmail.com>
+Roel Van Nyen <roel.vannyen@gmail.com>
+Roger Peppe <rogpeppe@gmail.com>
+Rohit Jnagal <jnagal@google.com>
+Rohit Kadam <rohit.d.kadam@gmail.com>
+Rohit Kapur <rkapur@flatiron.com>
+Rojin George <rojingeorge@huawei.com>
+Roland Huß <roland@jolokia.org>
+Roland Kammerer <roland.kammerer@linbit.com>
+Roland Moriz <rmoriz@users.noreply.github.com>
+Roma Sokolov <sokolov.r.v@gmail.com>
+Roman Dudin <katrmr@gmail.com>
+Roman Mazur <roman@balena.io>
+Roman Strashkin <roman.strashkin@gmail.com>
+Ron Smits <ron.smits@gmail.com>
+Ron Williams <ron.a.williams@gmail.com>
+Rong Gao <gaoronggood@163.com>
+Rong Zhang <rongzhang@alauda.io>
+Rongxiang Song <tinysong1226@gmail.com>
+root <docker-dummy@example.com>
+root <root@lxdebmas.marist.edu>
+root <root@ubuntu-14.04-amd64-vbox>
+root <root@webm215.cluster016.ha.ovh.net>
+Rory Hunter <roryhunter2@gmail.com>
+Rory McCune <raesene@gmail.com>
+Ross Boucher <rboucher@gmail.com>
+Rovanion Luckey <rovanion.luckey@gmail.com>
+Royce Remer <royceremer@gmail.com>
+Rozhnov Alexandr <nox73@ya.ru>
+Rudolph Gottesheim <r.gottesheim@loot.at>
+Rui Cao <ruicao@alauda.io>
+Rui Lopes <rgl@ruilopes.com>
+Ruilin Li <liruilin4@huawei.com>
+Runshen Zhu <runshen.zhu@gmail.com>
+Russ Magee <rmagee@gmail.com>
+Ryan Abrams <rdabrams@gmail.com>
+Ryan Anderson <anderson.ryanc@gmail.com>
+Ryan Aslett <github@mixologic.com>
+Ryan Belgrave <rmb1993@gmail.com>
+Ryan Detzel <ryan.detzel@gmail.com>
+Ryan Fowler <rwfowler@gmail.com>
+Ryan Liu <ryanlyy@me.com>
+Ryan McLaughlin <rmclaughlin@insidesales.com>
+Ryan O'Donnell <odonnellryanc@gmail.com>
+Ryan Seto <ryanseto@yak.net>
+Ryan Simmen <ryan.simmen@gmail.com>
+Ryan Stelly <ryan.stelly@live.com>
+Ryan Thomas <rthomas@atlassian.com>
+Ryan Trauntvein <rtrauntvein@novacoast.com>
+Ryan Wallner <ryan.wallner@clusterhq.com>
+Ryan Zhang <ryan.zhang@docker.com>
+ryancooper7 <ryan.cooper7@gmail.com>
+RyanDeng <sheldon.d1018@gmail.com>
+Ryo Nakao <nakabonne@gmail.com>
+Rémy Greinhofer <remy.greinhofer@livelovely.com>
+s. rannou <mxs@sbrk.org>
+s00318865 <sunyuan3@huawei.com>
+Sabin Basyal <sabin.basyal@gmail.com>
+Sachin Joshi <sachin_jayant_joshi@hotmail.com>
+Sagar Hani <sagarhani33@gmail.com>
+Sainath Grandhi <sainath.grandhi@intel.com>
+Sakeven Jiang <jc5930@sina.cn>
+Salahuddin Khan <salah@docker.com>
+Sally O'Malley <somalley@redhat.com>
+Sam Abed <sam.abed@gmail.com>
+Sam Alba <sam.alba@gmail.com>
+Sam Bailey <cyprix@cyprix.com.au>
+Sam J Sharpe <sam.sharpe@digital.cabinet-office.gov.uk>
+Sam Neirinck <sam@samneirinck.com>
+Sam Reis <sreis@atlassian.com>
+Sam Rijs <srijs@airpost.net>
+Sam Whited <sam@samwhited.com>
+Sambuddha Basu <sambuddhabasu1@gmail.com>
+Sami Wagiaalla <swagiaal@redhat.com>
+Samuel Andaya <samuel@andaya.net>
+Samuel Dion-Girardeau <samuel.diongirardeau@gmail.com>
+Samuel Karp <skarp@amazon.com>
+Samuel PHAN <samuel-phan@users.noreply.github.com>
+Sandeep Bansal <sabansal@microsoft.com>
+Sankar சங்கர் <sankar.curiosity@gmail.com>
+Sanket Saurav <sanketsaurav@gmail.com>
+Santhosh Manohar <santhosh@docker.com>
+sapphiredev <se.imas.kr@gmail.com>
+Sargun Dhillon <sargun@netflix.com>
+Sascha Andres <sascha.andres@outlook.com>
+Sascha Grunert <sgrunert@suse.com>
+SataQiu <qiushida@beyondcent.com>
+Satnam Singh <satnam@raintown.org>
+Satoshi Amemiya <satoshi_amemiya@voyagegroup.com>
+Satoshi Tagomori <tagomoris@gmail.com>
+Scott Bessler <scottbessler@gmail.com>
+Scott Collier <emailscottcollier@gmail.com>
+Scott Johnston <scott@docker.com>
+Scott Stamp <scottstamp851@gmail.com>
+Scott Walls <sawalls@umich.edu>
+sdreyesg <sdreyesg@gmail.com>
+Sean Christopherson <sean.j.christopherson@intel.com>
+Sean Cronin <seancron@gmail.com>
+Sean Lee <seanlee@tw.ibm.com>
+Sean McIntyre <s.mcintyre@xverba.ca>
+Sean OMeara <sean@chef.io>
+Sean P. Kane <skane@newrelic.com>
+Sean Rodman <srodman7689@gmail.com>
+Sebastiaan van Steenis <mail@superseb.nl>
+Sebastiaan van Stijn <github@gone.nl>
+Senthil Kumar Selvaraj <senthil.thecoder@gmail.com>
+Senthil Kumaran <senthil@uthcode.com>
+SeongJae Park <sj38.park@gmail.com>
+Seongyeol Lim <seongyeol37@gmail.com>
+Serge Hallyn <serge.hallyn@ubuntu.com>
+Sergey Alekseev <sergey.alekseev.minsk@gmail.com>
+Sergey Evstifeev <sergey.evstifeev@gmail.com>
+Sergii Kabashniuk <skabashnyuk@codenvy.com>
+Sergio Lopez <slp@redhat.com>
+Serhat Gülçiçek <serhat25@gmail.com>
+SeungUkLee <lsy931106@gmail.com>
+Sevki Hasirci <s@sevki.org>
+Shane Canon <scanon@lbl.gov>
+Shane da Silva <shane@dasilva.io>
+Shaun Kaasten <shaunk@gmail.com>
+shaunol <shaunol@gmail.com>
+Shawn Landden <shawn@churchofgit.com>
+Shawn Siefkas <shawn.siefkas@meredith.com>
+shawnhe <shawnhe@shawnhedeMacBook-Pro.local>
+Shayne Wang <shaynexwang@gmail.com>
+Shekhar Gulati <shekhargulati84@gmail.com>
+Sheng Yang <sheng@yasker.org>
+Shengbo Song <thomassong@tencent.com>
+Shev Yan <yandong_8212@163.com>
+Shih-Yuan Lee <fourdollars@gmail.com>
+Shijiang Wei <mountkin@gmail.com>
+Shijun Qin <qinshijun16@mails.ucas.ac.cn>
+Shishir Mahajan <shishir.mahajan@redhat.com>
+Shoubhik Bose <sbose78@gmail.com>
+Shourya Sarcar <shourya.sarcar@gmail.com>
+Shu-Wai Chow <shu-wai.chow@seattlechildrens.org>
+shuai-z <zs.broccoli@gmail.com>
+Shukui Yang <yangshukui@huawei.com>
+Shuwei Hao <haosw@cn.ibm.com>
+Sian Lerk Lau <kiawin@gmail.com>
+Sidhartha Mani <sidharthamn@gmail.com>
+sidharthamani <sid@rancher.com>
+Silas Sewell <silas@sewell.org>
+Silvan Jegen <s.jegen@gmail.com>
+Simão Reis <smnrsti@gmail.com>
+Simei He <hesimei@zju.edu.cn>
+Simon Barendse <simon.barendse@gmail.com>
+Simon Eskildsen <sirup@sirupsen.com>
+Simon Ferquel <simon.ferquel@docker.com>
+Simon Leinen <simon.leinen@gmail.com>
+Simon Menke <simon.menke@gmail.com>
+Simon Taranto <simon.taranto@gmail.com>
+Simon Vikstrom <pullreq@devsn.se>
+Sindhu S <sindhus@live.in>
+Sjoerd Langkemper <sjoerd-github@linuxonly.nl>
+skanehira <sho19921005@gmail.com>
+Solganik Alexander <solganik@gmail.com>
+Solomon Hykes <solomon@docker.com>
+Song Gao <song@gao.io>
+Soshi Katsuta <soshi.katsuta@gmail.com>
+Soulou <leo@unbekandt.eu>
+Spencer Brown <spencer@spencerbrown.org>
+Spencer Smith <robertspencersmith@gmail.com>
+Sridatta Thatipamala <sthatipamala@gmail.com>
+Sridhar Ratnakumar <sridharr@activestate.com>
+Srini Brahmaroutu <srbrahma@us.ibm.com>
+Srinivasan Srivatsan <srinivasan.srivatsan@hpe.com>
+Staf Wagemakers <staf@wagemakers.be>
+Stanislav Bondarenko <stanislav.bondarenko@gmail.com>
+Stanislav Levin <slev@altlinux.org>
+Steeve Morin <steeve.morin@gmail.com>
+Stefan Berger <stefanb@linux.vnet.ibm.com>
+Stefan J. Wernli <swernli@microsoft.com>
+Stefan Praszalowicz <stefan@greplin.com>
+Stefan S. <tronicum@user.github.com>
+Stefan Scherer <stefan.scherer@docker.com>
+Stefan Staudenmeyer <doerte@instana.com>
+Stefan Weil <sw@weilnetz.de>
+Stephan Spindler <shutefan@gmail.com>
+Stephen Benjamin <stephen@redhat.com>
+Stephen Crosby <stevecrozz@gmail.com>
+Stephen Day <stevvooe@gmail.com>
+Stephen Drake <stephen@xenolith.net>
+Stephen Rust <srust@blockbridge.com>
+Steve Desmond <steve@vtsv.ca>
+Steve Dougherty <steve@asksteved.com>
+Steve Durrheimer <s.durrheimer@gmail.com>
+Steve Francia <steve.francia@gmail.com>
+Steve Koch <stevekochscience@gmail.com>
+Steven Burgess <steven.a.burgess@hotmail.com>
+Steven Erenst <stevenerenst@gmail.com>
+Steven Hartland <steven.hartland@multiplay.co.uk>
+Steven Iveson <sjiveson@outlook.com>
+Steven Merrill <steven.merrill@gmail.com>
+Steven Richards <steven@axiomzen.co>
+Steven Taylor <steven.taylor@me.com>
+Stig Larsson <stig@larsson.dev>
+Subhajit Ghosh <isubuz.g@gmail.com>
+Sujith Haridasan <sujith.h@gmail.com>
+Sun Gengze <690388648@qq.com>
+Sun Jianbo <wonderflow.sun@gmail.com>
+Sune Keller <sune.keller@gmail.com>
+Sunny Gogoi <indiasuny000@gmail.com>
+Suryakumar Sudar <surya.trunks@gmail.com>
+Sven Dowideit <SvenDowideit@home.org.au>
+Swapnil Daingade <swapnil.daingade@gmail.com>
+Sylvain Baubeau <sbaubeau@redhat.com>
+Sylvain Bellemare <sylvain@ascribe.io>
+Sébastien <sebastien@yoozio.com>
+Sébastien HOUZÉ <cto@verylastroom.com>
+Sébastien Luttringer <seblu@seblu.net>
+Sébastien Stormacq <sebsto@users.noreply.github.com>
+Tabakhase <mail@tabakhase.com>
+Tadej Janež <tadej.j@nez.si>
+TAGOMORI Satoshi <tagomoris@gmail.com>
+tang0th <tang0th@gmx.com>
+Tangi Colin <tangicolin@gmail.com>
+Tatsuki Sugiura <sugi@nemui.org>
+Tatsushi Inagaki <e29253@jp.ibm.com>
+Taylan Isikdemir <taylani@google.com>
+Taylor Jones <monitorjbl@gmail.com>
+Ted M. Young <tedyoung@gmail.com>
+Tehmasp Chaudhri <tehmasp@gmail.com>
+Tejaswini Duggaraju <naduggar@microsoft.com>
+Tejesh Mehta <tejesh.mehta@gmail.com>
+terryding77 <550147740@qq.com>
+tgic <farmer1992@gmail.com>
+Thatcher Peskens <thatcher@docker.com>
+theadactyl <thea.lamkin@gmail.com>
+Thell 'Bo' Fowler <thell@tbfowler.name>
+Thermionix <bond711@gmail.com>
+Thijs Terlouw <thijsterlouw@gmail.com>
+Thomas Bikeev <thomas.bikeev@mac.com>
+Thomas Frössman <thomasf@jossystem.se>
+Thomas Gazagnaire <thomas@gazagnaire.org>
+Thomas Grainger <tagrain@gmail.com>
+Thomas Hansen <thomas.hansen@gmail.com>
+Thomas Leonard <thomas.leonard@docker.com>
+Thomas Léveil <thomasleveil@gmail.com>
+Thomas Orozco <thomas@orozco.fr>
+Thomas Riccardi <riccardi@systran.fr>
+Thomas Schroeter <thomas@cliqz.com>
+Thomas Sjögren <konstruktoid@users.noreply.github.com>
+Thomas Swift <tgs242@gmail.com>
+Thomas Tanaka <thomas.tanaka@oracle.com>
+Thomas Texier <sharkone@en-mousse.org>
+Ti Zhou <tizhou1986@gmail.com>
+Tianon Gravi <admwiggin@gmail.com>
+Tianyi Wang <capkurmagati@gmail.com>
+Tibor Vass <teabee89@gmail.com>
+Tiffany Jernigan <tiffany.f.j@gmail.com>
+Tiffany Low <tiffany@box.com>
+Till Wegmüller <toasterson@gmail.com>
+Tim <elatllat@gmail.com>
+Tim Bart <tim@fewagainstmany.com>
+Tim Bosse <taim@bosboot.org>
+Tim Dettrick <t.dettrick@uq.edu.au>
+Tim Düsterhus <tim@bastelstu.be>
+Tim Hockin <thockin@google.com>
+Tim Potter <tpot@hpe.com>
+Tim Ruffles <oi@truffles.me.uk>
+Tim Smith <timbot@google.com>
+Tim Terhorst <mynamewastaken+git@gmail.com>
+Tim Wang <timwangdev@gmail.com>
+Tim Waugh <twaugh@redhat.com>
+Tim Wraight <tim.wraight@tangentlabs.co.uk>
+Tim Zju <21651152@zju.edu.cn>
+timfeirg <kkcocogogo@gmail.com>
+Timothy Hobbs <timothyhobbs@seznam.cz>
+tjwebb123 <tjwebb123@users.noreply.github.com>
+tobe <tobegit3hub@gmail.com>
+Tobias Bieniek <Tobias.Bieniek@gmx.de>
+Tobias Bradtke <webwurst@gmail.com>
+Tobias Gesellchen <tobias@gesellix.de>
+Tobias Klauser <tklauser@distanz.ch>
+Tobias Munk <schmunk@usrbin.de>
+Tobias Schmidt <ts@soundcloud.com>
+Tobias Schwab <tobias.schwab@dynport.de>
+Todd Crane <todd@toddcrane.com>
+Todd Lunter <tlunter@gmail.com>
+Todd Whiteman <todd.whiteman@joyent.com>
+Toli Kuznets <toli@docker.com>
+Tom Barlow <tomwbarlow@gmail.com>
+Tom Booth <tombooth@gmail.com>
+Tom Denham <tom@tomdee.co.uk>
+Tom Fotherby <tom+github@peopleperhour.com>
+Tom Howe <tom.howe@enstratius.com>
+Tom Hulihan <hulihan.tom159@gmail.com>
+Tom Maaswinkel <tom.maaswinkel@12wiki.eu>
+Tom Sweeney <tsweeney@redhat.com>
+Tom Wilkie <tom.wilkie@gmail.com>
+Tom X. Tobin <tomxtobin@tomxtobin.com>
+Tomas Tomecek <ttomecek@redhat.com>
+Tomasz Kopczynski <tomek@kopczynski.net.pl>
+Tomasz Lipinski <tlipinski@users.noreply.github.com>
+Tomasz Nurkiewicz <nurkiewicz@gmail.com>
+Tommaso Visconti <tommaso.visconti@gmail.com>
+Tomáš Hrčka <thrcka@redhat.com>
+Tonny Xu <tonny.xu@gmail.com>
+Tony Abboud <tdabboud@hotmail.com>
+Tony Daws <tony@daws.ca>
+Tony Miller <mcfiredrill@gmail.com>
+toogley <toogley@mailbox.org>
+Torstein Husebø <torstein@huseboe.net>
+Tõnis Tiigi <tonistiigi@gmail.com>
+Trace Andreason <tandreason@gmail.com>
+tracylihui <793912329@qq.com>
+Trapier Marshall <trapier.marshall@docker.com>
+Travis Cline <travis.cline@gmail.com>
+Travis Thieman <travis.thieman@gmail.com>
+Trent Ogren <tedwardo2@gmail.com>
+Trevor <trevinwoodstock@gmail.com>
+Trevor Pounds <trevor.pounds@gmail.com>
+Trevor Sullivan <pcgeek86@gmail.com>
+Trishna Guha <trishnaguha17@gmail.com>
+Tristan Carel <tristan@cogniteev.com>
+Troy Denton <trdenton@gmail.com>
+Tycho Andersen <tycho@docker.com>
+Tyler Brock <tyler.brock@gmail.com>
+Tyler Brown <tylers.pile@gmail.com>
+Tzu-Jung Lee <roylee17@gmail.com>
+uhayate <uhayate.gong@daocloud.io>
+Ulysse Carion <ulyssecarion@gmail.com>
+Umesh Yadav <umesh4257@gmail.com>
+Utz Bacher <utz.bacher@de.ibm.com>
+vagrant <vagrant@ubuntu-14.04-amd64-vbox>
+Vaidas Jablonskis <jablonskis@gmail.com>
+vanderliang <lansheng@meili-inc.com>
+Velko Ivanov <vivanov@deeperplane.com>
+Veres Lajos <vlajos@gmail.com>
+Victor Algaze <valgaze@gmail.com>
+Victor Coisne <victor.coisne@dotcloud.com>
+Victor Costan <costan@gmail.com>
+Victor I. Wood <viw@t2am.com>
+Victor Lyuboslavsky <victor@victoreda.com>
+Victor Marmol <vmarmol@google.com>
+Victor Palma <palma.victor@gmail.com>
+Victor Vieux <victor.vieux@docker.com>
+Victoria Bialas <victoria.bialas@docker.com>
+Vijaya Kumar K <vijayak@caviumnetworks.com>
+Vikram bir Singh <vsingh@mirantis.com>
+Viktor Stanchev <me@viktorstanchev.com>
+Viktor Vojnovski <viktor.vojnovski@amadeus.com>
+VinayRaghavanKS <raghavan.vinay@gmail.com>
+Vincent Batts <vbatts@redhat.com>
+Vincent Bernat <Vincent.Bernat@exoscale.ch>
+Vincent Boulineau <vincent.boulineau@datadoghq.com>
+Vincent Demeester <vincent.demeester@docker.com>
+Vincent Giersch <vincent.giersch@ovh.net>
+Vincent Mayers <vincent.mayers@inbloom.org>
+Vincent Woo <me@vincentwoo.com>
+Vinod Kulkarni <vinod.kulkarni@gmail.com>
+Vishal Doshi <vishal.doshi@gmail.com>
+Vishnu Kannan <vishnuk@google.com>
+Vitaly Ostrosablin <vostrosablin@virtuozzo.com>
+Vitor Monteiro <vmrmonteiro@gmail.com>
+Vivek Agarwal <me@vivek.im>
+Vivek Dasgupta <vdasgupt@redhat.com>
+Vivek Goyal <vgoyal@redhat.com>
+Vladimir Bulyga <xx@ccxx.cc>
+Vladimir Kirillov <proger@wilab.org.ua>
+Vladimir Pouzanov <farcaller@google.com>
+Vladimir Rutsky <altsysrq@gmail.com>
+Vladimir Varankin <nek.narqo+git@gmail.com>
+VladimirAus <v_roudakov@yahoo.com>
+Vlastimil Zeman <vlastimil.zeman@diffblue.com>
+Vojtech Vitek (V-Teq) <vvitek@redhat.com>
+waitingkuo <waitingkuo0527@gmail.com>
+Walter Leibbrandt <github@wrl.co.za>
+Walter Stanish <walter@pratyeka.org>
+Wang Chao <chao.wang@ucloud.cn>
+Wang Guoliang <liangcszzu@163.com>
+Wang Jie <wangjie5@chinaskycloud.com>
+Wang Long <long.wanglong@huawei.com>
+Wang Ping <present.wp@icloud.com>
+Wang Xing <hzwangxing@corp.netease.com>
+Wang Yuexiao <wang.yuexiao@zte.com.cn>
+Wang Yumu <37442693@qq.com>
+wanghuaiqing <wanghuaiqing@loongson.cn>
+Ward Vandewege <ward@jhvc.com>
+WarheadsSE <max@warheads.net>
+Wassim Dhif <wassimdhif@gmail.com>
+Wayne Chang <wayne@neverfear.org>
+Wayne Song <wsong@docker.com>
+Weerasak Chongnguluam <singpor@gmail.com>
+Wei Fu <fuweid89@gmail.com>
+Wei Wu <wuwei4455@gmail.com>
+Wei-Ting Kuo <waitingkuo0527@gmail.com>
+weipeng <weipeng@tuscloud.io>
+weiyan <weiyan3@huawei.com>
+Weiyang Zhu <cnresonant@gmail.com>
+Wen Cheng Ma <wenchma@cn.ibm.com>
+Wendel Fleming <wfleming@usc.edu>
+Wenjun Tang <tangwj2@lenovo.com>
+Wenkai Yin <yinw@vmware.com>
+wenlxie <wenlxie@ebay.com>
+Wentao Zhang <zhangwentao234@huawei.com>
+Wenxuan Zhao <viz@linux.com>
+Wenyu You <21551128@zju.edu.cn>
+Wenzhi Liang <wenzhi.liang@gmail.com>
+Wes Morgan <cap10morgan@gmail.com>
+Wewang Xiaorenfine <wang.xiaoren@zte.com.cn>
+Wiktor Kwapisiewicz <wiktor@metacode.biz>
+Will Dietz <w@wdtz.org>
+Will Rouesnel <w.rouesnel@gmail.com>
+Will Weaver <monkey@buildingbananas.com>
+willhf <willhf@gmail.com>
+William Delanoue <william.delanoue@gmail.com>
+William Henry <whenry@redhat.com>
+William Hubbs <w.d.hubbs@gmail.com>
+William Martin <wmartin@pivotal.io>
+William Riancho <wr.wllm@gmail.com>
+William Thurston <thurstw@amazon.com>
+Wilson Júnior <wilsonpjunior@gmail.com>
+Wing-Kam Wong <wingkwong.code@gmail.com>
+WiseTrem <shepelyov.g@gmail.com>
+Wolfgang Powisch <powo@powo.priv.at>
+Wonjun Kim <wonjun.kim@navercorp.com>
+xamyzhao <x.amy.zhao@gmail.com>
+Xian Chaobo <xianchaobo@huawei.com>
+Xianglin Gao <xlgao@zju.edu.cn>
+Xianlu Bird <xianlubird@gmail.com>
+Xiao YongBiao <xyb4638@gmail.com>
+XiaoBing Jiang <s7v7nislands@gmail.com>
+Xiaodong Liu <liuxiaodong@loongson.cn>
+Xiaodong Zhang <a4012017@sina.com>
+Xiaoxi He <xxhe@alauda.io>
+Xiaoxu Chen <chenxiaoxu14@otcaix.iscas.ac.cn>
+Xiaoyu Zhang <zhang.xiaoyu33@zte.com.cn>
+xichengliudui <1693291525@qq.com>
+xiekeyang <xiekeyang@huawei.com>
+Ximo Guanter Gonzálbez <joaquin.guantergonzalbez@telefonica.com>
+Xinbo Weng <xihuanbo_0521@zju.edu.cn>
+Xinfeng Liu <xinfeng.liu@gmail.com>
+Xinzi Zhou <imdreamrunner@gmail.com>
+Xiuming Chen <cc@cxm.cc>
+Xuecong Liao <satorulogic@gmail.com>
+xuzhaokui <cynicholas@gmail.com>
+Yadnyawalkya Tale <ytale@redhat.com>
+Yahya <ya7yaz@gmail.com>
+YAMADA Tsuyoshi <tyamada@minimum2scp.org>
+Yamasaki Masahide <masahide.y@gmail.com>
+Yan Feng <yanfeng2@huawei.com>
+Yang Bai <hamo.by@gmail.com>
+Yang Pengfei <yangpengfei4@huawei.com>
+yangchenliang <yangchenliang@huawei.com>
+Yanqiang Miao <miao.yanqiang@zte.com.cn>
+Yao Zaiyong <yaozaiyong@hotmail.com>
+Yash Murty <yashmurty@gmail.com>
+Yassine Tijani <yasstij11@gmail.com>
+Yasunori Mahata <nori@mahata.net>
+Yazhong Liu <yorkiefixer@gmail.com>
+Yestin Sun <sunyi0804@gmail.com>
+Yi EungJun <eungjun.yi@navercorp.com>
+Yibai Zhang <xm1994@gmail.com>
+Yihang Ho <hoyihang5@gmail.com>
+Ying Li <ying.li@docker.com>
+Yohei Ueda <yohei@jp.ibm.com>
+Yong Tang <yong.tang.github@outlook.com>
+Yongxin Li <yxli@alauda.io>
+Yongzhi Pan <panyongzhi@gmail.com>
+Yosef Fertel <yfertel@gmail.com>
+You-Sheng Yang (楊有勝) <vicamo@gmail.com>
+youcai <omegacoleman@gmail.com>
+Youcef YEKHLEF <yyekhlef@gmail.com>
+Yu Changchun <yuchangchun1@huawei.com>
+Yu Chengxia <yuchengxia@huawei.com>
+Yu Peng <yu.peng36@zte.com.cn>
+Yu-Ju Hong <yjhong@google.com>
+Yuan Sun <sunyuan3@huawei.com>
+Yuanhong Peng <pengyuanhong@huawei.com>
+Yue Zhang <zy675793960@yeah.net>
+Yuhao Fang <fangyuhao@gmail.com>
+Yuichiro Kaneko <spiketeika@gmail.com>
+Yunxiang Huang <hyxqshk@vip.qq.com>
+Yurii Rashkovskii <yrashk@gmail.com>
+Yusuf Tarık Günaydın <yusuf_tarik@hotmail.com>
+Yves Junqueira <yves.junqueira@gmail.com>
+Zac Dover <zdover@redhat.com>
+Zach Borboa <zachborboa@gmail.com>
+Zachary Jaffee <zjaffee@us.ibm.com>
+Zain Memon <zain@inzain.net>
+Zaiste! <oh@zaiste.net>
+Zane DeGraffenried <zane.deg@gmail.com>
+Zefan Li <lizefan@huawei.com>
+Zen Lin(Zhinan Lin) <linzhinan@huawei.com>
+Zhang Kun <zkazure@gmail.com>
+Zhang Wei <zhangwei555@huawei.com>
+Zhang Wentao <zhangwentao234@huawei.com>
+ZhangHang <stevezhang2014@gmail.com>
+zhangxianwei <xianwei.zw@alibaba-inc.com>
+Zhenan Ye <21551168@zju.edu.cn>
+zhenghenghuo <zhenghenghuo@zju.edu.cn>
+Zhenhai Gao <gaozh1988@live.com>
+Zhenkun Bi <bi.zhenkun@zte.com.cn>
+zhipengzuo <zuozhipeng@baidu.com>
+Zhou Hao <zhouhao@cn.fujitsu.com>
+Zhoulin Xie <zhoulin.xie@daocloud.io>
+Zhu Guihua <zhugh.fnst@cn.fujitsu.com>
+Zhu Kunjia <zhu.kunjia@zte.com.cn>
+Zhuoyun Wei <wzyboy@wzyboy.org>
+Ziheng Liu <lzhfromustc@gmail.com>
+Zilin Du <zilin.du@gmail.com>
+zimbatm <zimbatm@zimbatm.com>
+Ziming Dong <bnudzm@foxmail.com>
+ZJUshuaizhou <21551191@zju.edu.cn>
+zmarouf <zeid.marouf@gmail.com>
+Zoltan Tombol <zoltan.tombol@gmail.com>
+Zou Yu <zouyu7@huawei.com>
+zqh <zqhxuyuan@gmail.com>
+Zuhayr Elahi <zuhayr.elahi@docker.com>
+Zunayed Ali <zunayed@gmail.com>
+Álex González <agonzalezro@gmail.com>
+Álvaro Lázaro <alvaro.lazaro.g@gmail.com>
+Átila Camurça Alves <camurca.home@gmail.com>
+尹吉峰 <jifeng.yin@gmail.com>
+屈骏 <qujun@tiduyun.com>
+徐俊杰 <paco.xu@daocloud.io>
+慕陶 <jihui.xjh@alibaba-inc.com>
+搏通 <yufeng.pyf@alibaba-inc.com>
+黄艳红00139573 <huang.yanhong@zte.com.cn>
diff --git a/vendor/github.com/moby/moby/LICENSE b/vendor/github.com/moby/moby/LICENSE
new file mode 100644
index 000000000..6d8d58fb6
--- /dev/null
+++ b/vendor/github.com/moby/moby/LICENSE
@@ -0,0 +1,191 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        https://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   Copyright 2013-2018 Docker, Inc.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       https://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/vendor/github.com/moby/moby/NOTICE b/vendor/github.com/moby/moby/NOTICE
new file mode 100644
index 000000000..58b19b6d1
--- /dev/null
+++ b/vendor/github.com/moby/moby/NOTICE
@@ -0,0 +1,19 @@
+Docker
+Copyright 2012-2017 Docker, Inc.
+
+This product includes software developed at Docker, Inc. (https://www.docker.com).
+
+This product contains software (https://github.com/creack/pty) developed
+by Keith Rarick, licensed under the MIT License.
+
+The following is courtesy of our legal counsel:
+
+
+Use and transfer of Docker may be subject to certain restrictions by the
+United States and other governments.
+It is your responsibility to ensure that your use and/or transfer does not
+violate applicable laws.
+
+For more information, please see https://www.bis.doc.gov
+
+See also https://www.apache.org/dev/crypto.html and/or seek legal counsel.
diff --git a/vendor/github.com/moby/moby/pkg/stringid/README.md b/vendor/github.com/moby/moby/pkg/stringid/README.md
new file mode 100644
index 000000000..37a5098fd
--- /dev/null
+++ b/vendor/github.com/moby/moby/pkg/stringid/README.md
@@ -0,0 +1,1 @@
+This package provides helper functions for dealing with string identifiers
diff --git a/vendor/github.com/moby/moby/pkg/stringid/stringid.go b/vendor/github.com/moby/moby/pkg/stringid/stringid.go
new file mode 100644
index 000000000..5fe071d62
--- /dev/null
+++ b/vendor/github.com/moby/moby/pkg/stringid/stringid.go
@@ -0,0 +1,63 @@
+// Package stringid provides helper functions for dealing with string identifiers
+package stringid // import "github.com/docker/docker/pkg/stringid"
+
+import (
+	"crypto/rand"
+	"encoding/hex"
+	"fmt"
+	"regexp"
+	"strconv"
+	"strings"
+)
+
+const shortLen = 12
+
+var (
+	validShortID = regexp.MustCompile("^[a-f0-9]{12}$")
+	validHex     = regexp.MustCompile(`^[a-f0-9]{64}$`)
+)
+
+// IsShortID determines if an arbitrary string *looks like* a short ID.
+func IsShortID(id string) bool {
+	return validShortID.MatchString(id)
+}
+
+// TruncateID returns a shorthand version of a string identifier for convenience.
+// A collision with other shorthands is very unlikely, but possible.
+// In case of a collision a lookup with TruncIndex.Get() will fail, and the caller
+// will need to use a longer prefix, or the full-length Id.
+func TruncateID(id string) string {
+	if i := strings.IndexRune(id, ':'); i >= 0 {
+		id = id[i+1:]
+	}
+	if len(id) > shortLen {
+		id = id[:shortLen]
+	}
+	return id
+}
+
+// GenerateRandomID returns a unique id.
+func GenerateRandomID() string {
+	b := make([]byte, 32)
+	for {
+		if _, err := rand.Read(b); err != nil {
+			panic(err) // This shouldn't happen
+		}
+		id := hex.EncodeToString(b)
+		// if we try to parse the truncated for as an int and we don't have
+		// an error then the value is all numeric and causes issues when
+		// used as a hostname. ref #3869
+		if _, err := strconv.ParseInt(TruncateID(id), 10, 64); err == nil {
+			continue
+		}
+		return id
+	}
+}
+
+// ValidateID checks whether an ID string is a valid image ID.
+func ValidateID(id string) error {
+	if ok := validHex.MatchString(id); !ok {
+		return fmt.Errorf("image ID %q is invalid", id)
+	}
+	return nil
+}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index a7c006af7..70a9e697f 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -277,6 +277,9 @@ github.com/mitchellh/mapstructure
 # github.com/mitchellh/reflectwalk v1.0.2
 ## explicit
 github.com/mitchellh/reflectwalk
+# github.com/moby/moby v20.10.21+incompatible
+## explicit
+github.com/moby/moby/pkg/stringid
 # github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd
 ## explicit
 github.com/modern-go/concurrent


Test patch:
diff --git a/pkg/podmanager/pod_manager_test.go b/pkg/podmanager/pod_manager_test.go
index f8eceffdb..afa8caf7f 100644
--- a/pkg/podmanager/pod_manager_test.go
+++ b/pkg/podmanager/pod_manager_test.go
@@ -320,8 +320,6 @@ var _ = Describe("PodManager", Label("pod_manager_test"), func() {
 			})
 		})
 
-		PDescribe("GetPodTopController", func() {
-
-		})
+		PDescribe("GetPodTopController", func() {})
 	})
 })
diff --git a/pkg/podmanager/utils_test.go b/pkg/podmanager/utils_test.go
index 59d1f03f4..01d8f4e98 100644
--- a/pkg/podmanager/utils_test.go
+++ b/pkg/podmanager/utils_test.go
@@ -15,24 +15,24 @@ import (
 )
 
 var _ = Describe("PodManager utils", Label("pod_manager_utils_test"), func() {
-	Describe("Test CheckPodStatus", func() {
-		var podT *corev1.Pod
-
-		BeforeEach(func() {
-			podT = &corev1.Pod{
-				TypeMeta: metav1.TypeMeta{
-					Kind:       "Pod",
-					APIVersion: corev1.SchemeGroupVersion.String(),
-				},
-				ObjectMeta: metav1.ObjectMeta{
-					Name:      "pod",
-					Namespace: "default",
-				},
-				Spec:   corev1.PodSpec{},
-				Status: corev1.PodStatus{},
-			}
-		})
+	var podT *corev1.Pod
+
+	BeforeEach(func() {
+		podT = &corev1.Pod{
+			TypeMeta: metav1.TypeMeta{
+				Kind:       "Pod",
+				APIVersion: corev1.SchemeGroupVersion.String(),
+			},
+			ObjectMeta: metav1.ObjectMeta{
+				Name:      "pod",
+				Namespace: "default",
+			},
+			Spec:   corev1.PodSpec{},
+			Status: corev1.PodStatus{},
+		}
+	})
 
+	Describe("Test CheckPodStatus", func() {
 		It("inputs nil Pod", func() {
 			status, allocatable := podmanager.CheckPodStatus(nil)
 			Expect(status).To(Equal(constant.PodUnknown))
diff --git a/pkg/workloadendpointmanager/utils_test.go b/pkg/workloadendpointmanager/utils_test.go
new file mode 100644
index 000000000..4cca688f2
--- /dev/null
+++ b/pkg/workloadendpointmanager/utils_test.go
@@ -0,0 +1,134 @@
+// Copyright 2019 The Kubernetes Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package workloadendpointmanager_test
+
+import (
+	"fmt"
+
+	"github.com/moby/moby/pkg/stringid"
+	. "github.com/onsi/ginkgo/v2"
+	. "github.com/onsi/gomega"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/utils/pointer"
+
+	"github.com/spidernet-io/spiderpool/pkg/constant"
+	spiderpoolv1 "github.com/spidernet-io/spiderpool/pkg/k8s/apis/spiderpool.spidernet.io/v1"
+	"github.com/spidernet-io/spiderpool/pkg/workloadendpointmanager"
+)
+
+var _ = Describe("WorkloadEndpointManager utils", Label("workloadendpoint_manager_utils_test"), func() {
+	var endpointT *spiderpoolv1.SpiderEndpoint
+
+	BeforeEach(func() {
+		endpointT = &spiderpoolv1.SpiderEndpoint{
+			TypeMeta: metav1.TypeMeta{
+				Kind:       constant.SpiderEndpointKind,
+				APIVersion: fmt.Sprintf("%s/%s", constant.SpiderpoolAPIGroup, constant.SpiderpoolAPIVersionV1),
+			},
+			ObjectMeta: metav1.ObjectMeta{
+				Name:      "endpoint",
+				Namespace: "default",
+			},
+			Status: spiderpoolv1.WorkloadEndpointStatus{},
+		}
+	})
+
+	Describe("Test RetrieveIPAllocation", func() {
+		var nic1, nic2 string
+		var containerID, historyContainerID string
+		var allocationT, historyAllocationT *spiderpoolv1.PodIPAllocation
+
+		BeforeEach(func() {
+			nic1 = "eth0"
+			nic2 = "net1"
+
+			containerID = stringid.GenerateRandomID()
+			allocationT = &spiderpoolv1.PodIPAllocation{
+				ContainerID: containerID,
+				IPs: []spiderpoolv1.IPAllocationDetail{
+					{
+						NIC:      nic1,
+						Vlan:     pointer.Int64(0),
+						IPv4:     pointer.String("172.18.40.10/24"),
+						IPv4Pool: pointer.String("ipv4-ippool-1"),
+					},
+					{
+						NIC:      nic2,
+						Vlan:     pointer.Int64(0),
+						IPv4:     pointer.String("192.168.40.9/24"),
+						IPv4Pool: pointer.String("ipv4-ippool-2"),
+					},
+				},
+			}
+
+			historyContainerID = stringid.GenerateRandomID()
+			historyAllocationT = &spiderpoolv1.PodIPAllocation{
+				ContainerID: historyContainerID,
+				IPs: []spiderpoolv1.IPAllocationDetail{
+					{
+						NIC:      nic1,
+						Vlan:     pointer.Int64(0),
+						IPv4:     pointer.String("172.18.40.5/24"),
+						IPv4Pool: pointer.String("ipv4-ippool-1"),
+					},
+					{
+						NIC:      nic2,
+						Vlan:     pointer.Int64(0),
+						IPv4:     pointer.String("192.168.40.6/24"),
+						IPv4Pool: pointer.String("ipv4-ippool-2"),
+					},
+				},
+			}
+		})
+
+		It("inputs nil Endpoint", func() {
+			allocation, currently := workloadendpointmanager.RetrieveIPAllocation(containerID, nic2, true, nil)
+			Expect(allocation).To(BeNil())
+			Expect(currently).To(BeFalse())
+		})
+
+		It("retrieves the IP allocation but the current record is nil", func() {
+			allocation, currently := workloadendpointmanager.RetrieveIPAllocation(containerID, nic2, true, endpointT)
+			Expect(allocation).To(BeNil())
+			Expect(currently).To(BeFalse())
+		})
+
+		It("retrieves non-existent current IP allocation", func() {
+			endpointT.Status.Current = allocationT
+			endpointT.Status.History = append(endpointT.Status.History, *allocationT, *historyAllocationT)
+
+			allocation, currently := workloadendpointmanager.RetrieveIPAllocation(stringid.GenerateRandomID(), nic2, true, endpointT)
+			Expect(allocation).To(BeNil())
+			Expect(currently).To(BeFalse())
+		})
+
+		It("retrieves the current IP allocation", func() {
+			endpointT.Status.Current = allocationT
+			endpointT.Status.History = append(endpointT.Status.History, *allocationT, *historyAllocationT)
+
+			allocation, currently := workloadendpointmanager.RetrieveIPAllocation(containerID, nic2, false, endpointT)
+			Expect(allocation).To(Equal(allocationT))
+			Expect(currently).To(BeTrue())
+
+			allocation, currently = workloadendpointmanager.RetrieveIPAllocation(containerID, nic2, true, endpointT)
+			Expect(allocation).To(Equal(allocationT))
+			Expect(currently).To(BeTrue())
+		})
+
+		It("retrieves the historical IP allocation", func() {
+			endpointT.Status.Current = allocationT
+			endpointT.Status.History = append(endpointT.Status.History, *allocationT, *historyAllocationT)
+
+			allocation, currently := workloadendpointmanager.RetrieveIPAllocation(historyContainerID, nic2, false, endpointT)
+			Expect(allocation).To(BeNil())
+			Expect(currently).To(BeFalse())
+
+			allocation, currently = workloadendpointmanager.RetrieveIPAllocation(historyContainerID, nic2, true, endpointT)
+			Expect(allocation).To(Equal(historyAllocationT))
+			Expect(currently).To(BeFalse())
+		})
+	})
+
+	PDescribe("Test ListAllHistoricalIPs", func() {})
+})
diff --git a/pkg/workloadendpointmanager/workloadendpoint_manager_suite_test.go b/pkg/workloadendpointmanager/workloadendpoint_manager_suite_test.go
new file mode 100644
index 000000000..f157ee896
--- /dev/null
+++ b/pkg/workloadendpointmanager/workloadendpoint_manager_suite_test.go
@@ -0,0 +1,63 @@
+// Copyright 2019 The Kubernetes Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package workloadendpointmanager_test
+
+import (
+	"testing"
+
+	"github.com/golang/mock/gomock"
+	. "github.com/onsi/ginkgo/v2"
+	. "github.com/onsi/gomega"
+	corev1 "k8s.io/api/core/v1"
+	"k8s.io/apimachinery/pkg/runtime"
+	"k8s.io/utils/pointer"
+	"sigs.k8s.io/controller-runtime/pkg/client"
+	"sigs.k8s.io/controller-runtime/pkg/client/fake"
+
+	spiderpoolv1 "github.com/spidernet-io/spiderpool/pkg/k8s/apis/spiderpool.spidernet.io/v1"
+	podmock "github.com/spidernet-io/spiderpool/pkg/podmanager/mock"
+	"github.com/spidernet-io/spiderpool/pkg/workloadendpointmanager"
+)
+
+var mockCtrl *gomock.Controller
+var mockPodManager *podmock.MockPodManager
+
+var scheme *runtime.Scheme
+var fakeClient client.Client
+var endpointManager workloadendpointmanager.WorkloadEndpointManager
+var endpointWebhook *workloadendpointmanager.WorkloadEndpointWebhook
+
+func TestWorkloadEndpointManager(t *testing.T) {
+	mockCtrl = gomock.NewController(t)
+	defer mockCtrl.Finish()
+
+	RegisterFailHandler(Fail)
+	RunSpecs(t, "WorkloadEndpointManager Suite", Label("workloadendpointmanager", "unitest"))
+}
+
+var _ = BeforeSuite(func() {
+	scheme = runtime.NewScheme()
+	err := spiderpoolv1.AddToScheme(scheme)
+	Expect(err).NotTo(HaveOccurred())
+
+	err = corev1.AddToScheme(scheme)
+	Expect(err).NotTo(HaveOccurred())
+
+	fakeClient = fake.NewClientBuilder().
+		WithScheme(scheme).
+		Build()
+
+	mockPodManager = podmock.NewMockPodManager(mockCtrl)
+	endpointManager, err = workloadendpointmanager.NewWorkloadEndpointManager(
+		workloadendpointmanager.EndpointManagerConfig{
+			MaxConflictRetries: 1,
+			MaxHistoryRecords:  pointer.Int(1),
+		},
+		fakeClient,
+		mockPodManager,
+	)
+	Expect(err).NotTo(HaveOccurred())
+
+	endpointWebhook = &workloadendpointmanager.WorkloadEndpointWebhook{}
+})
diff --git a/pkg/workloadendpointmanager/workloadendpoint_manager_test.go b/pkg/workloadendpointmanager/workloadendpoint_manager_test.go
new file mode 100644
index 000000000..b920a4914
--- /dev/null
+++ b/pkg/workloadendpointmanager/workloadendpoint_manager_test.go
@@ -0,0 +1,801 @@
+// Copyright 2019 The Kubernetes Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package workloadendpointmanager_test
+
+import (
+	"context"
+	"fmt"
+	"sync/atomic"
+	"time"
+
+	"github.com/agiledragon/gomonkey/v2"
+	"github.com/golang/mock/gomock"
+	"github.com/moby/moby/pkg/stringid"
+	. "github.com/onsi/ginkgo/v2"
+	. "github.com/onsi/gomega"
+	appsv1 "k8s.io/api/apps/v1"
+	corev1 "k8s.io/api/core/v1"
+	apierrors "k8s.io/apimachinery/pkg/api/errors"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/runtime/schema"
+	"k8s.io/apimachinery/pkg/types"
+	"k8s.io/apimachinery/pkg/util/uuid"
+	"k8s.io/utils/pointer"
+	"sigs.k8s.io/controller-runtime/pkg/client"
+	"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
+
+	"github.com/spidernet-io/spiderpool/pkg/constant"
+	spiderpoolv1 "github.com/spidernet-io/spiderpool/pkg/k8s/apis/spiderpool.spidernet.io/v1"
+	"github.com/spidernet-io/spiderpool/pkg/workloadendpointmanager"
+)
+
+var _ = Describe("WorkloadEndpointManager", Label("workloadendpoint_manager_test"), func() {
+	Describe("New WorkloadEndpointManager", func() {
+		It("sets default config", func() {
+			manager, err := workloadendpointmanager.NewWorkloadEndpointManager(
+				workloadendpointmanager.EndpointManagerConfig{},
+				fakeClient,
+				mockPodManager,
+			)
+			Expect(err).NotTo(HaveOccurred())
+			Expect(manager).NotTo(BeNil())
+		})
+
+		It("inputs nil client", func() {
+			manager, err := workloadendpointmanager.NewWorkloadEndpointManager(
+				workloadendpointmanager.EndpointManagerConfig{},
+				nil,
+				mockPodManager,
+			)
+			Expect(err).To(MatchError(constant.ErrMissingRequiredParam))
+			Expect(manager).To(BeNil())
+		})
+
+		It("inputs nil Pod manager", func() {
+			manager, err := workloadendpointmanager.NewWorkloadEndpointManager(
+				workloadendpointmanager.EndpointManagerConfig{},
+				fakeClient,
+				nil,
+			)
+			Expect(err).To(MatchError(constant.ErrMissingRequiredParam))
+			Expect(manager).To(BeNil())
+		})
+	})
+
+	Describe("Test WorkloadEndpointManager's method", func() {
+		var count uint64
+		var namespace string
+		var endpointName string
+		var labels map[string]string
+		var endpointT *spiderpoolv1.SpiderEndpoint
+
+		BeforeEach(func() {
+			atomic.AddUint64(&count, 1)
+			namespace = "default"
+			endpointName = fmt.Sprintf("endpoint-%v", count)
+			labels = map[string]string{"foo": fmt.Sprintf("bar-%v", count)}
+			endpointT = &spiderpoolv1.SpiderEndpoint{
+				TypeMeta: metav1.TypeMeta{
+					Kind:       constant.SpiderEndpointKind,
+					APIVersion: fmt.Sprintf("%s/%s", constant.SpiderpoolAPIGroup, constant.SpiderpoolAPIVersionV1),
+				},
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      endpointName,
+					Namespace: namespace,
+					Labels:    labels,
+				},
+				Status: spiderpoolv1.WorkloadEndpointStatus{
+					Current: &spiderpoolv1.PodIPAllocation{},
+				},
+			}
+		})
+
+		var deleteOption *client.DeleteOptions
+
+		AfterEach(func() {
+			policy := metav1.DeletePropagationForeground
+			deleteOption = &client.DeleteOptions{
+				GracePeriodSeconds: pointer.Int64(0),
+				PropagationPolicy:  &policy,
+			}
+
+			ctx := context.TODO()
+			err := fakeClient.Delete(ctx, endpointT, deleteOption)
+			Expect(client.IgnoreNotFound(err)).NotTo(HaveOccurred())
+		})
+
+		Describe("GetEndpointByName", func() {
+			It("gets non-existent Endpoint", func() {
+				ctx := context.TODO()
+				endpoint, err := endpointManager.GetEndpointByName(ctx, namespace, endpointName)
+				Expect(apierrors.IsNotFound(err)).To(BeTrue())
+				Expect(endpoint).To(BeNil())
+			})
+
+			It("gets an existing Endpoint", func() {
+				ctx := context.TODO()
+				err := fakeClient.Create(ctx, endpointT)
+				Expect(err).NotTo(HaveOccurred())
+
+				endpoint, err := endpointManager.GetEndpointByName(ctx, namespace, endpointName)
+				Expect(err).NotTo(HaveOccurred())
+				Expect(endpoint).NotTo(BeNil())
+
+				Expect(endpoint).To(Equal(endpointT))
+			})
+		})
+
+		Describe("ListEndpoints", func() {
+			It("failed to list Endpoints due to some unknown errors", func() {
+				patches := gomonkey.ApplyMethodReturn(fakeClient, "List", constant.ErrUnknown)
+				defer patches.Reset()
+
+				ctx := context.TODO()
+				err := fakeClient.Create(ctx, endpointT)
+				Expect(err).NotTo(HaveOccurred())
+
+				endpointList, err := endpointManager.ListEndpoints(ctx)
+				Expect(err).To(MatchError(constant.ErrUnknown))
+				Expect(endpointList).To(BeNil())
+			})
+
+			It("lists all Endpoints", func() {
+				ctx := context.TODO()
+				err := fakeClient.Create(ctx, endpointT)
+				Expect(err).NotTo(HaveOccurred())
+
+				endpointList, err := endpointManager.ListEndpoints(ctx)
+				Expect(err).NotTo(HaveOccurred())
+				Expect(endpointList.Items).NotTo(BeEmpty())
+
+				hasEndpoint := false
+				for _, endpoint := range endpointList.Items {
+					if endpoint.Name == endpointName {
+						hasEndpoint = true
+						break
+					}
+				}
+				Expect(hasEndpoint).To(BeTrue())
+			})
+
+			It("filters results by Namespace", func() {
+				ctx := context.TODO()
+				err := fakeClient.Create(ctx, endpointT)
+				Expect(err).NotTo(HaveOccurred())
+
+				endpointList, err := endpointManager.ListEndpoints(ctx, client.MatchingFields{metav1.ObjectNameField: endpointName})
+				Expect(err).NotTo(HaveOccurred())
+				Expect(endpointList.Items).NotTo(BeEmpty())
+
+				hasEndpoint := false
+				for _, endpoint := range endpointList.Items {
+					if endpoint.Name == endpointName {
+						hasEndpoint = true
+						break
+					}
+				}
+				Expect(hasEndpoint).To(BeTrue())
+			})
+
+			It("filters results by label selector", func() {
+				ctx := context.TODO()
+				err := fakeClient.Create(ctx, endpointT)
+				Expect(err).NotTo(HaveOccurred())
+
+				endpointList, err := endpointManager.ListEndpoints(ctx, client.MatchingLabels(labels))
+				Expect(err).NotTo(HaveOccurred())
+				Expect(endpointList.Items).NotTo(BeEmpty())
+
+				hasEndpoint := false
+				for _, endpoint := range endpointList.Items {
+					if endpoint.Name == endpointName {
+						hasEndpoint = true
+						break
+					}
+				}
+				Expect(hasEndpoint).To(BeTrue())
+			})
+
+			It("filters results by field selector", func() {
+				ctx := context.TODO()
+				err := fakeClient.Create(ctx, endpointT)
+				Expect(err).NotTo(HaveOccurred())
+
+				endpointList, err := endpointManager.ListEndpoints(ctx, client.MatchingFields{metav1.ObjectNameField: endpointName})
+				Expect(err).NotTo(HaveOccurred())
+				Expect(endpointList.Items).NotTo(BeEmpty())
+
+				hasEndpoint := false
+				for _, endpoint := range endpointList.Items {
+					if endpoint.Name == endpointName {
+						hasEndpoint = true
+						break
+					}
+				}
+				Expect(hasEndpoint).To(BeTrue())
+			})
+		})
+
+		Describe("DeleteEndpoint", func() {
+			It("deletes non-existent Endpoint", func() {
+				ctx := context.TODO()
+				err := endpointManager.DeleteEndpoint(ctx, endpointT)
+				Expect(err).NotTo(HaveOccurred())
+			})
+
+			It("deletes an existing Endpoint", func() {
+				ctx := context.TODO()
+				err := fakeClient.Create(ctx, endpointT)
+				Expect(err).NotTo(HaveOccurred())
+
+				err = endpointManager.DeleteEndpoint(ctx, endpointT)
+				Expect(err).NotTo(HaveOccurred())
+			})
+		})
+
+		Describe("RemoveFinalizer", func() {
+			It("removes the finalizer for non-existent Endpoint", func() {
+				ctx := context.TODO()
+				err := endpointManager.RemoveFinalizer(ctx, namespace, endpointName)
+				Expect(err).NotTo(HaveOccurred())
+			})
+
+			It("removes the finalizer that does not exit on the Endpoint", func() {
+				ctx := context.TODO()
+				err := fakeClient.Create(ctx, endpointT)
+				Expect(err).NotTo(HaveOccurred())
+
+				err = endpointManager.RemoveFinalizer(ctx, namespace, endpointName)
+				Expect(err).NotTo(HaveOccurred())
+			})
+
+			It("failed to update Endpoint due to some unknown errors", func() {
+				patches := gomonkey.ApplyMethodReturn(fakeClient, "Update", constant.ErrUnknown)
+				defer patches.Reset()
+
+				controllerutil.AddFinalizer(endpointT, constant.SpiderFinalizer)
+
+				ctx := context.TODO()
+				err := fakeClient.Create(ctx, endpointT)
+				Expect(err).NotTo(HaveOccurred())
+
+				err = endpointManager.RemoveFinalizer(ctx, namespace, endpointName)
+				Expect(err).To(MatchError(constant.ErrUnknown))
+			})
+
+			It("runs out of retries to update Endpoint, but conflicts still occur", func() {
+				patches := gomonkey.ApplyMethodReturn(fakeClient, "Update", apierrors.NewConflict(schema.GroupResource{Resource: "test"}, "other", nil))
+				defer patches.Reset()
+
+				controllerutil.AddFinalizer(endpointT, constant.SpiderFinalizer)
+
+				ctx := context.TODO()
+				err := fakeClient.Create(ctx, endpointT)
+				Expect(err).NotTo(HaveOccurred())
+
+				err = endpointManager.RemoveFinalizer(ctx, namespace, endpointName)
+				Expect(err).To(MatchError(constant.ErrRetriesExhausted))
+			})
+
+			It("removes the Endpoint's finalizer", func() {
+				controllerutil.AddFinalizer(endpointT, constant.SpiderFinalizer)
+
+				ctx := context.TODO()
+				err := fakeClient.Create(ctx, endpointT)
+				Expect(err).NotTo(HaveOccurred())
+
+				err = endpointManager.RemoveFinalizer(ctx, namespace, endpointName)
+				Expect(err).NotTo(HaveOccurred())
+
+				var endpoint spiderpoolv1.SpiderEndpoint
+				err = fakeClient.Get(ctx, types.NamespacedName{Namespace: namespace, Name: endpointName}, &endpoint)
+				Expect(err).NotTo(HaveOccurred())
+
+				contains := controllerutil.ContainsFinalizer(&endpoint, constant.SpiderFinalizer)
+				Expect(contains).To(BeFalse())
+			})
+		})
+
+		Describe("MarkIPAllocation", func() {
+			var podT *corev1.Pod
+
+			BeforeEach(func() {
+				podT = &corev1.Pod{
+					TypeMeta: metav1.TypeMeta{
+						Kind:       "Pod",
+						APIVersion: corev1.SchemeGroupVersion.String(),
+					},
+					ObjectMeta: metav1.ObjectMeta{
+						Name:      endpointName,
+						Namespace: namespace,
+						UID:       uuid.NewUUID(),
+					},
+					Spec: corev1.PodSpec{
+						NodeName: "node",
+					},
+				}
+			})
+
+			It("inputs nil Pod", func() {
+				ctx := context.TODO()
+				endpoint, err := endpointManager.MarkIPAllocation(ctx, stringid.GenerateRandomID(), nil)
+				Expect(err).To(MatchError(constant.ErrMissingRequiredParam))
+				Expect(endpoint).To(BeNil())
+			})
+
+			It("failed to get the top controller of Pod due to some unknown errors", func() {
+				mockPodManager.EXPECT().
+					GetPodTopController(gomock.All(), gomock.All()).
+					Return("", nil, constant.ErrUnknown).
+					Times(1)
+
+				ctx := context.TODO()
+				endpoint, err := endpointManager.MarkIPAllocation(ctx, stringid.GenerateRandomID(), podT)
+				Expect(err).To(MatchError(constant.ErrUnknown))
+				Expect(endpoint).To(BeNil())
+			})
+
+			It("failed to set ownerReference to Pod due to some unknown errors", func() {
+				mockPodManager.EXPECT().
+					GetPodTopController(gomock.All(), gomock.All()).
+					Return(constant.OwnerNone, nil, nil).
+					Times(1)
+
+				patches := gomonkey.ApplyFuncReturn(controllerutil.SetOwnerReference, constant.ErrUnknown)
+				defer patches.Reset()
+
+				ctx := context.TODO()
+				endpoint, err := endpointManager.MarkIPAllocation(ctx, stringid.GenerateRandomID(), podT)
+				Expect(err).To(MatchError(constant.ErrUnknown))
+				Expect(endpoint).To(BeNil())
+			})
+
+			It("failed to create Endpoint due to some unknown errors", func() {
+				mockPodManager.EXPECT().
+					GetPodTopController(gomock.All(), gomock.All()).
+					Return(constant.OwnerNone, nil, nil).
+					Times(1)
+
+				patches := gomonkey.ApplyMethodReturn(fakeClient, "Create", constant.ErrUnknown)
+				defer patches.Reset()
+
+				ctx := context.TODO()
+				endpoint, err := endpointManager.MarkIPAllocation(ctx, stringid.GenerateRandomID(), podT)
+				Expect(err).To(MatchError(constant.ErrUnknown))
+				Expect(endpoint).To(BeNil())
+			})
+
+			It("failed to update the status of Endpoint due to some unknown errors", func() {
+				mockPodManager.EXPECT().
+					GetPodTopController(gomock.All(), gomock.All()).
+					Return(constant.OwnerNone, nil, nil).
+					Times(1)
+
+				patches := gomonkey.ApplyMethodReturn(fakeClient.Status(), "Update", constant.ErrUnknown)
+				defer patches.Reset()
+
+				ctx := context.TODO()
+				endpoint, err := endpointManager.MarkIPAllocation(ctx, stringid.GenerateRandomID(), podT)
+				Expect(err).To(MatchError(constant.ErrUnknown))
+				Expect(endpoint).To(BeNil())
+			})
+
+			It("marks the IP allocation for orphan Pod", func() {
+				mockPodManager.EXPECT().
+					GetPodTopController(gomock.All(), gomock.All()).
+					Return(constant.OwnerNone, nil, nil).
+					Times(1)
+
+				ctx := context.TODO()
+				endpoint, err := endpointManager.MarkIPAllocation(ctx, stringid.GenerateRandomID(), podT)
+				Expect(err).NotTo(HaveOccurred())
+				Expect(endpoint).NotTo(BeNil())
+			})
+
+			It("marks the IP allocation for StatefulSet's Pod", func() {
+				mockPodManager.EXPECT().
+					GetPodTopController(gomock.All(), gomock.All()).
+					Return(
+						constant.OwnerStatefulSet,
+						&appsv1.StatefulSet{
+							TypeMeta: metav1.TypeMeta{
+								Kind:       "StatefulSet",
+								APIVersion: appsv1.SchemeGroupVersion.String(),
+							},
+							ObjectMeta: metav1.ObjectMeta{
+								Name:      "statefulset",
+								Namespace: namespace,
+							},
+						},
+						nil,
+					).
+					Times(1)
+
+				ctx := context.TODO()
+				endpoint, err := endpointManager.MarkIPAllocation(ctx, stringid.GenerateRandomID(), podT)
+				Expect(err).NotTo(HaveOccurred())
+				Expect(endpoint).NotTo(BeNil())
+			})
+		})
+
+		Describe("ReMarkIPAllocation", func() {
+			var containerID string
+			var podT *corev1.Pod
+
+			BeforeEach(func() {
+				podT = &corev1.Pod{
+					TypeMeta: metav1.TypeMeta{
+						Kind:       "Pod",
+						APIVersion: corev1.SchemeGroupVersion.String(),
+					},
+					ObjectMeta: metav1.ObjectMeta{
+						Name:      endpointName,
+						Namespace: namespace,
+						UID:       uuid.NewUUID(),
+					},
+					Spec: corev1.PodSpec{
+						NodeName: "node",
+					},
+				}
+
+				containerID = stringid.GenerateRandomID()
+				allocation := &spiderpoolv1.PodIPAllocation{
+					ContainerID:  containerID,
+					Node:         &podT.Spec.NodeName,
+					CreationTime: &metav1.Time{Time: time.Now()},
+				}
+
+				err := controllerutil.SetOwnerReference(podT, endpointT, scheme)
+				Expect(err).NotTo(HaveOccurred())
+
+				controllerutil.AddFinalizer(endpointT, constant.SpiderFinalizer)
+				endpointT.Status.Current = allocation
+				endpointT.Status.History = append(endpointT.Status.History, *allocation)
+			})
+
+			It("inputs nil Pod", func() {
+				ctx := context.TODO()
+				err := endpointManager.ReMarkIPAllocation(ctx, stringid.GenerateRandomID(), nil, endpointT)
+				Expect(err).To(MatchError(constant.ErrMissingRequiredParam))
+			})
+
+			It("inputs nil Endpoint", func() {
+				ctx := context.TODO()
+				err := endpointManager.ReMarkIPAllocation(ctx, stringid.GenerateRandomID(), podT, nil)
+				Expect(err).To(MatchError(constant.ErrMissingRequiredParam))
+			})
+
+			It("test to create two Pods with the same namespace and name in a very short time", func() {
+				ctx := context.TODO()
+				err := fakeClient.Create(ctx, endpointT)
+				Expect(err).NotTo(HaveOccurred())
+
+				err = fakeClient.Delete(ctx, endpointT)
+				Expect(err).NotTo(HaveOccurred())
+
+				var endpoint spiderpoolv1.SpiderEndpoint
+				err = fakeClient.Get(ctx, types.NamespacedName{Namespace: namespace, Name: endpointName}, &endpoint)
+				Expect(err).NotTo(HaveOccurred())
+
+				newPod := podT.DeepCopy()
+				newPod.SetUID(uuid.NewUUID())
+				err = endpointManager.ReMarkIPAllocation(ctx, stringid.GenerateRandomID(), newPod, &endpoint)
+				Expect(err).To(HaveOccurred())
+			})
+
+			It("re-marks the IP allocation with the same container ID", func() {
+				ctx := context.TODO()
+				err := endpointManager.ReMarkIPAllocation(ctx, containerID, podT, endpointT)
+				Expect(err).NotTo(HaveOccurred())
+			})
+
+			It("failed to update the status of Endpoint due to some unknown errors", func() {
+				patches := gomonkey.ApplyMethodReturn(fakeClient.Status(), "Update", constant.ErrUnknown)
+				defer patches.Reset()
+
+				ctx := context.TODO()
+				err := endpointManager.ReMarkIPAllocation(ctx, stringid.GenerateRandomID(), podT, endpointT)
+				Expect(err).To(MatchError(constant.ErrUnknown))
+			})
+
+			It("re-marks the IP allocation", func() {
+				By("Create the Endpoint")
+				ctx := context.TODO()
+				err := fakeClient.Create(ctx, endpointT)
+				Expect(err).NotTo(HaveOccurred())
+
+				By("Inadvertently delete the Endpoint manually")
+				err = fakeClient.Delete(ctx, endpointT)
+				Expect(err).NotTo(HaveOccurred())
+
+				By("Re-mark the Endpoint")
+				var endpoint spiderpoolv1.SpiderEndpoint
+				err = fakeClient.Get(ctx, types.NamespacedName{Namespace: namespace, Name: endpointName}, &endpoint)
+				Expect(err).NotTo(HaveOccurred())
+
+				newContainerID := stringid.GenerateRandomID()
+				err = endpointManager.ReMarkIPAllocation(ctx, newContainerID, podT, &endpoint)
+				Expect(err).NotTo(HaveOccurred())
+				Expect(endpoint.Status.Current.ContainerID).To(Equal(newContainerID))
+
+				By("Truncate the extra history records")
+				Expect(endpoint.Status.History).To(HaveLen(1))
+				Expect(*endpoint.Status.Current).To(Equal(endpoint.Status.History[0]))
+			})
+		})
+
+		Describe("PatchIPAllocation", func() {
+			var marked *spiderpoolv1.PodIPAllocation
+			var v4Patch, v6Patch *spiderpoolv1.PodIPAllocation
+
+			BeforeEach(func() {
+				containerID := stringid.GenerateRandomID()
+				marked = &spiderpoolv1.PodIPAllocation{
+					ContainerID:  containerID,
+					Node:         pointer.String("node"),
+					CreationTime: &metav1.Time{Time: time.Now()},
+				}
+
+				v4Patch = &spiderpoolv1.PodIPAllocation{
+					ContainerID: containerID,
+					IPs: []spiderpoolv1.IPAllocationDetail{
+						{
+							NIC:         "eth0",
+							Vlan:        pointer.Int64(0),
+							IPv4:        pointer.String("172.18.40.10/24"),
+							IPv4Pool:    pointer.String("default-ipv4-ippool"),
+							IPv4Gateway: pointer.String("172.18.40.1"),
+							Routes: []spiderpoolv1.Route{
+								{
+									Dst: "192.168.40.0/24",
+									Gw:  "172.18.40.1",
+								},
+							},
+						},
+					},
+				}
+				v6Patch = &spiderpoolv1.PodIPAllocation{
+					ContainerID: containerID,
+					IPs: []spiderpoolv1.IPAllocationDetail{
+						{
+							NIC:         "eth0",
+							Vlan:        pointer.Int64(0),
+							IPv6:        pointer.String("abcd:1234::a/120"),
+							IPv6Pool:    pointer.String("default-ipv6-ippool"),
+							IPv6Gateway: pointer.String("abcd:1234::1"),
+							Routes: []spiderpoolv1.Route{
+								{
+									Dst: "fd00:40::/120",
+									Gw:  "abcd:1234::1",
+								},
+							},
+						},
+					},
+				}
+			})
+
+			It("inputs nil Endpoint", func() {
+				ctx := context.TODO()
+				err := endpointManager.PatchIPAllocation(ctx, v4Patch, nil)
+				Expect(err).To(MatchError(constant.ErrMissingRequiredParam))
+			})
+
+			It("inputs nil IP allocation", func() {
+				ctx := context.TODO()
+				err := endpointManager.PatchIPAllocation(ctx, nil, endpointT)
+				Expect(err).To(MatchError(constant.ErrMissingRequiredParam))
+			})
+
+			It("patches the IP allocation for unmarked Endpoint", func() {
+				endpointT.Status.Current = nil
+
+				ctx := context.TODO()
+				err := endpointManager.PatchIPAllocation(ctx, v4Patch, endpointT)
+				Expect(err).To(HaveOccurred())
+			})
+
+			It("patches the IP allocation when the Endpoint data is corrupt", func() {
+				endpointT.Status.Current = marked
+
+				ctx := context.TODO()
+				err := endpointManager.PatchIPAllocation(ctx, v4Patch, endpointT)
+				Expect(err).To(HaveOccurred())
+			})
+
+			It("patches the IP allocation with unmatched container ID", func() {
+				endpointT.Status.Current = marked
+				endpointT.Status.History = append(endpointT.Status.History, *marked)
+				v4Patch.ContainerID = stringid.GenerateRandomID()
+
+				ctx := context.TODO()
+				err := endpointManager.PatchIPAllocation(ctx, v4Patch, endpointT)
+				Expect(err).To(HaveOccurred())
+			})
+
+			It("failed to update the status of Endpoint due to some unknown errors", func() {
+				patches := gomonkey.ApplyMethodReturn(fakeClient.Status(), "Update", constant.ErrUnknown)
+				defer patches.Reset()
+
+				endpointT.Status.Current = marked
+				endpointT.Status.History = append(endpointT.Status.History, *marked)
+
+				ctx := context.TODO()
+				err := endpointManager.PatchIPAllocation(ctx, v4Patch, endpointT)
+				Expect(err).To(MatchError(constant.ErrUnknown))
+			})
+
+			It("patches the IP allocation of IPv4 and IPv6", func() {
+				endpointT.Status.Current = marked
+				endpointT.Status.History = append(endpointT.Status.History, *marked)
+
+				ctx := context.TODO()
+				err := fakeClient.Create(ctx, endpointT)
+				Expect(err).NotTo(HaveOccurred())
+
+				err = endpointManager.PatchIPAllocation(ctx, v4Patch, endpointT)
+				Expect(err).NotTo(HaveOccurred())
+				err = endpointManager.PatchIPAllocation(ctx, v6Patch, endpointT)
+				Expect(err).NotTo(HaveOccurred())
+
+				var endpoint spiderpoolv1.SpiderEndpoint
+				err = fakeClient.Get(ctx, types.NamespacedName{Namespace: namespace, Name: endpointName}, &endpoint)
+				Expect(err).NotTo(HaveOccurred())
+				Expect(endpoint.Status.Current.IPs).To(HaveLen(1))
+				Expect(endpoint.Status.Current.IPs[0]).To(Equal(
+					spiderpoolv1.IPAllocationDetail{
+						NIC:         "eth0",
+						Vlan:        pointer.Int64(0),
+						IPv4:        pointer.String("172.18.40.10/24"),
+						IPv4Pool:    pointer.String("default-ipv4-ippool"),
+						IPv4Gateway: pointer.String("172.18.40.1"),
+						IPv6:        pointer.String("abcd:1234::a/120"),
+						IPv6Pool:    pointer.String("default-ipv6-ippool"),
+						IPv6Gateway: pointer.String("abcd:1234::1"),
+						Routes: []spiderpoolv1.Route{
+							{
+								Dst: "192.168.40.0/24",
+								Gw:  "172.18.40.1",
+							},
+							{
+								Dst: "fd00:40::/120",
+								Gw:  "abcd:1234::1",
+							},
+						},
+					},
+				))
+				Expect(*endpoint.Status.Current).To(Equal(endpoint.Status.History[0]))
+			})
+		})
+
+		Describe("ClearCurrentIPAllocation", func() {
+			It("inputs nil Endpoint", func() {
+				ctx := context.TODO()
+				err := endpointManager.ClearCurrentIPAllocation(ctx, stringid.GenerateRandomID(), nil)
+				Expect(err).NotTo(HaveOccurred())
+			})
+
+			It("clears up nil current IP allocation", func() {
+				ctx := context.TODO()
+				err := endpointManager.ClearCurrentIPAllocation(ctx, stringid.GenerateRandomID(), endpointT)
+				Expect(err).NotTo(HaveOccurred())
+			})
+
+			It("clears up the current IP allocation with unmatched container ID", func() {
+				endpointT.Status.Current.ContainerID = stringid.GenerateRandomID()
+
+				ctx := context.TODO()
+				err := endpointManager.ClearCurrentIPAllocation(ctx, stringid.GenerateRandomID(), endpointT)
+				Expect(err).NotTo(HaveOccurred())
+			})
+
+			It("failed to update the status of Endpoint due to some unknown errors", func() {
+				patches := gomonkey.ApplyMethodReturn(fakeClient.Status(), "Update", constant.ErrUnknown)
+				defer patches.Reset()
+
+				containerId := stringid.GenerateRandomID()
+				endpointT.Status.Current.ContainerID = containerId
+
+				ctx := context.TODO()
+				err := endpointManager.ClearCurrentIPAllocation(ctx, containerId, endpointT)
+				Expect(err).To(MatchError(constant.ErrUnknown))
+			})
+
+			It("clears up the current IP allocation for non-existent Endpoint", func() {
+				containerId := stringid.GenerateRandomID()
+				endpointT.Status.Current.ContainerID = containerId
+
+				ctx := context.TODO()
+				err := endpointManager.ClearCurrentIPAllocation(ctx, containerId, endpointT)
+				Expect(err).NotTo(HaveOccurred())
+			})
+
+			It("clears up the current IP allocation", func() {
+				containerId := stringid.GenerateRandomID()
+				endpointT.Status.Current.ContainerID = containerId
+
+				ctx := context.TODO()
+				err := fakeClient.Create(ctx, endpointT)
+				Expect(err).NotTo(HaveOccurred())
+
+				err = endpointManager.ClearCurrentIPAllocation(ctx, containerId, endpointT)
+				Expect(err).NotTo(HaveOccurred())
+
+				var endpoint spiderpoolv1.SpiderEndpoint
+				err = fakeClient.Get(ctx, types.NamespacedName{Namespace: namespace, Name: endpointName}, &endpoint)
+				Expect(err).NotTo(HaveOccurred())
+				Expect(endpoint.Status.Current).To(BeNil())
+			})
+		})
+
+		Describe("ReallocateCurrentIPAllocation", func() {
+			It("reallocates the current IP allocation for non-existent Endpoint", func() {
+				ctx := context.TODO()
+				err := endpointManager.ReallocateCurrentIPAllocation(ctx, stringid.GenerateRandomID(), "node", namespace, endpointName)
+				Expect(apierrors.IsNotFound(err)).To(BeTrue())
+			})
+
+			It("reallocates the current IP allocation with the same container ID", func() {
+				containerID := stringid.GenerateRandomID()
+				endpointT.Status.Current.ContainerID = containerID
+
+				ctx := context.TODO()
+				err := fakeClient.Create(ctx, endpointT)
+				Expect(err).NotTo(HaveOccurred())
+
+				err = endpointManager.ReallocateCurrentIPAllocation(ctx, containerID, "node", namespace, endpointName)
+				Expect(err).NotTo(HaveOccurred())
+			})
+
+			It("failed to update the status of Endpoint due to some unknown errors", func() {
+				patches := gomonkey.ApplyMethodReturn(fakeClient.Status(), "Update", constant.ErrUnknown)
+				defer patches.Reset()
+
+				endpointT.Status.Current.ContainerID = stringid.GenerateRandomID()
+				endpointT.Status.Current.Node = pointer.String("old-node")
+
+				ctx := context.TODO()
+				err := fakeClient.Create(ctx, endpointT)
+				Expect(err).NotTo(HaveOccurred())
+
+				err = endpointManager.ReallocateCurrentIPAllocation(ctx, stringid.GenerateRandomID(), "new-node", namespace, endpointName)
+				Expect(err).To(MatchError(constant.ErrUnknown))
+			})
+
+			It("runs out of retries to update the status of Endpoint, but conflicts still occur", func() {
+				patches := gomonkey.ApplyMethodReturn(fakeClient.Status(), "Update", apierrors.NewConflict(schema.GroupResource{Resource: "test"}, "other", nil))
+				defer patches.Reset()
+
+				endpointT.Status.Current.ContainerID = stringid.GenerateRandomID()
+				endpointT.Status.Current.Node = pointer.String("old-node")
+
+				ctx := context.TODO()
+				err := fakeClient.Create(ctx, endpointT)
+				Expect(err).NotTo(HaveOccurred())
+
+				err = endpointManager.ReallocateCurrentIPAllocation(ctx, stringid.GenerateRandomID(), "new-node", namespace, endpointName)
+				Expect(err).To(MatchError(constant.ErrRetriesExhausted))
+			})
+
+			It("updates the current IP allocation", func() {
+				endpointT.Status.Current.ContainerID = stringid.GenerateRandomID()
+				endpointT.Status.Current.Node = pointer.String("old-node")
+
+				ctx := context.TODO()
+				err := fakeClient.Create(ctx, endpointT)
+				Expect(err).NotTo(HaveOccurred())
+
+				containerID := stringid.GenerateRandomID()
+				nodeName := "new-node"
+				err = endpointManager.ReallocateCurrentIPAllocation(ctx, containerID, nodeName, namespace, endpointName)
+				Expect(err).NotTo(HaveOccurred())
+
+				var endpoint spiderpoolv1.SpiderEndpoint
+				err = fakeClient.Get(ctx, types.NamespacedName{Namespace: namespace, Name: endpointName}, &endpoint)
+				Expect(err).NotTo(HaveOccurred())
+				Expect(endpoint.Status.Current.ContainerID).To(Equal(containerID))
+				Expect(*endpoint.Status.Current.Node).To(Equal(nodeName))
+			})
+		})
+	})
+})
diff --git a/pkg/workloadendpointmanager/workloadendpoint_webhook_test.go b/pkg/workloadendpointmanager/workloadendpoint_webhook_test.go
new file mode 100644
index 000000000..7994e2239
--- /dev/null
+++ b/pkg/workloadendpointmanager/workloadendpoint_webhook_test.go
@@ -0,0 +1,93 @@
+// Copyright 2019 The Kubernetes Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package workloadendpointmanager_test
+
+import (
+	"context"
+	"fmt"
+	"time"
+
+	"github.com/agiledragon/gomonkey/v2"
+	. "github.com/onsi/ginkgo/v2"
+	. "github.com/onsi/gomega"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	ctrl "sigs.k8s.io/controller-runtime"
+	"sigs.k8s.io/controller-runtime/pkg/client/config"
+	"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
+	"sigs.k8s.io/controller-runtime/pkg/manager"
+
+	"github.com/spidernet-io/spiderpool/pkg/constant"
+	spiderpoolv1 "github.com/spidernet-io/spiderpool/pkg/k8s/apis/spiderpool.spidernet.io/v1"
+	"github.com/spidernet-io/spiderpool/pkg/logutils"
+	"github.com/spidernet-io/spiderpool/pkg/workloadendpointmanager"
+)
+
+var _ = Describe("WorkloadEndpointWebhook", Label("workloadendpoint_webhook_test"), func() {
+	Describe("Set up WorkloadEndpointWebhook", func() {
+		PIt("talks to a Kubernetes API server", func() {
+			cfg, err := config.GetConfig()
+			Expect(err).NotTo(HaveOccurred())
+			Expect(cfg).NotTo(BeNil())
+
+			mgr, err := ctrl.NewManager(cfg, manager.Options{Scheme: scheme})
+			Expect(err).NotTo(HaveOccurred())
+
+			err = endpointWebhook.SetupWebhookWithManager(mgr)
+			Expect(err).NotTo(HaveOccurred())
+		})
+	})
+
+	Describe("Test WorkloadEndpointWebhook's method", func() {
+		var endpointT *spiderpoolv1.SpiderEndpoint
+
+		BeforeEach(func() {
+			workloadendpointmanager.WebhookLogger = logutils.Logger.Named("Endpoint-Webhook")
+			endpointT = &spiderpoolv1.SpiderEndpoint{
+				TypeMeta: metav1.TypeMeta{
+					Kind:       constant.SpiderEndpointKind,
+					APIVersion: fmt.Sprintf("%s/%s", constant.SpiderpoolAPIGroup, constant.SpiderpoolAPIVersionV1),
+				},
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      "endpoint",
+					Namespace: "default",
+				},
+			}
+		})
+
+		Describe("Default", func() {
+			It("avoids modifying the terminating Endpoint", func() {
+				deletionTimestamp := metav1.NewTime(time.Now().Add(30 * time.Second))
+				endpointT.SetDeletionTimestamp(&deletionTimestamp)
+
+				ctx := context.TODO()
+				err := endpointWebhook.Default(ctx, endpointT)
+				Expect(err).NotTo(HaveOccurred())
+			})
+
+			It("sets finalizer", func() {
+				ctx := context.TODO()
+				err := endpointWebhook.Default(ctx, endpointT)
+				Expect(err).NotTo(HaveOccurred())
+
+				contains := controllerutil.ContainsFinalizer(endpointT, constant.SpiderFinalizer)
+				Expect(contains).To(BeTrue())
+			})
+
+			It("failed to mutate Endpoint due to some unknown errors", func() {
+				patches := gomonkey.ApplyPrivateMethod(
+					endpointWebhook,
+					"mutateWorkloadEndpoint",
+					func(_ context.Context, _ *spiderpoolv1.SpiderEndpoint) error {
+						return constant.ErrUnknown
+					},
+				)
+				defer patches.Reset()
+
+				ctx := context.TODO()
+				err := endpointWebhook.Default(ctx, endpointT)
+				Expect(err).NotTo(HaveOccurred())
+			})
+		})
+	})
+})