Merge pull request #719 from erikwilson/encrypted-network-support

Initial encrypted network support
This commit is contained in:
Erik Wilson 2019-09-27 19:35:24 -07:00 committed by GitHub
commit 2ea7a717d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
58 changed files with 3074 additions and 117 deletions

View File

@ -1,4 +1,5 @@
./bin
./etc
./build/data
./build/data.tar.gz
./pkg/data/zz_generated_bindata.go

1
.gitignore vendored
View File

@ -11,6 +11,7 @@
/.lesshst
/*.log
/bin
/etc
/build
/data-dir
/dist

2
Vagrantfile vendored
View File

@ -1,4 +1,4 @@
BOX = "generic/alpine39"
BOX = "generic/alpine310"
HOME = File.dirname(__FILE__)
PROJECT = File.basename(HOME)
MOUNT_TYPE = ENV['MOUNT_TYPE'] || "nfs"

View File

@ -87,6 +87,9 @@ func stageAndRun(dataDir string, cmd string, args []string) error {
if err := os.Setenv("PATH", filepath.Join(dir, "bin")+":"+os.Getenv("PATH")+":"+filepath.Join(dir, "bin/aux")); err != nil {
return err
}
if err := os.Setenv("K3S_DATA_DIR", dir); err != nil {
return err
}
cmd, err = exec.LookPath(cmd)
if err != nil {

3
go.mod
View File

@ -12,7 +12,7 @@ replace (
github.com/containerd/go-runc => github.com/containerd/go-runc v0.0.0-20190911050354-e029b79d8cda
github.com/containerd/typeurl => github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd
github.com/containernetworking/plugins => github.com/rancher/plugins v0.8.2-k3s.2
github.com/coreos/flannel => github.com/ibuildthecloud/flannel v0.10.1-0.20190131215433-823afe66b226
github.com/coreos/flannel => github.com/rancher/flannel v0.11.0-k3s.1
github.com/coreos/go-systemd => github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7
github.com/docker/distribution => github.com/docker/distribution v0.0.0-20190205005809-0d3efadf0154
github.com/docker/libnetwork => github.com/docker/libnetwork v0.8.0-dev.2.0.20190624125649-f0e46a78ea34
@ -57,6 +57,7 @@ require (
github.com/Microsoft/go-winio v0.4.14 // indirect
github.com/NYTimes/gziphandler v1.1.1 // indirect
github.com/bhendo/go-powershell v0.0.0-20190719160123-219e7fb4e41e // indirect
github.com/bronze1man/goStrongswanVici v0.0.0-20190828090544-27d02f80ba40 // indirect
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23 // indirect
github.com/containerd/cgroups v0.0.0-20190923161937-abd0b19954a6 // indirect
github.com/containerd/containerd v1.2.8

31
go.sum
View File

@ -1,6 +1,5 @@
bitbucket.org/bertimus9/systemstat v0.0.0-20180207000608-0eeff89b0690/go.mod h1:Ulb78X89vxKYgdL24HMTiXYHlyHEvruOj1ZPlqeNEZM=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0 h1:eOI3/cP2VTU6uZLDYAoic+eyzzB9YyGmJ7eIjl8rOPg=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0 h1:ROfEUZz+Gh5pa62DJWXSaonyu3StP6EA6lPEXPI6mCo=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
@ -40,13 +39,11 @@ github.com/Microsoft/go-winio v0.4.14 h1:+hMXMk01us9KgxGb7ftKQt2Xpf5hH/yky+TDA+q
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
github.com/Microsoft/hcsshim v0.8.6 h1:ZfF0+zZeYdzMIVMZHKtDKJvLHj76XCuVae/jNkjj0IA=
github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46 h1:lsxEuwrXEAokXB9qhlbKWPpo3KMLZQ5WB5WLQRW1uq0=
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I=
github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=
github.com/OpenPeeDeeP/depguard v0.0.0-20180806142446-a69c782687b2/go.mod h1:7/4sitnI9YlQgTLLk734QlzXT8DuHVnAyztLplQjk+o=
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/purell v1.1.0 h1:rmGxhojJlM0tuKtfdvliR84CFHljx9ag64t2xmVkjK4=
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
@ -61,7 +58,6 @@ github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:C
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e h1:QEF07wC0T1rKkctt1RINW/+RMTVmiwxETico2l3gxJA=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf h1:eg0MeVzsP1G42dRafH3vf+al2vQIJU0YHX+1Tw87oco=
github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA=
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
@ -78,6 +74,8 @@ github.com/bifurcation/mint v0.0.0-20180715133206-93c51c6ce115/go.mod h1:zVt7zX3
github.com/blang/semver v3.5.0+incompatible h1:CGxCgetQ64DKk7rdZ++Vfnb1+ogGNnB17OJKJXD2Cfs=
github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
github.com/bronze1man/goStrongswanVici v0.0.0-20190828090544-27d02f80ba40 h1:udTfdeYqe866Z5mxTaEm5irSJK2vupyxwBOHAYEVtJo=
github.com/bronze1man/goStrongswanVici v0.0.0-20190828090544-27d02f80ba40/go.mod h1:fWUtBEPt2yjrr3WFhOqvajM8JSEU8bEeBcoeSCsKRpc=
github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23 h1:D21IyuvjDCshj1/qq+pCNd3VZOAEI9jy6Bi131YlXgI=
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
@ -121,7 +119,6 @@ github.com/coredns/corefile-migration v1.0.2/go.mod h1:OFwBp/Wc9dJt5cAZzHWMNhK1r
github.com/coreos/bbolt v1.3.1-coreos.6 h1:uTXKg9gY70s9jMAKdfljFQcuh4e/BXOM+V+d00KFj3A=
github.com/coreos/bbolt v1.3.1-coreos.6/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/etcd v3.3.13+incompatible h1:8F3hqu9fGYLBifCmRCJsicFqDx/D68Rt3q1JMazcgBQ=
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/etcd v3.3.15+incompatible h1:+9RjdC18gMxNQVvSiXvObLu29mOFmkgdsB4cRTlV+EE=
github.com/coreos/etcd v3.3.15+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
@ -158,7 +155,6 @@ github.com/dnaeon/go-vcr v1.0.1 h1:r8L/HqC0Hje5AXMu1ooW8oyQyOFv4GxqpL0nRP7SLLY=
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
github.com/docker/distribution v0.0.0-20190205005809-0d3efadf0154 h1:C8WBRZDiZn3IZnBlbHVeTWF32XhVGK69Li4GC/3jL9Q=
github.com/docker/distribution v0.0.0-20190205005809-0d3efadf0154/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0 h1:w3NnFcKR5241cfmQU5ZZAsf0xcpId6mWOupTvJlUX2U=
github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v0.7.3-0.20190731001754-589f1dad8dad h1:Rs3PR4MuVaSoApfaYJQRRJtC5dNBSyvRcTSl9MNWKlw=
github.com/docker/docker v0.7.3-0.20190731001754-589f1dad8dad/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
@ -168,7 +164,6 @@ github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=
github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8=
github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw=
github.com/docker/go-units v0.3.3 h1:Xk8S3Xj5sLGlG5g67hJmYMmUgXv5N4PhkjJHHqrwnTk=
github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
@ -243,7 +238,6 @@ github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsd
github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
github.com/go-openapi/spec v0.19.2 h1:SStNd1jRcYtfKCN7R0laGNs80WYYvn5CbBjM2sOmCrE=
github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY=
github.com/go-openapi/strfmt v0.17.0 h1:1isAxYf//QDTnVzbLAMrUK++0k1EjeLJU/gTOR0o3Mc=
github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
github.com/go-openapi/strfmt v0.19.0 h1:0Dn9qy1G9+UJfRU7TR8bmdGxb4uifB7HNrJjOnV0yPk=
@ -253,7 +247,6 @@ github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/
github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
github.com/go-openapi/swag v0.19.2 h1:jvO6bCMBEilGwMfHhrd61zIID4oIFdwb76V17SM88dE=
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/validate v0.18.0 h1:PVXYcP1GkTl+XIAJnyJxOmK6CSG5Q1UcvoCvNO++5Kg=
github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
github.com/go-openapi/validate v0.19.2 h1:ky5l57HjyVRrsJfd2+Ro5Z9PjGuKbsmftwyMtk8H7js=
github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA=
@ -282,7 +275,6 @@ github.com/gofrs/flock v0.7.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14j
github.com/gogo/googleapis v1.3.0 h1:M695OaDJ5ipWvDPcoAg/YL9c3uORAegkEfBqTQF/fTQ=
github.com/gogo/googleapis v1.3.0/go.mod h1:d+q1s/xVJxZGKWwC/6UfPIF33J+G1Tq4GYv9Y+Tg/EU=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/gogo/protobuf v1.3.0 h1:G8O7TerXerS4F6sx9OV7/nRfJdnXgHZu/S/7F2SN+UE=
@ -298,7 +290,6 @@ github.com/golang/mock v1.2.0 h1:28o5sBqPkBsMGnC6b4MvE2TzSr5/AT4c/1fLqVGIwlk=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@ -343,7 +334,6 @@ github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OI
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/tcpproxy v0.0.0-20180808230851-dfa16c61dad2 h1:AtvtonGEH/fZK0XPNNBdB6swgy7Iudfx88wzyIpwqJ8=
github.com/google/tcpproxy v0.0.0-20180808230851-dfa16c61dad2/go.mod h1:DavVbd41y+b7ukKDmlnPR4nGYmkWXR6vHUkjQNiHPBs=
github.com/google/uuid v1.0.0 h1:b4Gk+7WdP/d3HZH8EJsZpvV7EtDOgaZLtnaNGIu1adA=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@ -383,8 +373,6 @@ github.com/heketi/tests v0.0.0-20151005000721-f3775cbcefd6/go.mod h1:xGMAM8JLi7U
github.com/heketi/utils v0.0.0-20170317161834-435bc5bdfa64/go.mod h1:RYlF4ghFZPPmk2TC5REt5OFwvfb6lzxFWrTWB+qs28s=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/ibuildthecloud/flannel v0.10.1-0.20190131215433-823afe66b226 h1:XdW09kPx8lMtvPAPVnlIG4H/kTC01x5ADdN1J+KsglM=
github.com/ibuildthecloud/flannel v0.10.1-0.20190131215433-823afe66b226/go.mod h1:HCHln+957B/ml+RJJ4fnilxsq7wN5dOnytc3nLQchV4=
github.com/ibuildthecloud/kine v0.1.0 h1:nF/wtPm7qECzZeagEyZgy8seFcwpJz8LRF6pc7hYSl0=
github.com/ibuildthecloud/kine v0.1.0/go.mod h1:TTWUtUeu7dHQan9BrCtlRbKr9eK7epHqrBFOAae15Bg=
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
@ -402,7 +390,6 @@ github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht
github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo=
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
@ -456,7 +443,6 @@ github.com/magiconair/properties v1.7.6/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czP
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 h1:2gxZ0XQIU/5z3Z3bUBu+FXuk2pFbkN6tcwi/pjyaDic=
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63 h1:nTT4s92Dgz2HlrB2NaMgvlfqHH39OgMhA7z3PK7PGD4=
@ -518,7 +504,6 @@ github.com/nbutton23/zxcvbn-go v0.0.0-20160627004424-a22cb81b2ecd/go.mod h1:o96d
github.com/nbutton23/zxcvbn-go v0.0.0-20171102151520-eafdab6b0663/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU=
github.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.6.0 h1:Ix8l273rp3QzYgXSR+c8d1fTG7UPgYkOSELPhiY/YGw=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo=
@ -573,6 +558,8 @@ github.com/rancher/containerd v1.3.0-k3s.1 h1:8dz25shb4egTLl0nOXQdtllx20LEXsuOs4
github.com/rancher/containerd v1.3.0-k3s.1/go.mod h1:ZMfzmqce2Z+QSEqdHMfeJs1TZ/UeJ1aDrazjpQT4ehM=
github.com/rancher/cri-tools v1.16.0-k3s.1 h1:cv/iVFkfvDLfpSqGFwgyQbMKLGRzcXo8AALUsd8s5qE=
github.com/rancher/cri-tools v1.16.0-k3s.1/go.mod h1:TEKhKv2EJIZp+p9jnEy4C63g8CosJzsI4kyKKkHag+8=
github.com/rancher/flannel v0.11.0-k3s.1 h1:mIwnfWDafjzQgFkZeJ1AkFrrAT3EdBaA1giE0eLJKo8=
github.com/rancher/flannel v0.11.0-k3s.1/go.mod h1:Hn4ZV+eq0LhLZP63xZnxdGwXEoRSxs5sxELxu27M3UA=
github.com/rancher/helm-controller v0.2.2 h1:MUqisy53/Ay1EYOF2uTCYBbGpgtZLNKKrI01BdxIbQo=
github.com/rancher/helm-controller v0.2.2/go.mod h1:0JkL0UjxddNbT4FmLoESarD4Mz8xzA5YlejqJ/U4g+8=
github.com/rancher/kubernetes v1.16.0-k3s.1 h1:6ewJ22WFt/3l/7d724XiAXZWbatkzWZ/Q8kMow7Jq4E=
@ -677,7 +664,6 @@ github.com/spf13/jwalterweatherman v0.0.0-20180109140146-7c0cea34c8ec/go.mod h1:
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.1 h1:aCvUg6QPl3ibpQUxyLkrEkCHtPqYJL4x9AuhqVqFis4=
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
@ -685,7 +671,6 @@ github.com/spf13/viper v1.0.2/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7Sr
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
github.com/storageos/go-api v0.0.0-20180912212459-343b3eff91fc/go.mod h1:ZrLn+e0ZuF3Y65PNF6dIwbJPZqfmtCXxFm9ckv0agOY=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
@ -713,11 +698,9 @@ github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyC
github.com/valyala/fasthttp v1.2.0/go.mod h1:4vX61m6KN+xDduDNwXrhIAVZaZaZiQ1luJk8LWSxF3s=
github.com/valyala/quicktemplate v1.1.1/go.mod h1:EH+4AkTd43SvgIbQHYu59/cJyxDoOVRUAfrukLPuGJ4=
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
github.com/vishvananda/netlink v0.0.0-20171020171820-b2de5d10e38e h1:f1yevOHP+Suqk0rVc13fIkzcLULJbyQcXDba2klljD0=
github.com/vishvananda/netlink v0.0.0-20171020171820-b2de5d10e38e/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf h1:3J37+NPjNyGW/dbfXtj3yWuF9OEepIdGOXRaJGbORV8=
github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
github.com/vishvananda/netns v0.0.0-20171111001504-be1fbeda1936 h1:J9gO8RJCAFlln1jsvRba/CWVUnMHwObklfxxjErl1uk=
github.com/vishvananda/netns v0.0.0-20171111001504-be1fbeda1936/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI=
github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc h1:R83G5ikgLMxrBvLh22JhdfI8K6YXEPHx5P03Uu3DRs4=
github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI=
@ -747,7 +730,6 @@ golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25/go.mod h1:djNgcEr1/C05ACk
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190506204251-e1dfcc566284 h1:rlLehGeYg6jfoyz/eDqDU1iRXLKfR42nnNh57ytKEWo=
golang.org/x/crypto v0.0.0-20190506204251-e1dfcc566284/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8 h1:1wopBVtVdWnn03fZelqdXTqk7U7zPQCb+T4rbU9ZEoU=
@ -788,7 +770,6 @@ golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc h1:gkKoSkUmnU6bpS/VhkuO27bzQ
golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a h1:tImsplftrFpALCYumobsd0K86vlAs/eXGFms2txfJfA=
golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -815,7 +796,6 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190509141414-a5b02f93d862/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f h1:25KHgbfyiSm6vwQLbM3zZIe1v9p/3ea4Rz+nnM5K/i4=
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190730183949-1393eb018365/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190812073006-9eafafc0a87e h1:TsjK5I7fXk8f2FQrgu6NS7i5Qih3knl2FL1htyguLRE=
@ -846,7 +826,6 @@ golang.org/x/tools v0.0.0-20190311215038-5c2858a9cfe5/go.mod h1:LCzVGOaR6xXOjkQ3
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190322203728-c1a832b0ad89/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384 h1:TFlARGu6Czu1z7q93HTxcP1P+/ZFC/IKythI5RzrnRg=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
@ -876,7 +855,6 @@ google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiq
google.golang.org/grpc v1.23.0 h1:AzbTB6ux+okLTzP8Ru1Xs41C303zdcfEht7MQnYJt5A=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@ -915,7 +893,6 @@ honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.2/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/gengo v0.0.0-20190327210449-e17681d19d3a h1:QoHVuRquf80YZ+/bovwxoMO3Q/A3nt3yTgS0/0nejuk=
k8s.io/gengo v0.0.0-20190327210449-e17681d19d3a/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/gengo v0.0.0-20190822140433-26a664648505 h1:ZY6yclUKVbZ+SdWnkfY+Je5vrMpKOxmGeKRbsXVmqYM=
k8s.io/gengo v0.0.0-20190822140433-26a664648505/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=

View File

@ -330,8 +330,8 @@ func get(envInfo *cmds.Agent) (*config.Node, error) {
nodeConfig := &config.Node{
Docker: envInfo.Docker,
NoFlannel: envInfo.NoFlannel,
ContainerRuntimeEndpoint: envInfo.ContainerRuntimeEndpoint,
FlannelBackend: controlConfig.FlannelBackend,
}
nodeConfig.FlannelIface = flannelIface
nodeConfig.Images = filepath.Join(envInfo.DataDir, "images")
@ -349,6 +349,8 @@ func get(envInfo *cmds.Agent) (*config.Node, error) {
nodeConfig.AgentConfig.KubeConfigKubeProxy = kubeconfigKubeproxy
nodeConfig.AgentConfig.RootDir = filepath.Join(envInfo.DataDir, "kubelet")
nodeConfig.AgentConfig.PauseImage = envInfo.PauseImage
nodeConfig.AgentConfig.IPSECPSK = controlConfig.IPSECPSK
nodeConfig.AgentConfig.StrongSwanDir = filepath.Join(envInfo.DataDir, "strongswan")
nodeConfig.CACerts = info.CACerts
nodeConfig.Containerd.Config = filepath.Join(envInfo.DataDir, "etc/containerd/config.toml")
nodeConfig.Containerd.Root = filepath.Join(envInfo.DataDir, "containerd")
@ -361,8 +363,20 @@ func get(envInfo *cmds.Agent) (*config.Node, error) {
nodeConfig.Containerd.Template = filepath.Join(envInfo.DataDir, "etc/containerd/config.toml.tmpl")
nodeConfig.ServerAddress = serverURLParsed.Host
nodeConfig.Certificate = servingCert
if nodeConfig.FlannelBackend == config.FlannelBackendNone {
nodeConfig.NoFlannel = true
} else {
nodeConfig.NoFlannel = envInfo.NoFlannel
}
if !nodeConfig.NoFlannel {
nodeConfig.FlannelConf = filepath.Join(envInfo.DataDir, "etc/flannel/net-conf.json")
if envInfo.FlannelConf == "" {
nodeConfig.FlannelConf = filepath.Join(envInfo.DataDir, "etc/flannel/net-conf.json")
} else {
nodeConfig.FlannelConf = envInfo.FlannelConf
nodeConfig.FlannelConfOverride = true
}
nodeConfig.AgentConfig.CNIBinDir = filepath.Dir(hostLocal)
nodeConfig.AgentConfig.CNIConfDir = filepath.Join(envInfo.DataDir, "etc/cni/net.d")
}

View File

@ -29,6 +29,8 @@ import (
log "k8s.io/klog"
// Backends need to be imported for their init() to get executed and them to register
_ "github.com/coreos/flannel/backend/extension"
_ "github.com/coreos/flannel/backend/ipsec"
_ "github.com/coreos/flannel/backend/vxlan"
)
@ -42,7 +44,7 @@ func flannel(ctx context.Context, flannelIface *net.Interface, flannelConf, kube
return err
}
sm, err := kube.NewSubnetManager("", flannelConf, kubeConfigFile, "flannel.alpha.coreos.com")
sm, err := kube.NewSubnetManager("", kubeConfigFile, "flannel.alpha.coreos.com", flannelConf)
if err != nil {
return err
}

View File

@ -2,6 +2,9 @@ package flannel
import (
"context"
"fmt"
"os"
"path"
"path/filepath"
"strings"
"time"
@ -22,6 +25,7 @@ const (
{
"type":"flannel",
"delegate":{
"hairpinMode":true,
"forceAddress":true,
"isDefaultGateway":true
}
@ -35,27 +39,45 @@ const (
]
}
`
netJSON = `{
"Network": "%CIDR%",
"Backend": {
"Type": "vxlan"
}
flannelConf = `{
"Network": "%CIDR%",
"Backend": %backend%
}
`
vxlanBackend = `{
"Type": "vxlan"
}`
ipsecBackend = `{
"Type": "ipsec",
"UDPEncap": true,
"PSK": "%psk%"
}`
wireguardBackend = `{
"Type": "extension",
"PreStartupCommand": "wg genkey | tee privatekey | wg pubkey",
"PostStartupCommand": "export SUBNET_IP=$(echo $SUBNET | cut -d'/' -f 1); ip link del flannel.1 2>/dev/null; echo $PATH >&2; wg-add.sh flannel.1 && wg set flannel.1 listen-port 51820 private-key privatekey && ip addr add $SUBNET_IP/32 dev flannel.1 && ip link set flannel.1 up && ip route add $NETWORK dev flannel.1",
"ShutdownCommand": "ip link del flannel.1",
"SubnetAddCommand": "read PUBLICKEY; wg set flannel.1 peer $PUBLICKEY endpoint $PUBLIC_IP:51820 allowed-ips $SUBNET",
"SubnetRemoveCommand": "read PUBLICKEY; wg set flannel.1 peer $PUBLICKEY remove"
}`
)
func Prepare(ctx context.Context, config *config.Node) error {
if err := createCNIConf(config.AgentConfig.CNIConfDir); err != nil {
func Prepare(ctx context.Context, nodeConfig *config.Node) error {
if err := createCNIConf(nodeConfig.AgentConfig.CNIConfDir); err != nil {
return err
}
return createFlannelConf(config)
return createFlannelConf(nodeConfig)
}
func Run(ctx context.Context, config *config.Node) error {
nodeName := config.AgentConfig.NodeName
func Run(ctx context.Context, nodeConfig *config.Node) error {
nodeName := nodeConfig.AgentConfig.NodeName
restConfig, err := clientcmd.BuildConfigFromFlags("", config.AgentConfig.KubeConfigNode)
restConfig, err := clientcmd.BuildConfigFromFlags("", nodeConfig.AgentConfig.KubeConfigNode)
if err != nil {
return err
}
@ -79,7 +101,7 @@ func Run(ctx context.Context, config *config.Node) error {
}
go func() {
err := flannel(ctx, config.FlannelIface, config.FlannelConf, config.AgentConfig.KubeConfigNode)
err := flannel(ctx, nodeConfig.FlannelIface, nodeConfig.FlannelConf, nodeConfig.AgentConfig.KubeConfigNode)
logrus.Fatalf("flannel exited: %v", err)
}()
@ -94,10 +116,53 @@ func createCNIConf(dir string) error {
return util.WriteFile(p, cniConf)
}
func createFlannelConf(config *config.Node) error {
if config.FlannelConf == "" {
func createFlannelConf(nodeConfig *config.Node) error {
if nodeConfig.FlannelConf == "" {
return nil
}
return util.WriteFile(config.FlannelConf,
strings.Replace(netJSON, "%CIDR%", config.AgentConfig.ClusterCIDR.String(), -1))
if nodeConfig.FlannelConfOverride {
logrus.Infof("Using custom flannel conf defined at %s", nodeConfig.FlannelConf)
return nil
}
confJSON := strings.Replace(flannelConf, "%CIDR%", nodeConfig.AgentConfig.ClusterCIDR.String(), -1)
var backendConf string
switch nodeConfig.FlannelBackend {
case config.FlannelBackendVXLAN:
backendConf = vxlanBackend
case config.FlannelBackendIPSEC:
backendConf = strings.Replace(ipsecBackend, "%psk%", nodeConfig.AgentConfig.IPSECPSK, -1)
if err := setupStrongSwan(nodeConfig); err != nil {
return err
}
case config.FlannelBackendWireguard:
backendConf = wireguardBackend
default:
return fmt.Errorf("Cannot configure unknown flannel backend '%s'", nodeConfig.FlannelBackend)
}
confJSON = strings.Replace(confJSON, "%backend%", backendConf, -1)
return util.WriteFile(nodeConfig.FlannelConf, confJSON)
}
func setupStrongSwan(nodeConfig *config.Node) error {
// if we don't know the location of extracted strongswan data then return
dataDir := os.Getenv("K3S_DATA_DIR")
if dataDir == "" {
return nil
}
dataDir = path.Join(dataDir, "etc", "strongswan")
info, err := os.Lstat(nodeConfig.AgentConfig.StrongSwanDir)
// something exists but is not a symlink, return
if err == nil && info.Mode()&os.ModeSymlink == 0 {
return nil
}
// clean up strongswan old link
os.Remove(nodeConfig.AgentConfig.StrongSwanDir)
// make new strongswan link
return os.Symlink(dataDir, nodeConfig.AgentConfig.StrongSwanDir)
}

View File

@ -22,6 +22,7 @@ type Agent struct {
ContainerRuntimeEndpoint string
NoFlannel bool
FlannelIface string
FlannelConf string
Debug bool
Rootless bool
AgentShared
@ -64,6 +65,11 @@ var (
Usage: "(agent) Override default flannel interface",
Destination: &AgentConfig.FlannelIface,
}
FlannelConfFlag = cli.StringFlag{
Name: "flannel-conf",
Usage: "(agent) (experimental) Override default flannel config file",
Destination: &AgentConfig.FlannelConf,
}
CRIEndpointFlag = cli.StringFlag{
Name: "container-runtime-endpoint",
Usage: "(agent) Disable embedded containerd and use alternative CRI implementation",
@ -151,6 +157,7 @@ func NewAgentCommand(action func(ctx *cli.Context) error) cli.Command {
DockerFlag,
FlannelFlag,
FlannelIfaceFlag,
FlannelConfFlag,
NodeNameFlag,
NodeIPFlag,
CRIEndpointFlag,

View File

@ -1,6 +1,9 @@
package cmds
import (
"fmt"
"github.com/rancher/k3s/pkg/daemons/config"
"github.com/urfave/cli"
)
@ -30,6 +33,7 @@ type Server struct {
AdvertiseIP string
AdvertisePort int
DisableScheduler bool
FlannelBackend string
}
var ServerConfig Server
@ -189,11 +193,18 @@ func NewServerCommand(action func(*cli.Context) error) cli.Command {
Usage: "Disable Kubernetes default scheduler",
Destination: &ServerConfig.DisableScheduler,
},
cli.StringFlag{
Name: "flannel-backend",
Usage: fmt.Sprintf("(experimental) One of '%s', '%s', '%s', or '%s'", config.FlannelBackendNone, config.FlannelBackendVXLAN, config.FlannelBackendIPSEC, config.FlannelBackendWireguard),
Destination: &ServerConfig.FlannelBackend,
Value: config.FlannelBackendVXLAN,
},
NodeIPFlag,
NodeNameFlag,
DockerFlag,
FlannelFlag,
FlannelIfaceFlag,
FlannelConfFlag,
CRIEndpointFlag,
PauseImageFlag,
ResolvConfFlag,

View File

@ -84,6 +84,7 @@ func run(app *cli.Context, cfg *cmds.Server) error {
serverConfig.ControlConfig.AdvertiseIP = cfg.AdvertiseIP
serverConfig.ControlConfig.AdvertisePort = cfg.AdvertisePort
serverConfig.ControlConfig.BootstrapReadOnly = !cfg.StoreBootstrap
serverConfig.ControlConfig.FlannelBackend = cfg.FlannelBackend
if cmds.AgentConfig.FlannelIface != "" && cmds.AgentConfig.NodeIP == "" {
cmds.AgentConfig.NodeIP = netutil.GetIPFromInterface(cmds.AgentConfig.FlannelIface)

View File

@ -13,11 +13,20 @@ import (
"k8s.io/apiserver/pkg/authentication/authenticator"
)
const (
FlannelBackendNone = "none"
FlannelBackendVXLAN = "vxlan"
FlannelBackendIPSEC = "ipsec"
FlannelBackendWireguard = "wireguard"
)
type Node struct {
Docker bool
ContainerRuntimeEndpoint string
NoFlannel bool
FlannelBackend string
FlannelConf string
FlannelConfOverride bool
FlannelIface *net.Interface
Containerd Containerd
Images string
@ -65,6 +74,8 @@ type Agent struct {
CNIPlugin bool
NodeTaints []string
NodeLabels []string
IPSECPSK string
StrongSwanDir string
}
type Control struct {
@ -89,6 +100,8 @@ type Control struct {
ExtraControllerArgs []string
ExtraSchedulerAPIArgs []string
NoLeaderElect bool
FlannelBackend string
IPSECPSK string
Runtime *ControlRuntime `json:"-"`
}
@ -105,6 +118,7 @@ type ControlRuntimeBootstrap struct {
ClientKubeletKey string
ClientKubeProxyKey string
ServingKubeletKey string
IPSECKey string
}
type ControlRuntime struct {

View File

@ -62,6 +62,11 @@ users:
`))
)
const (
userTokenSize = 16
ipsecTokenSize = 48
)
func Server(ctx context.Context, cfg *config.Control) error {
rand.Seed(time.Now().UTC().UnixNano())
@ -252,6 +257,7 @@ func prepare(ctx context.Context, config *config.Control, runtime *config.Contro
runtime.ServerCAKey = path.Join(config.DataDir, "tls", "server-ca.key")
runtime.RequestHeaderCA = path.Join(config.DataDir, "tls", "request-header-ca.crt")
runtime.RequestHeaderCAKey = path.Join(config.DataDir, "tls", "request-header-ca.key")
runtime.IPSECKey = path.Join(config.DataDir, "cred", "ipsec.psk")
runtime.ServiceKey = path.Join(config.DataDir, "tls", "service.key")
runtime.PasswdFile = path.Join(config.DataDir, "cred", "passwd")
@ -304,6 +310,10 @@ func prepare(ctx context.Context, config *config.Control, runtime *config.Contro
return err
}
if err := genEncryptedNetworkInfo(config, runtime); err != nil {
return err
}
if err := storeBootstrapData(ctx, config, etcdClient); err != nil {
return err
}
@ -422,20 +432,43 @@ func WritePasswords(passwdFile string, records [][]string) error {
return os.Rename(passwdFile+".tmp", passwdFile)
}
func genEncryptedNetworkInfo(controlConfig *config.Control, runtime *config.ControlRuntime) error {
if s, err := os.Stat(runtime.IPSECKey); err == nil && s.Size() > 0 {
psk, err := ioutil.ReadFile(runtime.IPSECKey)
if err != nil {
return err
}
controlConfig.IPSECPSK = strings.TrimSpace(string(psk))
return nil
}
psk, err := getToken(ipsecTokenSize)
if err != nil {
return err
}
controlConfig.IPSECPSK = psk
if err := ioutil.WriteFile(runtime.IPSECKey, []byte(psk+"\n"), 0600); err != nil {
return err
}
return nil
}
func genUsers(config *config.Control, runtime *config.ControlRuntime) error {
if s, err := os.Stat(runtime.PasswdFile); err == nil && s.Size() > 0 {
return ensureNodeToken(config, runtime)
}
adminToken, err := getToken()
adminToken, err := getToken(userTokenSize)
if err != nil {
return err
}
systemToken, err := getToken()
systemToken, err := getToken(userTokenSize)
if err != nil {
return err
}
nodeToken, err := getToken()
nodeToken, err := getToken(userTokenSize)
if err != nil {
return err
}
@ -451,8 +484,8 @@ func genUsers(config *config.Control, runtime *config.ControlRuntime) error {
})
}
func getToken() (string, error) {
token := make([]byte, 16, 16)
func getToken(size int) (string, error) {
token := make([]byte, size, size)
_, err := cryptorand.Read(token)
if err != nil {
return "", err

View File

@ -16,3 +16,5 @@ mkdir -p bin/aux && rm bin/mount && ln -sf ../busybox bin/aux/mount
TRAEFIK_FILE=traefik-${TRAEFIK_VERSION}.tgz
curl -sfL https://kubernetes-charts.storage.googleapis.com/${TRAEFIK_FILE} -o ${CHARTS_DIR}/${TRAEFIK_FILE}
cp scripts/wg-add.sh bin/aux/

View File

@ -22,7 +22,7 @@ rm -rf build/data
mkdir -p build/data build/out
mkdir -p dist/artifacts
tar cvzf ./build/out/data.tar.gz --exclude ./bin/hyperkube ./bin
tar cvzf ./build/out/data.tar.gz --exclude ./bin/hyperkube ./bin ./etc
HASH=$(sha256sum ./build/out/data.tar.gz | awk '{print $1}')
cp ./build/out/data.tar.gz ./build/data/${HASH}.tgz

34
scripts/wg-add.sh Executable file
View File

@ -0,0 +1,34 @@
#!/usr/bin/env bash
auto-mtu() {
local mtu=0 endpoint output
while read -r _ endpoint; do
[[ $endpoint =~ ^\[?([a-z0-9:.]+)\]?:[0-9]+$ ]] || continue
output="$(ip route get "${BASH_REMATCH[1]}" || true)"
[[ ( $output =~ mtu\ ([0-9]+) || ( $output =~ dev\ ([^ ]+) && $(ip link show dev "${BASH_REMATCH[1]}") =~ mtu\ ([0-9]+) ) ) && ${BASH_REMATCH[1]} -gt $mtu ]] && mtu="${BASH_REMATCH[1]}"
done < <(wg show "$1" endpoints)
if [[ $mtu -eq 0 ]]; then
read -r output < <(ip route show default || true) || true
[[ ( $output =~ mtu\ ([0-9]+) || ( $output =~ dev\ ([^ ]+) && $(ip link show dev "${BASH_REMATCH[1]}") =~ mtu\ ([0-9]+) ) ) && ${BASH_REMATCH[1]} -gt $mtu ]] && mtu="${BASH_REMATCH[1]}"
fi
[[ $mtu -gt 0 ]] || mtu=1500
ip link set mtu $(( mtu - 80 )) up dev "$1"
}
# probe for any modules that may be needed
modprobe wireguard
modprobe tun
# try wireguard kernel module first
ip link add "$1" type wireguard && exit
# try boringtun and let it drop privileges
boringtun "$1" && auto-mtu "$1" && exit
# try boringtun w/o dropping privileges
WG_SUDO=1 boringtun "$1" && auto-mtu "$1" && exit
# try wireguard-go - p.s. should not use wireguard-go, it leaks memory
WG_I_PREFER_BUGGY_USERSPACE_TO_POLISHED_KMOD=1 wireguard-go "$1" && auto-mtu "$1" && exit
exit 1

View File

@ -0,0 +1 @@
*.swp

View File

@ -0,0 +1,16 @@
language: go
services:
- docker
go:
- "1.11.x"
before_script:
- docker-compose up -d strongswan
script:
- docker-compose run app go test -v ./...
after_script:
- docker-compose down -v

View File

@ -0,0 +1,7 @@
# Docker image for building the Go app
FROM golang:latest
WORKDIR /app
ADD . /app
RUN GO111MODULE=on go mod download

20
vendor/github.com/bronze1man/goStrongswanVici/LICENSE generated vendored Normal file
View File

@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2015 bronze1man
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

167
vendor/github.com/bronze1man/goStrongswanVici/README.md generated vendored Normal file
View File

@ -0,0 +1,167 @@
strongswan vici golang client
=============================
[![Build Status](https://travis-ci.org/bronze1man/goStrongswanVici.svg)](https://travis-ci.org/bronze1man/goStrongswanVici)
[![GoDoc](https://godoc.org/github.com/bronze1man/goStrongswanVici?status.svg)](https://godoc.org/github.com/bronze1man/goStrongswanVici)
[![docs examples](https://sourcegraph.com/api/repos/github.com/bronze1man/goStrongswanVici/badges/docs-examples.png)](https://sourcegraph.com/github.com/bronze1man/goStrongswanVici)
[![Total views](https://sourcegraph.com/api/repos/github.com/bronze1man/goStrongswanVici/counters/views.png)](https://sourcegraph.com/github.com/bronze1man/goStrongswanVici)
[![GitHub issues](https://img.shields.io/github/issues/bronze1man/goStrongswanVici.svg)](https://github.com/bronze1man/goStrongswanVici/issues)
[![GitHub stars](https://img.shields.io/github/stars/bronze1man/goStrongswanVici.svg)](https://github.com/bronze1man/goStrongswanVici/stargazers)
[![GitHub forks](https://img.shields.io/github/forks/bronze1man/goStrongswanVici.svg)](https://github.com/bronze1man/goStrongswanVici/network)
[![MIT License](http://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](https://github.com/bronze1man/goStrongswanVici/blob/master/LICENSE)
a golang implement of strongswan vici plugin client.
### document
* http://godoc.org/github.com/bronze1man/goStrongswanVici
* https://github.com/strongswan/strongswan/tree/master/src/libcharon/plugins/vici
### Implemented command list
* version()
* list-sas()
* get-shared()
* terminate()
* load-conn()
* load-cert()
* load-key()
* load-pool()
* load-shared()
* list-conns()
* unload-conn()
* unload-shared()
If you need some commands, but it is not here .you can implement yourself, and send a pull request to this project.
### Testing
To test the library's functionality, `docker-compose` is used to spin up strongswan in a separate Docker container.
```bash
$ docker-compose up -V
Creating network "gostrongswanvici_default" with the default drive
Creating volume "gostrongswanvici_charondata" with default driver
Creating gostrongswanvici_strongswan_1 ... done
Creating gostrongswanvici_go-test_1 ... done
Attaching to gostrongswanvici_strongswan_1, gostrongswanvici_go-test_1
...
go-test_1 | ok github.com/RenaultAI/goStrongswanVici 0.017s
gostrongswanvici_go-test_1 exited with code 0
```
### example
```go
package main
import (
"fmt"
"github.com/bronze1man/goStrongswanVici"
)
func main(){
// create a client.
client, err := goStrongswanVici.NewClientConnFromDefaultSocket()
if err != nil {
panic(err)
}
defer client.Close()
// get strongswan version
v, err := client.Version()
if err != nil {
panic(err)
}
fmt.Printf("%#v\n", v)
childConfMap := make(map[string]goStrongswanVici.ChildSAConf)
childSAConf := goStrongswanVici.ChildSAConf{
Local_ts: []string{"10.10.59.0/24"},
Remote_ts: []string{"10.10.40.0/24"},
ESPProposals: []string{"aes256-sha256-modp2048"},
StartAction: "trap",
CloseAction: "restart",
Mode: "tunnel",
ReqID: "10",
RekeyTime: "10m",
InstallPolicy: "no",
}
childConfMap["test-child-conn"] = childSAConf
localAuthConf := goStrongswanVici.AuthConf{
AuthMethod: "psk",
}
remoteAuthConf := goStrongswanVici.AuthConf{
AuthMethod: "psk",
}
ikeConfMap := make(map[string] goStrongswanVici.IKEConf)
ikeConf := goStrongswanVici.IKEConf{
LocalAddrs: []string{"192.168.198.10"},
RemoteAddrs: []string{"192.168.198.11"},
Proposals: []string{"aes256-sha256-modp2048"},
Version: "1",
LocalAuth: localAuthConf,
RemoteAuth: remoteAuthConf,
Children: childConfMap,
Encap: "no",
}
ikeConfMap["test-connection"] = ikeConf
//load connenction information into strongswan
err = client.LoadConn(&ikeConfMap)
if err != nil {
fmt.Printf("error loading connection: %v")
panic(err)
}
sharedKey := &goStrongswanVici.Key{
Typ: "IKE",
Data: "this is the key",
Owners: []string{"192.168.198.10"}, //IP of the remote host
}
//load shared key into strongswan
err = client.LoadShared(sharedKey)
if err != nil {
fmt.Printf("error returned from loadsharedkey \n")
panic(err)
}
//list-conns
connList, err := client.ListConns("")
if err != nil {
fmt.Printf("error list-conns: %v \n", err)
}
for _, connection := range connList {
fmt.Printf("connection map: %v", connection)
}
// get all conns info from strongswan
connInfo, err := client.ListAllVpnConnInfo()
if err != nil {
panic(err)
}
fmt.Printf("found %d connections. \n", len(connInfo))
//unload connection from strongswan
unloadConnReq := &goStrongswanVici.UnloadConnRequest{
Name: "test-connection",
}
err = client.UnloadConn(unloadConnReq)
if err != nil {
panic(err)
}
// kill all conns in strongswan
for _, info := range connInfo {
fmt.Printf("kill connection id %s\n", info.Uniqueid)
err = client.Terminate(&goStrongswanVici.TerminateRequest{
Ike_id: info.Uniqueid,
})
if err != nil {
panic(err)
}
}
}
```

View File

@ -0,0 +1,79 @@
package goStrongswanVici
import (
"net"
)
type ClientOptions struct {
Network string
Addr string
// Dialer creates new network connection and has priority over
// Network and Addr options.
Dialer func() (net.Conn, error)
}
type Client struct {
o ClientOptions
}
func NewClient(options ClientOptions) (client *Client) {
if options.Dialer == nil {
options.Dialer = func() (net.Conn, error) {
return net.Dial(options.Network, options.Addr)
}
}
return &Client{
o: options,
}
}
func NewClientFromDefaultSocket() (client *Client) {
return NewClient(ClientOptions{
Network: "unix",
Addr: "/var/run/charon.vici",
})
}
func (c *Client) NewConn() (conn *ClientConn, err error) {
conn1, err := c.o.Dialer()
if err != nil {
return nil, err
}
return NewClientConn(conn1), nil
}
func (c *Client) ListSas(ike string, ike_id string) (sas []map[string]IkeSa, err error) {
conn, err := c.NewConn()
if err != nil {
return nil, err
}
defer conn.Close()
return conn.ListSas(ike, ike_id)
}
func (c *Client) ListAllVpnConnInfo() (list []VpnConnInfo, err error) {
conn, err := c.NewConn()
if err != nil {
return nil, err
}
defer conn.Close()
return conn.ListAllVpnConnInfo()
}
func (c *Client) Version() (out *Version, err error) {
conn, err := c.NewConn()
if err != nil {
return nil, err
}
defer conn.Close()
return conn.Version()
}
func (c *Client) Terminate(r *TerminateRequest) (err error) {
conn, err := c.NewConn()
if err != nil {
return err
}
defer conn.Close()
return conn.Terminate(r)
}

View File

@ -0,0 +1,154 @@
package goStrongswanVici
import (
"fmt"
"io"
"net"
"time"
)
const (
DefaultReadTimeout = 15 * time.Second
)
// This object is not thread safe.
// if you want concurrent, you need create more clients.
type ClientConn struct {
conn net.Conn
responseChan chan segment
eventHandlers map[string]func(response map[string]interface{})
lastError error
// ReadTimeout specifies a time limit for requests made
// by this client.
ReadTimeout time.Duration
}
func (c *ClientConn) Close() error {
close(c.responseChan)
c.lastError = io.ErrClosedPipe
return c.conn.Close()
}
func NewClientConn(conn net.Conn) (client *ClientConn) {
client = &ClientConn{
conn: conn,
responseChan: make(chan segment, 2),
eventHandlers: map[string]func(response map[string]interface{}){},
ReadTimeout: DefaultReadTimeout,
}
go client.readThread()
return client
}
// it dial from unix:///var/run/charon.vici
func NewClientConnFromDefaultSocket() (client *ClientConn, err error) {
conn, err := net.Dial("unix", "/var/run/charon.vici")
if err != nil {
return
}
return NewClientConn(conn), nil
}
func (c *ClientConn) Request(apiname string, request map[string]interface{}) (response map[string]interface{}, err error) {
err = writeSegment(c.conn, segment{
typ: stCMD_REQUEST,
name: apiname,
msg: request,
})
if err != nil {
fmt.Printf("error writing segment \n")
return
}
outMsg := c.readResponse()
if c.lastError != nil {
return nil, c.lastError
}
if outMsg.typ != stCMD_RESPONSE {
return nil, fmt.Errorf("[%s] response error %d", apiname, outMsg.typ)
}
return outMsg.msg, nil
}
func (c *ClientConn) readResponse() segment {
select {
case outMsg := <-c.responseChan:
return outMsg
case <-time.After(c.ReadTimeout):
if c.lastError == nil {
c.lastError = fmt.Errorf("Timeout waiting for message response")
}
return segment{}
}
}
func (c *ClientConn) RegisterEvent(name string, handler func(response map[string]interface{})) (err error) {
if c.eventHandlers[name] != nil {
return fmt.Errorf("[event %s] register a event twice.", name)
}
c.eventHandlers[name] = handler
err = writeSegment(c.conn, segment{
typ: stEVENT_REGISTER,
name: name,
})
if err != nil {
delete(c.eventHandlers, name)
return
}
outMsg := c.readResponse()
//fmt.Printf("registerEvent %#v\n", outMsg)
if c.lastError != nil {
delete(c.eventHandlers, name)
return c.lastError
}
if outMsg.typ != stEVENT_CONFIRM {
delete(c.eventHandlers, name)
return fmt.Errorf("[event %s] response error %d", name, outMsg.typ)
}
return nil
}
func (c *ClientConn) UnregisterEvent(name string) (err error) {
err = writeSegment(c.conn, segment{
typ: stEVENT_UNREGISTER,
name: name,
})
if err != nil {
return
}
outMsg := c.readResponse()
//fmt.Printf("UnregisterEvent %#v\n", outMsg)
if c.lastError != nil {
return c.lastError
}
if outMsg.typ != stEVENT_CONFIRM {
return fmt.Errorf("[event %s] response error %d", name, outMsg.typ)
}
delete(c.eventHandlers, name)
return nil
}
func (c *ClientConn) readThread() {
for {
outMsg, err := readSegment(c.conn)
if err != nil {
c.lastError = err
return
}
switch outMsg.typ {
case stCMD_RESPONSE, stEVENT_CONFIRM:
c.responseChan <- outMsg
case stEVENT:
handler := c.eventHandlers[outMsg.name]
if handler != nil {
handler(outMsg.msg)
}
default:
c.lastError = fmt.Errorf("[Client.readThread] unknow msg type %d", outMsg.typ)
return
}
}
}

5
vendor/github.com/bronze1man/goStrongswanVici/doc.go generated vendored Normal file
View File

@ -0,0 +1,5 @@
/*
a golang implement of strongswan vici plugin client.
https://github.com/strongswan/strongswan/tree/master/src/libcharon/plugins/vici
*/
package goStrongswanVici

View File

@ -0,0 +1,22 @@
version: '3.3'
services:
strongswan:
image: philplckthun/strongswan
ports:
- "500:500/udp"
- "4500:4500/udp"
- "1701:1701/udp"
privileged: true
volumes:
- "charondata:/var/run"
app:
build: .
volumes:
- ".:/app"
- "charondata:/var/run"
depends_on:
- strongswan
volumes:
charondata:

24
vendor/github.com/bronze1man/goStrongswanVici/err.go generated vendored Normal file
View File

@ -0,0 +1,24 @@
package goStrongswanVici
import (
"fmt"
)
func handlePanic(f func() error) (err error) {
defer func() {
r := recover()
//no panic
if r == nil {
return
}
//panic a error
if e, ok := r.(error); ok {
err = e
return
}
//panic another stuff
err = fmt.Errorf("%s", r)
}()
err = f()
return
}

7
vendor/github.com/bronze1man/goStrongswanVici/go.mod generated vendored Normal file
View File

@ -0,0 +1,7 @@
module github.com/bronze1man/goStrongswanVici
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/stretchr/testify v1.2.2
)

6
vendor/github.com/bronze1man/goStrongswanVici/go.sum generated vendored Normal file
View File

@ -0,0 +1,6 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=

View File

@ -0,0 +1,25 @@
package goStrongswanVici
import (
"fmt"
)
// Initiate is used to initiate an SA. This is the
// equivalent of `swanctl --initiate -c childname`
func (c *ClientConn) Initiate(child string, ike string) (err error) {
inMap := map[string]interface{}{}
if child != "" {
inMap["child"] = child
}
if ike != "" {
inMap["ike"] = ike
}
msg, err := c.Request("initiate", inMap)
if err != nil {
return err
}
if msg["success"] != "yes" {
return fmt.Errorf("unsuccessful Initiate: %v", msg["errmsg"])
}
return nil
}

View File

@ -0,0 +1,47 @@
package goStrongswanVici
import (
"fmt"
)
func (c *ClientConn) ListConns(ike string) ([]map[string]IKEConf, error) {
conns := []map[string]IKEConf{}
var eventErr error
var err error
err = c.RegisterEvent("list-conn", func(response map[string]interface{}) {
conn := &map[string]IKEConf{}
err = ConvertFromGeneral(response, conn)
if err != nil {
eventErr = fmt.Errorf("list-conn event error: %v", err)
return
}
conns = append(conns, *conn)
})
if err != nil {
return nil, fmt.Errorf("error registering list-conn event: %v", err)
}
if eventErr != nil {
return nil, eventErr
}
reqMap := map[string]interface{}{}
if ike != "" {
reqMap["ike"] = ike
}
_, err = c.Request("list-conns", reqMap)
if err != nil {
return nil, fmt.Errorf("error requesting list-conns: %v", err)
}
err = c.UnregisterEvent("list-conn")
if err != nil {
return nil, fmt.Errorf("error unregistering list-conns event: %v", err)
}
return conns, nil
}

View File

@ -0,0 +1,176 @@
package goStrongswanVici
import (
"fmt"
"strconv"
)
//from list-sa event
type IkeSa struct {
Uniqueid string `json:"uniqueid"` //called ike_id in terminate() argument.
Version string `json:"version"`
State string `json:"state"` //had saw: ESTABLISHED
Local_host string `json:"local-host"`
Local_port string `json:"local-port"`
Local_id string `json:"local-id"`
Remote_host string `json:"remote-host"`
Remote_port string `json:"remote-port"`
Remote_id string `json:"remote-id"`
Remote_xauth_id string `json:"remote-xauth-id"` //client username
Initiator string `json:"initiator"`
Initiator_spi string `json:"initiator-spi"`
Responder_spi string `json:"responder-spi"`
Encr_alg string `json:"encr-alg"`
Encr_keysize string `json:"encr-keysize"`
Integ_alg string `json:"integ-alg"`
Integ_keysize string `json:"integ-keysize"`
Prf_alg string `json:"prf-alg"`
Dh_group string `json:"dh-group"`
Established string `json:"established"`
Rekey_time string `json:"rekey-time"`
Reauth_time string `json:"reauth-time"`
Remote_vips []string `json:"remote-vips"`
Child_sas map[string]Child_sas `json:"child-sas"` //key means child-sa-name(conn name in ipsec.conf)
}
type Child_sas struct {
Reqid string `json:"reqid"`
State string `json:"state"` //had saw: INSTALLED
Mode string `json:"mode"` //had saw: TUNNEL
Protocol string `json:"protocol"`
Encap string `json:"encap"`
Spi_in string `json:"spi-in"`
Spi_out string `json:"spi-out"`
Cpi_in string `json:"cpi-in"`
Cpi_out string `json:"cpi-out"`
Encr_alg string `json:"encr-alg"`
Encr_keysize string `json:"encr-keysize"`
Integ_alg string `json:"integ-alg"`
Integ_keysize string `json:"integ-keysize"`
Prf_alg string `json:"prf-alg"`
Dh_group string `json:"dh-group"`
Esn string `json:"esn"`
Bytes_in string `json:"bytes-in"` //bytes into this machine
Packets_in string `json:"packets-in"`
Use_in string `json:"use-in"`
Bytes_out string `json:"bytes-out"` // bytes out of this machine
Packets_out string `json:"packets-out"`
Use_out string `json:"use-out"`
Rekey_time string `json:"rekey-time"`
Life_time string `json:"life-time"`
Install_time string `json:"install-time"`
Local_ts []string `json:"local-ts"`
Remote_ts []string `json:"remote-ts"`
}
func (s *Child_sas) GetBytesIn() uint64 {
num, err := strconv.ParseUint(s.Bytes_in, 10, 64)
if err != nil {
return 0
}
return num
}
func (s *Child_sas) GetBytesOut() uint64 {
num, err := strconv.ParseUint(s.Bytes_out, 10, 64)
if err != nil {
return 0
}
return num
}
// To be simple, list all clients that are connecting to this server .
// A client is a sa.
// Lists currently active IKE_SAs
func (c *ClientConn) ListSas(ike string, ike_id string) (sas []map[string]IkeSa, err error) {
sas = []map[string]IkeSa{}
var eventErr error
//register event
err = c.RegisterEvent("list-sa", func(response map[string]interface{}) {
sa := &map[string]IkeSa{}
err = ConvertFromGeneral(response, sa)
if err != nil {
fmt.Printf("list-sa event error: %s\n", err)
eventErr = err
return
}
sas = append(sas, *sa)
//fmt.Printf("event %#v\n", response)
})
if err != nil {
return
}
if eventErr != nil {
return
}
inMap := map[string]interface{}{}
if ike != "" {
inMap["ike"] = ike
}
if ike_id != "" {
inMap["ike_id"] = ike_id
}
_, err = c.Request("list-sas", inMap)
if err != nil {
return
}
//fmt.Printf("request finish %#v\n", sas)
err = c.UnregisterEvent("list-sa")
if err != nil {
return
}
return
}
//a vpn conn in the strongswan server
type VpnConnInfo struct {
IkeSa
Child_sas
IkeSaName string //looks like conn name in ipsec.conf, content is same as ChildSaName
ChildSaName string //looks like conn name in ipsec.conf
}
func (c *VpnConnInfo) GuessUserName() string {
if c.Remote_xauth_id != "" {
return c.Remote_xauth_id
}
if c.Remote_id != "" {
return c.Remote_id
}
return ""
}
// a helper method to avoid complex data struct in ListSas
// if it only have one child_sas ,it will put it into info.Child_sas
func (c *ClientConn) ListAllVpnConnInfo() (list []VpnConnInfo, err error) {
sasList, err := c.ListSas("", "")
if err != nil {
return
}
list = make([]VpnConnInfo, len(sasList))
for i, sa := range sasList {
info := VpnConnInfo{}
if len(sa) != 1 {
fmt.Printf("[vici.ListAllVpnConnInfo] warning: len(sa)[%d]!=1\n", len(sa))
}
for ikeSaName, ikeSa := range sa {
info.IkeSaName = ikeSaName
info.IkeSa = ikeSa
//if len(ikeSa.Child_sas) != 1 {
// fmt.Println("[vici.ListAllVpnConnInfo] warning: len(ikeSa.Child_sas)[%d]!=1", len(ikeSa.Child_sas))
//}
for childSaName, childSa := range ikeSa.Child_sas {
info.ChildSaName = childSaName
info.Child_sas = childSa
break
}
break
}
if len(info.IkeSa.Child_sas) == 1 {
info.IkeSa.Child_sas = nil
}
list[i] = info
}
return
}

View File

@ -0,0 +1,37 @@
package goStrongswanVici
import (
"fmt"
)
type certPayload struct {
Typ string `json:"type"` // (X509|X509_AC|X509_CRL)
Flag string `json:"flag"` // (CA|AA|OCSP|NONE)
Data string `json:"data"`
}
func (c *ClientConn) LoadCertificate(s string, typ string, flag string) (err error) {
requestMap := &map[string]interface{}{}
var k = certPayload{
Typ: typ,
Flag: flag,
Data: s,
}
if err = ConvertToGeneral(k, requestMap); err != nil {
return fmt.Errorf("error creating request: %v", err)
}
msg, err := c.Request("load-cert", *requestMap)
if err != nil {
return fmt.Errorf("unsuccessful loadCert: %v", err.Error())
}
if msg["success"] != "yes" {
return fmt.Errorf("unsuccessful loadCert: %v", msg["success"])
}
return nil
}

View File

@ -0,0 +1,68 @@
package goStrongswanVici
import (
"fmt"
)
type Connection struct {
ConnConf map[string]IKEConf `json:"connections"`
}
type IKEConf struct {
LocalAddrs []string `json:"local_addrs"`
RemoteAddrs []string `json:"remote_addrs,omitempty"`
Proposals []string `json:"proposals,omitempty"`
Version string `json:"version"` //1 for ikev1, 0 for ikev1 & ikev2
Encap string `json:"encap"` //yes,no
KeyingTries string `json:"keyingtries"`
RekeyTime string `json:"rekey_time"`
DPDDelay string `json:"dpd_delay,omitempty"`
LocalAuth AuthConf `json:"local"`
RemoteAuth AuthConf `json:"remote"`
Pools []string `json:"pools,omitempty"`
Children map[string]ChildSAConf `json:"children"`
}
type AuthConf struct {
ID string `json:"id"`
Round string `json:"round,omitempty"`
AuthMethod string `json:"auth"` // (psk|pubkey)
EAP_ID string `json:"eap_id,omitempty"`
}
type ChildSAConf struct {
Local_ts []string `json:"local_ts"`
Remote_ts []string `json:"remote_ts"`
ESPProposals []string `json:"esp_proposals,omitempty"` //aes128-sha1_modp1024
StartAction string `json:"start_action"` //none,trap,start
CloseAction string `json:"close_action"`
ReqID string `json:"reqid,omitempty"`
RekeyTime string `json:"rekey_time"`
ReplayWindow string `json:"replay_window,omitempty"`
Mode string `json:"mode"`
InstallPolicy string `json:"policies"`
UpDown string `json:"updown,omitempty"`
Priority string `json:"priority,omitempty"`
MarkIn string `json:"mark_in,omitempty"`
MarkOut string `json:"mark_out,omitempty"`
DpdAction string `json:"dpd_action,omitempty"`
LifeTime string `json:"life_time,omitempty"`
}
func (c *ClientConn) LoadConn(conn *map[string]IKEConf) error {
requestMap := &map[string]interface{}{}
err := ConvertToGeneral(conn, requestMap)
if err != nil {
return fmt.Errorf("error creating request: %v", err)
}
msg, err := c.Request("load-conn", *requestMap)
if msg["success"] != "yes" {
return fmt.Errorf("unsuccessful LoadConn: %v", msg["errmsg"])
}
return nil
}

View File

@ -0,0 +1,66 @@
package goStrongswanVici
import (
"crypto/ecdsa"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"fmt"
)
type keyPayload struct {
Typ string `json:"type"`
Data string `json:"data"`
}
// LoadECDSAPrivateKey encodes a *ecdsa.PrivateKey as a PEM block before sending
// it to the Vici interface
func (c *ClientConn) LoadECDSAPrivateKey(key *ecdsa.PrivateKey) error {
mk, err := x509.MarshalECPrivateKey(key)
if err != nil {
return err
}
var pemData = pem.EncodeToMemory(&pem.Block{
Type: "ECDSA PRIVATE KEY",
Bytes: mk,
})
return c.loadPrivateKey("ECDSA", string(pemData))
}
// LoadRSAPrivateKey encodes a *rsa.PrivateKey as a PEM block before sending
// it to the Vici interface
func (c *ClientConn) LoadRSAPrivateKey(key *rsa.PrivateKey) error {
var mk = x509.MarshalPKCS1PrivateKey(key)
var pemData = pem.EncodeToMemory(&pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: mk,
})
return c.loadPrivateKey("RSA", string(pemData))
}
// loadPrivateKey expects typ to be (RSA|ECDSA) and a PEM encoded data as a
// string
func (c *ClientConn) loadPrivateKey(typ, data string) (err error) {
requestMap := &map[string]interface{}{}
var k = keyPayload{
Typ: typ,
Data: data,
}
if err = ConvertToGeneral(k, requestMap); err != nil {
return fmt.Errorf("error creating request: %v", err)
}
msg, err := c.Request("load-key", *requestMap)
if msg["success"] != "yes" {
return fmt.Errorf("unsuccessful loadPrivateKey: %v", msg["success"])
}
return nil
}

View File

@ -0,0 +1,29 @@
package goStrongswanVici
import (
"encoding/json"
)
//concrete data type to general data type
// concrete data type like *Version
// general data type include map[string]interface{} []string string
// TODO make it faster
func ConvertToGeneral(concrete interface{}, general interface{}) (err error) {
b, err := json.Marshal(concrete)
if err != nil {
return
}
return json.Unmarshal(b, general)
}
// general data type to concrete data type
// concrete data type like *Version
// general data type include map[string]interface{} []string string
// TODO make it faster
func ConvertFromGeneral(general interface{}, concrete interface{}) (err error) {
b, err := json.Marshal(general)
if err != nil {
return
}
return json.Unmarshal(b, concrete)
}

View File

@ -0,0 +1,251 @@
package goStrongswanVici
import (
"bytes"
"encoding/json"
"time"
)
const (
EVENT_IKE_UPDOWN = "ike-updown"
EVENT_IKE_REKEY = "ike-rekey"
EVENT_CHILD_UPDOWN = "child-updown"
EVENT_CHILD_REKEY = "child-rekey"
)
type EventIkeSAUpDown struct {
Child_sas map[string]*EventChildSAUpDown `json:"child-sas"`
Dh_group string `json:"dh-group"`
Encr_keysize string `json:"encr-keysize"`
Encr_alg string `json:"encr-alg"`
Established string `json:"established"`
Initiator_spi string `json:"initiator-spi"`
Integ_alg string `json:"integ-alg"`
Local_id string `json:"local-id"`
Local_host string `json:"local-host"`
Local_port string `json:"local-port"`
Nat_any string `json:"nat-any"`
Nat_remote string `json:"nat-remote"`
Prf_alg string `json:"prf-alg"`
Rekey_time string `json:"rekey-time"`
Remote_id string `json:"remote-id"`
Remote_host string `json:"remote-host"`
Remote_port string `json:"remote-port"`
Responder_spi string `json:"responder-spi"`
State string `json:"state"`
Task_Active []string `json:"tasks-active"`
Uniqueid string `json:"uniqueid"`
Version string `json:"version"`
}
type EventChildSAUpDown struct {
Bytes_in string `json:"bytes-in"`
Bytes_out string `json:"bytes-out"`
Encap string `json:"encap"`
Encr_alg string `json:"encr-alg"`
Encr_keysize string `json:"encr-keysize"`
Integ_alg string `json:"integ-alg"`
Install_time string `json:"install-time"`
Life_time string `json:"life-time"`
Local_ts []string `json:"local-ts"`
Mode string `json:"mode"`
Name string `json:"name"`
Protocol string `json:"protocol"`
Packets_out string `json:"packets-out"`
Packets_in string `json:"packets-in"`
Rekey_time string `json:"rekey-time"`
Remote_ts []string `json:"remote-ts"`
Reqid string `json:"reqid"`
Spi_in string `json:"spi-in"`
Spi_out string `json:"spi-out"`
State string `json:"state"`
UniqueId string `json:"uniqueid"`
}
type EventIkeRekeyPair struct {
New EventIkeRekeySA `json:"new"`
Old EventIkeRekeySA `json:"old"`
}
type EventIkeRekeySA struct {
Child_sas map[string]*EventChildRekeyPair `json:"child-sas"`
Dh_group string `json:"dh-group"`
Encr_alg string `json:"encr-alg"`
Encr_keysize string `json:"encr-keysize"`
Established string `json:"established"`
Initiator_spi string `json:"initiator-spi"`
Integ_alg string `json:"integ-alg"`
Local_host string `json:"local-host"`
Local_port string `json:"local-port"`
Local_id string `json:"local-id"`
Nat_any string `json:"nat-any"`
Nat_remote string `json:"nat-remote"`
Prf_alg string `json:"prf-alg"`
Rekey_time string `json:"rekey-time"`
Remote_id string `json:"remote-id"`
Remote_host string `json:"remote-host"`
Remote_port string `json:"remote-port"`
Responder_spi string `json:"responder-spi"`
State string `json:"state"`
Task_Active []string `json:"tasks-active"`
Task_Passive []string `json:"tasks-passive"`
Uniqueid string `json:"uniqueid"`
Version string `json:"version"`
}
type EventChildRekeyPair struct {
New EventChildRekeySA `json:"new"`
Old EventChildRekeySA `json:"old"`
}
type EventChildRekeySA struct {
Bytes_in string `json:"bytes-in"`
Bytes_out string `json:"bytes-out"`
Encap string `json:"encap"`
Encr_alg string `json:"encr-alg"`
Encr_keysize string `json:"encr-keysize"`
Integ_alg string `json:"integ-alg"`
Install_time string `json:"install-time"`
Life_time string `json:"life-time"`
Local_ts []string `json:"local-ts"`
Mode string `json:"mode"`
Name string `json:"name"`
Packets_in string `json:"packets-in"`
Packets_out string `json:"packets-out"`
Protocol string `json:"protocol"`
Remote_ts []string `json:"remote-ts"`
Rekey_time string `json:"rekey-time"`
Reqid string `json:"reqid"`
Spi_in string `json:"spi-in"`
Spi_out string `json:"spi-out"`
State string `json:"state"`
Use_in string `json:"use-in"`
Use_out string `json:"use-out"`
UniqueId string `json:"uniqueid"`
}
type EventIkeUpDown struct {
Up bool
Ike map[string]*EventIkeSAUpDown
}
type EventIkeRekey struct {
Ike map[string]*EventIkeRekeyPair
}
type EventChildRekey struct {
Ike map[string]*EventIkeRekeySA
}
type EventChildUpDown struct {
Up bool
Ike map[string]*EventIkeSAUpDown
}
type EventIkeSa struct {
IkeSa
TasksActive []string `json:"tasks-active"`
}
type EventInfo struct {
Up bool
Ike map[string]*EventIkeSa
}
func prettyprint(b []byte) string {
var out bytes.Buffer
json.Indent(&out, b, "", " ")
return string(out.Bytes())
}
type monitorCallBack func(event string, info interface{})
func handleIkeUpDown(eventName string, callback monitorCallBack, response map[string]interface{}) {
event := &EventIkeUpDown{}
event.Ike = map[string]*EventIkeSAUpDown{}
//we need to marshall all ikes manual because json uses connections names as key
for name := range response {
value := response[name]
if name == "up" {
event.Up = true
} else {
sa := &EventIkeSAUpDown{}
ConvertFromGeneral(value, sa)
event.Ike[name] = sa
}
}
callback(eventName, event)
}
func handleIkeRekey(eventName string, callback monitorCallBack, response map[string]interface{}) {
event := &EventIkeRekey{}
event.Ike = map[string]*EventIkeRekeyPair{}
//we need to marshall all ikes manual because json uses connections names as key
for name := range response {
value := response[name]
sa := &EventIkeRekeyPair{}
ConvertFromGeneral(value, sa)
event.Ike[name] = sa
}
callback(eventName, event)
}
func handleChildUpDown(eventName string, callback monitorCallBack, response map[string]interface{}) {
event := &EventChildUpDown{}
event.Ike = map[string]*EventIkeSAUpDown{}
//we need to marshall all ikes manual because json uses connections names as key
for name := range response {
value := response[name]
if name == "up" {
event.Up = true
} else {
sa := &EventIkeSAUpDown{}
ConvertFromGeneral(value, sa)
event.Ike[name] = sa
}
}
callback(eventName, event)
}
func handleChildRekey(eventName string, callback monitorCallBack, response map[string]interface{}) {
event := &EventChildRekey{}
event.Ike = map[string]*EventIkeRekeySA{}
//we need to marshall all ikes manual because json uses connections names as key
for name := range response {
value := response[name]
sa := &EventIkeRekeySA{}
ConvertFromGeneral(value, sa)
event.Ike[name] = sa
}
callback(eventName, event)
}
func (c *ClientConn) MonitorSA(callback monitorCallBack,watchdog time.Duration) (err error) {
//register event
c.RegisterEvent(EVENT_CHILD_UPDOWN, func(response map[string]interface{}) {
//dumpResponse(response)
handleChildUpDown(EVENT_CHILD_UPDOWN, callback, response)
})
c.RegisterEvent(EVENT_CHILD_REKEY, func(response map[string]interface{}) {
//dumpResponse(response)
handleChildRekey(EVENT_CHILD_REKEY, callback, response)
})
c.RegisterEvent(EVENT_IKE_UPDOWN, func(response map[string]interface{}) {
//dumpResponse(response)
handleIkeUpDown(EVENT_IKE_UPDOWN, callback, response)
})
c.RegisterEvent(EVENT_IKE_REKEY, func(response map[string]interface{}) {
//dumpResponse(response)
handleIkeRekey(EVENT_IKE_REKEY, callback, response)
})
for {
time.Sleep(watchdog)
//collect some daemon stats to see if connection is alive
if _, err := c.Stats(); err != nil {
return err
}
}
return nil
}

359
vendor/github.com/bronze1man/goStrongswanVici/msg.go generated vendored Normal file
View File

@ -0,0 +1,359 @@
package goStrongswanVici
import (
"bufio"
"bytes"
"encoding/binary"
"fmt"
"io"
"strconv"
)
type segmentType byte
const (
stCMD_REQUEST segmentType = 0
stCMD_RESPONSE = 1
stCMD_UNKNOWN = 2
stEVENT_REGISTER = 3
stEVENT_UNREGISTER = 4
stEVENT_CONFIRM = 5
stEVENT_UNKNOWN = 6
stEVENT = 7
)
func (t segmentType) hasName() bool {
switch t {
case stCMD_REQUEST, stEVENT_REGISTER, stEVENT_UNREGISTER, stEVENT:
return true
}
return false
}
func (t segmentType) isValid() bool {
switch t {
case stCMD_REQUEST, stCMD_RESPONSE, stCMD_UNKNOWN, stEVENT_REGISTER,
stEVENT_UNREGISTER, stEVENT_CONFIRM, stEVENT_UNKNOWN, stEVENT:
return true
}
return false
}
func (t segmentType) hasMsg() bool {
switch t {
case stCMD_REQUEST, stCMD_RESPONSE, stEVENT:
return true
}
return false
}
type elementType byte
const (
etSECTION_START elementType = 1
etSECTION_END = 2
etKEY_VALUE = 3
etLIST_START = 4
etLIST_ITEM = 5
etLIST_END = 6
)
type segment struct {
typ segmentType
name string
msg map[string]interface{}
}
//msg 在内部以下列3种类型表示(降低复杂度)
// string
// map[string]interface{}
// []string
func writeSegment(w io.Writer, msg segment) (err error) {
if !msg.typ.isValid() {
return fmt.Errorf("[writeSegment] msg.typ %d not defined", msg.typ)
}
buf := &bytes.Buffer{}
buf.WriteByte(byte(msg.typ))
//name
if msg.typ.hasName() {
err = writeString1(buf, msg.name)
if err != nil {
fmt.Printf("error returned from writeString1i \n")
return
}
}
if msg.typ.hasMsg() {
err = writeMap(buf, msg.msg)
if err != nil {
fmt.Printf("error retruned from writeMap \n")
return
}
}
//写长度
err = binary.Write(w, binary.BigEndian, uint32(buf.Len()))
if err != nil {
fmt.Printf("[writeSegment] error writing to binary \n")
return
}
_, err = buf.WriteTo(w)
if err != nil {
fmt.Printf("[writeSegment] error writing to buffer \n")
return
}
return nil
}
func readSegment(inR io.Reader) (msg segment, err error) {
//长度
var length uint32
err = binary.Read(inR, binary.BigEndian, &length)
if err != nil {
return
}
r := bufio.NewReader(&io.LimitedReader{
R: inR,
N: int64(length),
})
//类型
c, err := r.ReadByte()
if err != nil {
return
}
msg.typ = segmentType(c)
if !msg.typ.isValid() {
return msg, fmt.Errorf("[readSegment] msg.typ %d not defined", msg.typ)
}
if msg.typ.hasName() {
msg.name, err = readString1(r)
if err != nil {
return
}
}
if msg.typ.hasMsg() {
msg.msg, err = readMap(r, true)
if err != nil {
return
}
}
return
}
//一个字节长度的字符串
func writeString1(w *bytes.Buffer, s string) (err error) {
length := len(s)
if length > 255 {
return fmt.Errorf("[writeString1] length>255")
}
w.WriteByte(byte(length))
w.WriteString(s)
return
}
func readString1(r *bufio.Reader) (s string, err error) {
length, err := r.ReadByte()
if err != nil {
return
}
buf := make([]byte, length)
_, err = io.ReadFull(r, buf)
if err != nil {
return
}
return string(buf), nil
}
//两个字节长度的字符串
func writeString2(w *bytes.Buffer, s string) (err error) {
length := len(s)
if length > 65535 {
return fmt.Errorf("[writeString2] length>65535")
}
binary.Write(w, binary.BigEndian, uint16(length))
w.WriteString(s)
return
}
func readString2(r io.Reader) (s string, err error) {
var length uint16
err = binary.Read(r, binary.BigEndian, &length)
if err != nil {
return
}
buf := make([]byte, length)
_, err = io.ReadFull(r, buf)
if err != nil {
return
}
return string(buf), nil
}
func writeKeyMap(w *bytes.Buffer, name string, msg map[string]interface{}) (err error) {
w.WriteByte(byte(etSECTION_START))
err = writeString1(w, name)
if err != nil {
return
}
writeMap(w, msg)
w.WriteByte(byte(etSECTION_END))
return nil
}
func writeKeyList(w *bytes.Buffer, name string, msg []string) (err error) {
w.WriteByte(byte(etLIST_START))
err = writeString1(w, name)
if err != nil {
return
}
for _, s := range msg {
w.WriteByte(byte(etLIST_ITEM))
err = writeString2(w, s)
if err != nil {
return
}
}
w.WriteByte(byte(etLIST_END))
return nil
}
func writeKeyString(w *bytes.Buffer, name string, msg string) (err error) {
w.WriteByte(byte(etKEY_VALUE))
err = writeString1(w, name)
if err != nil {
return
}
err = writeString2(w, msg)
return
}
func writeMap(w *bytes.Buffer, msg map[string]interface{}) (err error) {
for k, v := range msg {
switch t := v.(type) {
case map[string]interface{}:
writeKeyMap(w, k, t)
case []string:
writeKeyList(w, k, t)
case string:
writeKeyString(w, k, t)
case []interface{}:
str := make([]string, len(t))
for i := range t {
str[i] = t[i].(string)
}
writeKeyList(w, k, str)
default:
return fmt.Errorf("[writeMap] can not write type %T right now", msg)
}
}
return nil
}
//SECTION_START has been read already.
func readKeyMap(r *bufio.Reader) (key string, msg map[string]interface{}, err error) {
key, err = readString1(r)
if err != nil {
return
}
msg, err = readMap(r, false)
return
}
//LIST_START has been read already.
func readKeyList(r *bufio.Reader) (key string, msg []string, err error) {
key, err = readString1(r)
if err != nil {
return
}
msg = []string{}
for {
var c byte
c, err = r.ReadByte()
if err != nil {
return
}
switch elementType(c) {
case etLIST_ITEM:
value, err := readString2(r)
if err != nil {
return "", nil, err
}
msg = append(msg, value)
case etLIST_END: //end of outer list
return key, msg, nil
default:
return "", nil, fmt.Errorf("[readKeyList] protocol error 2")
}
}
return
}
//KEY_VALUE has been read already.
func readKeyString(r *bufio.Reader) (key string, msg string, err error) {
key, err = readString1(r)
if err != nil {
return
}
msg, err = readString2(r)
if err != nil {
return
}
return
}
// Since the original key chosen can have duplicates,
// this function is used to map the original key to a new one
// to make them unique.
func getNewKeyToHandleDuplicates(key string, msg map[string]interface{}) string {
if _, ok := msg[key]; !ok {
return key
}
for i := 0; ; i++ {
newKey := key + "##" + strconv.Itoa(i)
if _, ok := msg[newKey]; !ok {
return newKey
}
}
}
//SECTION_START has been read already.
func readMap(r *bufio.Reader, isRoot bool) (msg map[string]interface{}, err error) {
msg = map[string]interface{}{}
for {
c, err := r.ReadByte()
if err == io.EOF && isRoot { //may be root section
return msg, nil
}
if err != nil {
return nil, err
}
switch elementType(c) {
case etSECTION_START:
key, value, err := readKeyMap(r)
if err != nil {
return nil, err
}
msg[getNewKeyToHandleDuplicates(key, msg)] = value
case etLIST_START:
key, value, err := readKeyList(r)
if err != nil {
return nil, err
}
msg[getNewKeyToHandleDuplicates(key, msg)] = value
case etKEY_VALUE:
key, value, err := readKeyString(r)
if err != nil {
return nil, err
}
msg[getNewKeyToHandleDuplicates(key, msg)] = value
case etSECTION_END: //end of outer section
return msg, nil
default:
panic(fmt.Errorf("[readMap] protocol error 1, %d %#v", c, msg))
//return nil, fmt.Errorf("[readMap] protocol error 1, %d",c)
}
}
return
}

36
vendor/github.com/bronze1man/goStrongswanVici/pools.go generated vendored Normal file
View File

@ -0,0 +1,36 @@
package goStrongswanVici
import (
"fmt"
)
type Pool struct {
PoolMapping map[string]interface{} `json:"pools"`
}
type PoolMapping struct {
Addrs string `json:"addrs"`
DNS []string `json:"dns,omitempty"`
NBNS []string `json:"nbns,omitempty"`
ApplicationVersion []string `json:"7,omitempty"`
InternalIPv6Prefix []string `json:"18,omitempty"`
}
func (c *ClientConn) LoadPool(ph Pool) error {
requestMap := map[string]interface{}{}
err := ConvertToGeneral(ph.PoolMapping, &requestMap)
if err != nil {
fmt.Println(err)
return fmt.Errorf("error creating request: %v", err)
}
msg, err := c.Request("load-pool", requestMap)
if msg["success"] != "yes" {
return fmt.Errorf("unsuccessful LoadPool: %v", msg["success"])
}
return nil
}

View File

@ -0,0 +1,76 @@
// this file contains the functions for managing shared secrets
package goStrongswanVici
import (
"fmt"
)
type Key struct {
ID string `json:"id,omitempty"`
Typ string `json:"type"`
Data string `json:"data"`
Owners []string `json:"owners"`
}
type UnloadKeyRequest struct {
ID string `json:"id"`
}
type keyList struct {
Keys []string `json:"keys"`
}
// load a shared secret into the IKE daemon
func (c *ClientConn) LoadShared(key *Key) error {
requestMap := &map[string]interface{}{}
err := ConvertToGeneral(key, requestMap)
if err != nil {
return fmt.Errorf("error creating request: %v", err)
}
msg, err := c.Request("load-shared", *requestMap)
if msg["success"] != "yes" {
return fmt.Errorf("unsuccessful loadSharedKey: %v", msg["errmsg"])
}
return nil
}
// unload (delete) a shared secret from the IKE daemon
func (c *ClientConn) UnloadShared(key *UnloadKeyRequest) error {
requestMap := &map[string]interface{}{}
err := ConvertToGeneral(key, requestMap)
if err != nil {
return fmt.Errorf("error creating request: %v", err)
}
msg, err := c.Request("unload-shared", *requestMap)
if msg["success"] != "yes" {
return fmt.Errorf("unsuccessful loadSharedKey: %v", msg["errmsg"])
}
return nil
}
// get a the names of the shared secrets currently loaded
func (c *ClientConn) GetShared() ([]string, error) {
msg, err := c.Request("get-shared", nil)
if err != nil {
fmt.Errorf("Error making request: %v", err)
return nil, err
}
keys := &keyList{}
err = ConvertFromGeneral(msg, keys)
if err != nil {
fmt.Errorf("Error converting data: %v", err)
}
return keys.Keys, err
}

View File

@ -0,0 +1,7 @@
package goStrongswanVici
// Stats returns IKE daemon statistics and load information.
func (c *ClientConn) Stats() (msg map[string]interface{}, err error) {
msg, err = c.Request("stats", nil)
return
}

View File

@ -0,0 +1,32 @@
package goStrongswanVici
import (
"fmt"
)
type TerminateRequest struct {
Child string `json:"child,omitempty"`
Ike string `json:"ike,omitempty"`
Child_id string `json:"child-id,omitempty"`
Ike_id string `json:"ike-id,omitempty"`
Timeout string `json:"timeout,omitempty"`
Loglevel string `json:"loglevel,omitempty"`
}
// To be simple, kill a client that is connecting to this server. A client is a sa.
//Terminates an SA while streaming control-log events.
func (c *ClientConn) Terminate(r *TerminateRequest) (err error) {
err = handlePanic(func() (err error) {
reqMap := &map[string]interface{}{}
ConvertToGeneral(r, reqMap)
msg, err := c.Request("terminate", *reqMap)
if err != nil {
return
}
if msg["success"] != "yes" {
return fmt.Errorf("[Terminate] %s", msg["errmsg"])
}
return
})
return
}

View File

@ -0,0 +1,24 @@
package goStrongswanVici
import (
"fmt"
)
type UnloadConnRequest struct {
Name string `json:"name"`
}
func (c *ClientConn) UnloadConn(r *UnloadConnRequest) error {
reqMap := &map[string]interface{}{}
ConvertToGeneral(r, reqMap)
msg, err := c.Request("unload-conn", *reqMap)
if err != nil {
return err
}
if msg["success"] != "yes" {
return fmt.Errorf("[Unload-Connection] %s", msg["errmsg"])
}
return nil
}

View File

@ -0,0 +1,19 @@
package goStrongswanVici
type Version struct {
Daemon string `json:"daemon"`
Version string `json:"version"`
Sysname string `json:"sysname"`
Release string `json:"release"`
Machine string `json:"machine"`
}
func (c *ClientConn) Version() (out *Version, err error) {
msg, err := c.Request("version", nil)
if err != nil {
return
}
out = &Version{}
err = ConvertFromGeneral(msg, out)
return
}

View File

@ -0,0 +1,153 @@
// Copyright 2017 flannel authors
//
// 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
//
// http://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.
package extension
import (
"fmt"
"io"
"os"
"strings"
"encoding/json"
"os/exec"
"sync"
log "k8s.io/klog"
"github.com/coreos/flannel/backend"
"github.com/coreos/flannel/pkg/ip"
"github.com/coreos/flannel/subnet"
"golang.org/x/net/context"
)
func init() {
backend.Register("extension", New)
}
type ExtensionBackend struct {
sm subnet.Manager
extIface *backend.ExternalInterface
networks map[string]*network
}
func New(sm subnet.Manager, extIface *backend.ExternalInterface) (backend.Backend, error) {
be := &ExtensionBackend{
sm: sm,
extIface: extIface,
networks: make(map[string]*network),
}
return be, nil
}
func (_ *ExtensionBackend) Run(ctx context.Context) {
<-ctx.Done()
}
func (be *ExtensionBackend) RegisterNetwork(ctx context.Context, wg sync.WaitGroup, config *subnet.Config) (backend.Network, error) {
n := &network{
extIface: be.extIface,
sm: be.sm,
}
// Parse out configuration
if len(config.Backend) > 0 {
cfg := struct {
PreStartupCommand string
PostStartupCommand string
SubnetAddCommand string
SubnetRemoveCommand string
}{}
if err := json.Unmarshal(config.Backend, &cfg); err != nil {
return nil, fmt.Errorf("error decoding backend config: %v", err)
}
n.preStartupCommand = cfg.PreStartupCommand
n.postStartupCommand = cfg.PostStartupCommand
n.subnetAddCommand = cfg.SubnetAddCommand
n.subnetRemoveCommand = cfg.SubnetRemoveCommand
}
data := []byte{}
if len(n.preStartupCommand) > 0 {
cmd_output, err := runCmd([]string{}, "", "sh", "-c", n.preStartupCommand)
if err != nil {
return nil, fmt.Errorf("failed to run command: %s Err: %v Output: %s", n.preStartupCommand, err, cmd_output)
} else {
log.Infof("Ran command: %s\n Output: %s", n.preStartupCommand, cmd_output)
}
data, err = json.Marshal(cmd_output)
if err != nil {
return nil, err
}
} else {
log.Infof("No pre startup command configured - skipping")
}
attrs := subnet.LeaseAttrs{
PublicIP: ip.FromIP(be.extIface.ExtAddr),
BackendType: "extension",
BackendData: data,
}
lease, err := be.sm.AcquireLease(ctx, &attrs)
switch err {
case nil:
n.lease = lease
case context.Canceled, context.DeadlineExceeded:
return nil, err
default:
return nil, fmt.Errorf("failed to acquire lease: %v", err)
}
if len(n.postStartupCommand) > 0 {
cmd_output, err := runCmd([]string{
fmt.Sprintf("NETWORK=%s", config.Network),
fmt.Sprintf("SUBNET=%s", lease.Subnet),
fmt.Sprintf("PUBLIC_IP=%s", attrs.PublicIP)},
"", "sh", "-c", n.postStartupCommand)
if err != nil {
return nil, fmt.Errorf("failed to run command: %s Err: %v Output: %s", n.postStartupCommand, err, cmd_output)
} else {
log.Infof("Ran command: %s\n Output: %s", n.postStartupCommand, cmd_output)
}
} else {
log.Infof("No post startup command configured - skipping")
}
return n, nil
}
// Run a cmd, returning a combined stdout and stderr.
func runCmd(env []string, stdin string, name string, arg ...string) (string, error) {
env = append(env, fmt.Sprintf("PATH=%s", os.Getenv("PATH")))
cmd := exec.Command(name, arg...)
cmd.Env = env
stdinpipe, err := cmd.StdinPipe()
if err != nil {
return "", err
}
io.WriteString(stdinpipe, stdin)
io.WriteString(stdinpipe, "\n")
stdinpipe.Close()
output, err := cmd.CombinedOutput()
return strings.TrimSpace(string(output)), err
}

View File

@ -0,0 +1,141 @@
// Copyright 2017 flannel authors
//
// 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
//
// http://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.
package extension
import (
"encoding/json"
"sync"
log "k8s.io/klog"
"golang.org/x/net/context"
"fmt"
"github.com/coreos/flannel/backend"
"github.com/coreos/flannel/subnet"
)
type network struct {
name string
extIface *backend.ExternalInterface
lease *subnet.Lease
sm subnet.Manager
preStartupCommand string
postStartupCommand string
subnetAddCommand string
subnetRemoveCommand string
}
func (n *network) Lease() *subnet.Lease {
return n.lease
}
func (n *network) MTU() int {
return n.extIface.Iface.MTU
}
func (n *network) Run(ctx context.Context) {
wg := sync.WaitGroup{}
log.Info("Watching for new subnet leases")
evts := make(chan []subnet.Event)
wg.Add(1)
go func() {
subnet.WatchLeases(ctx, n.sm, n.lease, evts)
wg.Done()
}()
defer wg.Wait()
for {
select {
case evtBatch := <-evts:
n.handleSubnetEvents(evtBatch)
case <-ctx.Done():
return
}
}
}
func (n *network) handleSubnetEvents(batch []subnet.Event) {
for _, evt := range batch {
switch evt.Type {
case subnet.EventAdded:
log.Infof("Subnet added: %v via %v", evt.Lease.Subnet, evt.Lease.Attrs.PublicIP)
if evt.Lease.Attrs.BackendType != "extension" {
log.Warningf("Ignoring non-extension subnet: type=%v", evt.Lease.Attrs.BackendType)
continue
}
if len(n.subnetAddCommand) > 0 {
backendData := ""
if len(evt.Lease.Attrs.BackendData) > 0 {
if err := json.Unmarshal(evt.Lease.Attrs.BackendData, &backendData); err != nil {
log.Errorf("failed to unmarshal BackendData: %v", err)
continue
}
}
cmd_output, err := runCmd([]string{
fmt.Sprintf("SUBNET=%s", evt.Lease.Subnet),
fmt.Sprintf("PUBLIC_IP=%s", evt.Lease.Attrs.PublicIP)},
backendData,
"sh", "-c", n.subnetAddCommand)
if err != nil {
log.Errorf("failed to run command: %s Err: %v Output: %s", n.subnetAddCommand, err, cmd_output)
} else {
log.Infof("Ran command: %s\n Output: %s", n.subnetAddCommand, cmd_output)
}
}
case subnet.EventRemoved:
log.Info("Subnet removed: ", evt.Lease.Subnet)
if evt.Lease.Attrs.BackendType != "extension" {
log.Warningf("Ignoring non-extension subnet: type=%v", evt.Lease.Attrs.BackendType)
continue
}
if len(n.subnetRemoveCommand) > 0 {
backendData := ""
if len(evt.Lease.Attrs.BackendData) > 0 {
if err := json.Unmarshal(evt.Lease.Attrs.BackendData, &backendData); err != nil {
log.Errorf("failed to unmarshal BackendData: %v", err)
continue
}
}
cmd_output, err := runCmd([]string{
fmt.Sprintf("SUBNET=%s", evt.Lease.Subnet),
fmt.Sprintf("PUBLIC_IP=%s", evt.Lease.Attrs.PublicIP)},
backendData,
"sh", "-c", n.subnetRemoveCommand)
if err != nil {
log.Errorf("failed to run command: %s Err: %v Output: %s", n.subnetRemoveCommand, err, cmd_output)
} else {
log.Infof("Ran command: %s\n Output: %s", n.subnetRemoveCommand, cmd_output)
}
}
default:
log.Error("Internal error: unknown event type: ", int(evt.Type))
}
}
}

View File

@ -0,0 +1,236 @@
// Copyright 2017 flannel authors
//
// 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
//
// http://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.
// +build !windows
package ipsec
import (
"fmt"
"net"
"os"
"os/exec"
"strings"
"sync"
"syscall"
"time"
"github.com/bronze1man/goStrongswanVici"
"github.com/coreos/flannel/subnet"
log "k8s.io/klog"
"golang.org/x/net/context"
)
type Uri struct {
network, address string
}
type CharonIKEDaemon struct {
viciUri Uri
espProposal string
ctx context.Context
}
func NewCharonIKEDaemon(ctx context.Context, wg sync.WaitGroup, espProposal string) (*CharonIKEDaemon, error) {
charon := &CharonIKEDaemon{ctx: ctx, espProposal: espProposal}
addr := strings.Split("unix:///var/run/charon.vici", "://")
charon.viciUri = Uri{addr[0], addr[1]}
cmd, err := charon.runBundled("/usr/lib/strongswan/", "charon")
if err != nil {
log.Errorf("Error starting charon daemon: %v", err)
return nil, err
} else {
log.Info("Charon daemon started")
}
wg.Add(1)
go func() {
select {
case <-ctx.Done():
cmd.Process.Signal(syscall.SIGTERM)
cmd.Wait()
log.Infof("Stopped charon daemon")
wg.Done()
}
}()
return charon, nil
}
func (charon *CharonIKEDaemon) getClient(wait bool) (client *goStrongswanVici.ClientConn, err error) {
for {
socket_conn, err := net.Dial(charon.viciUri.network, charon.viciUri.address)
if err == nil {
return goStrongswanVici.NewClientConn(socket_conn), nil
} else {
if wait {
select {
case <-charon.ctx.Done():
log.Error("Cancel waiting for charon")
return nil, err
default:
log.Errorf("ClientConnection failed: %v", err)
}
log.Info("Retrying in a second ...")
time.Sleep(time.Second)
} else {
return nil, err
}
}
}
}
func (charon *CharonIKEDaemon) runBundled(staticLocation string, command string) (cmd *exec.Cmd, err error) {
path, err := exec.LookPath(command)
if err != nil {
path = staticLocation + command
}
cmd = &exec.Cmd{
Path: path,
SysProcAttr: &syscall.SysProcAttr{
Pdeathsig: syscall.SIGTERM,
},
Stdout: os.Stdout,
Stderr: os.Stderr,
}
err = cmd.Start()
return
}
func (charon *CharonIKEDaemon) LoadSharedKey(remotePublicIP, password string) error {
var err error
var client *goStrongswanVici.ClientConn
client, err = charon.getClient(true)
if err != nil {
log.Errorf("Failed to acquire Vici client: %v", err)
return err
}
defer client.Close()
sharedKey := &goStrongswanVici.Key{
Typ: "IKE",
Data: password,
Owners: []string{remotePublicIP},
}
for {
err = client.LoadShared(sharedKey)
if err != nil {
log.Errorf("Failed to load my key. Retrying. %v", err)
time.Sleep(time.Second)
} else {
break
}
}
log.Infof("Loaded shared key for: %v", remotePublicIP)
return nil
}
func (charon *CharonIKEDaemon) LoadConnection(localLease, remoteLease *subnet.Lease,
reqID, encap string) error {
var err error
var client *goStrongswanVici.ClientConn
client, err = charon.getClient(true)
if err != nil {
log.Errorf("Failed to acquire Vici client: %s", err)
return err
}
defer client.Close()
childConfMap := make(map[string]goStrongswanVici.ChildSAConf)
childSAConf := goStrongswanVici.ChildSAConf{
Local_ts: []string{localLease.Subnet.String()},
Remote_ts: []string{remoteLease.Subnet.String()},
ESPProposals: []string{charon.espProposal},
StartAction: "start",
CloseAction: "trap",
Mode: "tunnel",
ReqID: reqID,
// RekeyTime: rekeyTime,
InstallPolicy: "no",
}
childSAConfName := formatChildSAConfName(localLease, remoteLease)
childConfMap[childSAConfName] = childSAConf
localAuthConf := goStrongswanVici.AuthConf{
AuthMethod: "psk",
}
remoteAuthConf := goStrongswanVici.AuthConf{
AuthMethod: "psk",
}
ikeConf := goStrongswanVici.IKEConf{
LocalAddrs: []string{localLease.Attrs.PublicIP.String()},
RemoteAddrs: []string{remoteLease.Attrs.PublicIP.String()},
Proposals: []string{"aes256-sha256-modp4096"},
Version: "2",
KeyingTries: "0", //continues to retry
LocalAuth: localAuthConf,
RemoteAuth: remoteAuthConf,
Children: childConfMap,
Encap: encap,
}
ikeConfMap := make(map[string]goStrongswanVici.IKEConf)
connectionName := formatConnectionName(localLease, remoteLease)
ikeConfMap[connectionName] = ikeConf
err = client.LoadConn(&ikeConfMap)
if err != nil {
return err
}
log.Infof("Loaded connection: %v", connectionName)
return nil
}
func (charon *CharonIKEDaemon) UnloadCharonConnection(localLease,
remoteLease *subnet.Lease) error {
client, err := charon.getClient(false)
if err != nil {
log.Errorf("Failed to acquire Vici client: %s", err)
return err
}
defer client.Close()
connectionName := formatConnectionName(localLease, remoteLease)
unloadConnRequest := &goStrongswanVici.UnloadConnRequest{
Name: connectionName,
}
err = client.UnloadConn(unloadConnRequest)
if err != nil {
return err
}
log.Infof("Unloaded connection: %v", connectionName)
return nil
}
func formatConnectionName(localLease, remoteLease *subnet.Lease) string {
return fmt.Sprintf("%s-%s-%s-%s", localLease.Attrs.PublicIP,
localLease.Subnet, remoteLease.Subnet, remoteLease.Attrs.PublicIP)
}
func formatChildSAConfName(localLease, remoteLease *subnet.Lease) string {
return fmt.Sprintf("%s-%s", localLease.Subnet, remoteLease.Subnet)
}

View File

@ -0,0 +1,91 @@
// Copyright 2017 flannel authors
//
// 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
//
// http://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.
// +build !windows
package ipsec
import (
"fmt"
"net"
log "k8s.io/klog"
"github.com/vishvananda/netlink"
"github.com/coreos/flannel/subnet"
)
func AddXFRMPolicy(myLease, remoteLease *subnet.Lease, dir netlink.Dir, reqID int) error {
src := myLease.Subnet.ToIPNet()
dst := remoteLease.Subnet.ToIPNet()
policy := netlink.XfrmPolicy{
Src: src,
Dst: dst,
Dir: dir,
}
tunnelLeft := myLease.Attrs.PublicIP.ToIP()
tunnelRight := remoteLease.Attrs.PublicIP.ToIP()
tmpl := netlink.XfrmPolicyTmpl{
Src: tunnelLeft,
Dst: tunnelRight,
Proto: netlink.XFRM_PROTO_ESP,
Mode: netlink.XFRM_MODE_TUNNEL,
Reqid: reqID,
}
log.Infof("Adding ipsec policy: %+v", tmpl)
policy.Tmpls = append(policy.Tmpls, tmpl)
if err := netlink.XfrmPolicyAdd(&policy); err != nil {
return fmt.Errorf("error adding policy: %+v err: %v", policy, err)
}
return nil
}
func DeleteXFRMPolicy(localSubnet, remoteSubnet *net.IPNet, localPublicIP, remotePublicIP net.IP, dir netlink.Dir, reqID int) error {
src := localSubnet
dst := remoteSubnet
policy := netlink.XfrmPolicy{
Src: src,
Dst: dst,
Dir: dir,
}
tunnelLeft := localPublicIP
tunnelRight := remotePublicIP
tmpl := netlink.XfrmPolicyTmpl{
Src: tunnelLeft,
Dst: tunnelRight,
Proto: netlink.XFRM_PROTO_ESP,
Mode: netlink.XFRM_MODE_TUNNEL,
Reqid: reqID,
}
log.Infof("Deleting ipsec policy: %+v", tmpl)
policy.Tmpls = append(policy.Tmpls, tmpl)
if err := netlink.XfrmPolicyDel(&policy); err != nil {
return fmt.Errorf("error deleting policy: %+v err: %v", policy, err)
}
return nil
}

121
vendor/github.com/coreos/flannel/backend/ipsec/ipsec.go generated vendored Normal file
View File

@ -0,0 +1,121 @@
// Copyright 2017 flannel authors
//
// 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
//
// http://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.
// +build !windows
package ipsec
import (
"encoding/json"
"fmt"
"sync"
log "k8s.io/klog"
"golang.org/x/net/context"
"github.com/coreos/flannel/backend"
"github.com/coreos/flannel/pkg/ip"
"github.com/coreos/flannel/subnet"
)
/*
Flannel's approach to IPSec uses Strongswan to handle the key exchange (using IKEv2) and the kernel to handle the
actual encryption.
Strongswan's "charon" is bundled in the flannel container. Flannel runs it as a child process when the ipsec backend
is selected and communicates with it using the "VICI" interface. Strongswan ships a utility "swanctl" which also
uses the VICI interface. This utility is bundled in the flannel container and can help with debugging.
The file "handle_charon.go" contains the logic for working with the charon. It supports creating a "CharonIKEDaemon"
which supports loading the PSK into the charon and adding and removing connections.
The file "handle_xfrm.go" contains functions for adding and removing the ipsec polcies.
ipsec_network.go ties it all together, loading the PSK for current host on startu and as new hosts are added and
removed it, adds/removes the PSK and connection details to strongswan and adds/remove the policy to the kernel.
*/
const (
defaultESPProposal = "aes128gcm16-sha256-prfsha256-ecp256"
minPasswordLength = 96
)
func init() {
backend.Register("ipsec", New)
}
type IPSECBackend struct {
sm subnet.Manager
extIface *backend.ExternalInterface
}
func New(sm subnet.Manager, extIface *backend.ExternalInterface) (
backend.Backend, error) {
be := &IPSECBackend{
sm: sm,
extIface: extIface,
}
return be, nil
}
func (be *IPSECBackend) RegisterNetwork(
ctx context.Context, wg sync.WaitGroup, config *subnet.Config) (backend.Network, error) {
cfg := struct {
UDPEncap bool
ESPProposal string
PSK string
}{
UDPEncap: false,
ESPProposal: defaultESPProposal,
}
if len(config.Backend) > 0 {
if err := json.Unmarshal(config.Backend, &cfg); err != nil {
return nil, fmt.Errorf("error decoding IPSEC backend config: %v", err)
}
}
if len(cfg.PSK) < minPasswordLength {
return nil, fmt.Errorf(
"config error, password should be at least %d characters long",
minPasswordLength)
}
log.Infof("IPSec config: UDPEncap=%v ESPProposal=%s", cfg.UDPEncap, cfg.ESPProposal)
attrs := subnet.LeaseAttrs{
PublicIP: ip.FromIP(be.extIface.ExtAddr),
BackendType: "ipsec",
}
l, err := be.sm.AcquireLease(ctx, &attrs)
switch err {
case nil:
case context.Canceled, context.DeadlineExceeded:
return nil, err
default:
return nil, fmt.Errorf("failed to acquire lease: %v", err)
}
ikeDaemon, err := NewCharonIKEDaemon(ctx, wg, cfg.ESPProposal)
if err != nil {
return nil, fmt.Errorf("error creating CharonIKEDaemon struct: %v", err)
}
return newNetwork(be.sm, be.extIface, cfg.UDPEncap, cfg.PSK, ikeDaemon, l)
}

View File

@ -0,0 +1,207 @@
// Copyright 2017 flannel authors
//
// 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
//
// http://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.
// +build !windows
package ipsec
import (
"fmt"
"net"
"strconv"
"sync"
log "k8s.io/klog"
"github.com/vishvananda/netlink"
"golang.org/x/net/context"
"github.com/coreos/flannel/backend"
"github.com/coreos/flannel/subnet"
)
const (
/*
New IP header (Tunnel Mode) : 20
SPI (ESP Header) : 4
Sequence (ESP Header) : 4
ESP-AES IV : 16
ESP-AES Pad : 0-15
Pad length (ESP Trailer) : 1
Next Header (ESP Trailer) : 1
ESP-SHA-256 ICV : 16
*/
ipsecOverhead = 77
udpEncapOverhead = 8
defaultReqID = 11
)
type network struct {
backend.SimpleNetwork
password string
UDPEncap bool
sm subnet.Manager
iked *CharonIKEDaemon
}
func newNetwork(sm subnet.Manager, extIface *backend.ExternalInterface,
UDPEncap bool, password string, ikeDaemon *CharonIKEDaemon,
l *subnet.Lease) (*network, error) {
n := &network{
SimpleNetwork: backend.SimpleNetwork{
SubnetLease: l,
ExtIface: extIface,
},
sm: sm,
iked: ikeDaemon,
password: password,
UDPEncap: UDPEncap,
}
return n, nil
}
func (n *network) Run(ctx context.Context) {
err := n.iked.LoadSharedKey(n.SimpleNetwork.SubnetLease.Attrs.PublicIP.ToIP().String(), n.password)
if err != nil {
log.Errorf("Failed to load PSK: %v", err)
return
}
wg := sync.WaitGroup{}
defer wg.Wait()
log.Info("Watching for new subnet leases")
evts := make(chan []subnet.Event)
wg.Add(1)
go func() {
subnet.WatchLeases(ctx, n.sm, n.SubnetLease, evts)
log.Info("WatchLeases exited")
wg.Done()
}()
for {
select {
case evtsBatch := <-evts:
log.Info("Handling event")
n.handleSubnetEvents(evtsBatch)
case <-ctx.Done():
log.Info("Received DONE")
return
}
}
}
func (n *network) handleSubnetEvents(batch []subnet.Event) {
for _, evt := range batch {
switch evt.Type {
case subnet.EventAdded:
log.Info("Subnet added: ", evt.Lease.Subnet)
if evt.Lease.Attrs.BackendType != "ipsec" {
log.Warningf("Ignoring non-ipsec event: type: %v", evt.Lease.Attrs.BackendType)
continue
}
if evt.Lease.Subnet.Equal(n.SubnetLease.Subnet) {
log.Warningf("Ignoring own lease add event: %+v", evt.Lease)
continue
}
if err := n.AddIPSECPolicies(&evt.Lease, defaultReqID); err != nil {
log.Errorf("error adding ipsec policy: %v", err)
}
if err := n.iked.LoadSharedKey(evt.Lease.Attrs.PublicIP.String(), n.password); err != nil {
log.Errorf("error loading shared key into IKE daemon: %v", err)
}
if err := n.iked.LoadConnection(n.SubnetLease, &evt.Lease, strconv.Itoa(defaultReqID),
strconv.FormatBool(n.UDPEncap)); err != nil {
log.Errorf("error loading connection into IKE daemon: %v", err)
}
case subnet.EventRemoved:
log.Info("Subnet removed: ", evt.Lease.Subnet)
if evt.Lease.Attrs.BackendType != "ipsec" {
log.Warningf("Ignoring non-ipsec event: type: %v", evt.Lease.Attrs.BackendType)
continue
}
if evt.Lease.Subnet.Equal(n.SubnetLease.Subnet) {
log.Warningf("Ignoring own lease remove event: %+v", evt.Lease)
continue
}
if err := n.iked.UnloadCharonConnection(n.SubnetLease, &evt.Lease); err != nil {
log.Errorf("error unloading charon connections: %v", err)
}
if err := n.DeleteIPSECPolicies(n.SubnetLease.Subnet.ToIPNet(), evt.Lease.Subnet.ToIPNet(),
n.SubnetLease.Attrs.PublicIP.ToIP(), evt.Lease.Attrs.PublicIP.ToIP(), defaultReqID); err != nil {
log.Errorf("error deleting ipsec policies: %v", err)
}
}
}
}
func (n *network) MTU() int {
mtu := n.ExtIface.Iface.MTU - ipsecOverhead
if n.UDPEncap {
mtu -= udpEncapOverhead
}
return mtu
}
func (n *network) AddIPSECPolicies(remoteLease *subnet.Lease, reqID int) error {
err := AddXFRMPolicy(n.SubnetLease, remoteLease, netlink.XFRM_DIR_OUT, reqID)
if err != nil {
return fmt.Errorf("error adding ipsec out policy: %v", err)
}
err = AddXFRMPolicy(remoteLease, n.SubnetLease, netlink.XFRM_DIR_IN, reqID)
if err != nil {
return fmt.Errorf("error adding ipsec in policy: %v", err)
}
err = AddXFRMPolicy(remoteLease, n.SubnetLease, netlink.XFRM_DIR_FWD, reqID)
if err != nil {
return fmt.Errorf("error adding ipsec fwd policy: %v", err)
}
return nil
}
func (n *network) DeleteIPSECPolicies(localSubnet, remoteSubnet *net.IPNet, localPublicIP, remotePublicIP net.IP, reqID int) error {
err := DeleteXFRMPolicy(localSubnet, remoteSubnet, localPublicIP, remotePublicIP, netlink.XFRM_DIR_OUT, reqID)
if err != nil {
return fmt.Errorf("error deleting ipsec out policy: %v", err)
}
err = DeleteXFRMPolicy(remoteSubnet, localSubnet, remotePublicIP, localPublicIP, netlink.XFRM_DIR_IN, reqID)
if err != nil {
return fmt.Errorf("error deleting ipsec in policy: %v", err)
}
err = DeleteXFRMPolicy(remoteSubnet, localSubnet, remotePublicIP, localPublicIP, netlink.XFRM_DIR_FWD, reqID)
if err != nil {
return fmt.Errorf("error deleting ipsec fwd policy: %v", err)
}
return nil
}

View File

@ -0,0 +1,21 @@
// Copyright 2017 flannel authors
//
// 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
//
// http://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.
package ipsec
import log "k8s.io/klog"
func init() {
log.Infof("ipsec is not supported on this platform")
}

View File

@ -35,6 +35,7 @@ type vxlanDeviceAttrs struct {
vtepAddr net.IP
vtepPort int
gbp bool
learning bool
}
type vxlanDevice struct {
@ -51,7 +52,7 @@ func newVXLANDevice(devAttrs *vxlanDeviceAttrs) (*vxlanDevice, error) {
VtepDevIndex: devAttrs.vtepIndex,
SrcAddr: devAttrs.vtepAddr,
Port: devAttrs.vtepPort,
Learning: false,
Learning: devAttrs.learning,
GBP: devAttrs.gbp,
}

View File

@ -18,6 +18,7 @@ import (
"encoding/json"
"fmt"
"github.com/Microsoft/hcsshim"
"github.com/Microsoft/hcsshim/hcn"
"github.com/buger/jsonparser"
"github.com/coreos/flannel/pkg/ip"
log "k8s.io/klog"
@ -129,7 +130,30 @@ func ensureNetwork(expectedNetwork *hcsshim.HNSNetwork, expectedVSID int64, expe
}
log.Infof("Created HNSNetwork %s", networkName)
return newNetwork, nil
existingNetwork = newNetwork
}
existingNetworkV2, err := hcn.GetNetworkByID(existingNetwork.Id)
if err != nil {
return nil, errors.Annotatef(err, "Could not find vxlan0 in V2")
}
addHostRoute := true
for _, policy := range existingNetworkV2.Policies {
if policy.Type == hcn.HostRoute {
addHostRoute = false
}
}
if addHostRoute {
hostRoutePolicy := hcn.NetworkPolicy{
Type: hcn.HostRoute,
Settings: []byte("{}"),
}
networkRequest := hcn.PolicyNetworkRequest{
Policies: []hcn.NetworkPolicy{hostRoutePolicy},
}
existingNetworkV2.AddPolicy(networkRequest)
}
return existingNetwork, nil

View File

@ -107,6 +107,7 @@ func (be *VXLANBackend) RegisterNetwork(ctx context.Context, wg sync.WaitGroup,
VNI int
Port int
GBP bool
Learning bool
DirectRouting bool
}{
VNI: defaultVNI,
@ -117,7 +118,7 @@ func (be *VXLANBackend) RegisterNetwork(ctx context.Context, wg sync.WaitGroup,
return nil, fmt.Errorf("error decoding VXLAN backend config: %v", err)
}
}
log.Infof("VXLAN config: VNI=%d Port=%d GBP=%v DirectRouting=%v", cfg.VNI, cfg.Port, cfg.GBP, cfg.DirectRouting)
log.Infof("VXLAN config: VNI=%d Port=%d GBP=%v Learning=%v DirectRouting=%v", cfg.VNI, cfg.Port, cfg.GBP, cfg.Learning, cfg.DirectRouting)
devAttrs := vxlanDeviceAttrs{
vni: uint32(cfg.VNI),
@ -126,6 +127,7 @@ func (be *VXLANBackend) RegisterNetwork(ctx context.Context, wg sync.WaitGroup,
vtepAddr: be.extIface.IfaceAddr,
vtepPort: cfg.Port,
gbp: cfg.GBP,
learning: cfg.Learning,
}
dev, err := newVXLANDevice(&devAttrs)

View File

@ -33,7 +33,6 @@ import (
"golang.org/x/net/context"
"github.com/Microsoft/hcsshim"
"github.com/Microsoft/hcsshim/hcn"
"github.com/coreos/flannel/backend"
"github.com/coreos/flannel/pkg/ip"
@ -65,9 +64,13 @@ func New(sm subnet.Manager, extIface *backend.ExternalInterface) (backend.Backen
}
func newSubnetAttrs(publicIP net.IP, vnid uint16, mac net.HardwareAddr) (*subnet.LeaseAttrs, error) {
var hardwareAddress hardwareAddr
if mac != nil {
hardwareAddress = hardwareAddr(mac)
}
leaseAttrs := &vxlanLeaseAttrs{
VNI: vnid,
VtepMAC: hardwareAddr(mac),
VtepMAC: hardwareAddress,
}
data, err := json.Marshal(&leaseAttrs)
if err != nil {
@ -123,33 +126,12 @@ func (be *VXLANBackend) RegisterNetwork(ctx context.Context, wg sync.WaitGroup,
}
log.Infof("VXLAN config: Name=%s MacPrefix=%s VNI=%d Port=%d GBP=%v DirectRouting=%v", cfg.Name, cfg.MacPrefix, cfg.VNI, cfg.Port, cfg.GBP, cfg.DirectRouting)
hnsNetworks, err := hcsshim.HNSListNetworkRequest("GET", "", "")
if err != nil {
log.Infof("Cannot get HNS networks [%+v]", err)
}
var remoteDrMac string
for _, hnsnetwork := range hnsNetworks {
if hnsnetwork.ManagementIP == be.extIface.ExtAddr.String() {
hcnnetwork, err := hcn.GetNetworkByID(hnsnetwork.Id)
policies := hcnnetwork.Policies
for _, policy := range policies {
if policy.Type == hcn.DrMacAddress {
policySettings := hcn.DrMacAddressNetworkPolicySetting{}
err = json.Unmarshal(policy.Settings, &policySettings)
if err != nil {
return nil, fmt.Errorf("Failed to unmarshal settings")
}
remoteDrMac = policySettings.Address
}
}
}
}
mac, err := net.ParseMAC(string(remoteDrMac))
err := hcn.RemoteSubnetSupported()
if err != nil {
return nil, err
}
subnetAttrs, err := newSubnetAttrs(be.extIface.ExtAddr, uint16(cfg.VNI), mac)
subnetAttrs, err := newSubnetAttrs(be.extIface.ExtAddr, uint16(cfg.VNI), nil)
if err != nil {
return nil, err
}
@ -176,7 +158,41 @@ func (be *VXLANBackend) RegisterNetwork(ctx context.Context, wg sync.WaitGroup,
dev.directRouting = cfg.DirectRouting
dev.macPrefix = cfg.MacPrefix
return newNetwork(be.subnetMgr, be.extIface, dev, ip.IP4Net{}, lease)
network, err := newNetwork(be.subnetMgr, be.extIface, dev, ip.IP4Net{}, lease)
if err != nil {
return nil, err
}
hcnNetwork, err := hcn.GetNetworkByName(cfg.Name)
if err != nil {
return nil, err
}
var newDrMac string
for _, policy := range hcnNetwork.Policies {
if policy.Type == hcn.DrMacAddress {
policySettings := hcn.DrMacAddressNetworkPolicySetting{}
err = json.Unmarshal(policy.Settings, &policySettings)
if err != nil {
return nil, fmt.Errorf("Failed to unmarshal settings")
}
newDrMac = policySettings.Address
}
}
mac, err := net.ParseMAC(string(newDrMac))
if err != nil {
return nil, fmt.Errorf("Cannot parse DR MAC %v: %+v", newDrMac, err)
}
subnetAttrs, err = newSubnetAttrs(be.extIface.ExtAddr, uint16(cfg.VNI), mac)
if err != nil {
return nil, err
}
lease, err = be.subnetMgr.AcquireLease(ctx, subnetAttrs)
return network, nil
}
// So we can make it JSON (un)marshalable

View File

@ -77,12 +77,12 @@ func (ip IP4) StringSep(sep string) string {
return fmt.Sprintf("%d%s%d%s%d%s%d", a, sep, b, sep, c, sep, d)
}
// json.Marshaler impl
// MarshalJSON: json.Marshaler impl
func (ip IP4) MarshalJSON() ([]byte, error) {
return []byte(fmt.Sprintf(`"%s"`, ip)), nil
}
// json.Unmarshaler impl
// UnmarshalJSON: json.Unmarshaler impl
func (ip *IP4) UnmarshalJSON(j []byte) error {
j = bytes.Trim(j, "\"")
if val, err := ParseIP4(string(j)); err != nil {
@ -163,12 +163,12 @@ func (n IP4Net) Empty() bool {
return n.IP == IP4(0) && n.PrefixLen == uint(0)
}
// json.Marshaler impl
// MarshalJSON: json.Marshaler impl
func (n IP4Net) MarshalJSON() ([]byte, error) {
return []byte(fmt.Sprintf(`"%s"`, n)), nil
}
// json.Unmarshaler impl
// UnmarshalJSON: json.Unmarshaler impl
func (n *IP4Net) UnmarshalJSON(j []byte) error {
j = bytes.Trim(j, "\"")
if _, val, err := net.ParseCIDR(string(j)); err != nil {

View File

@ -25,6 +25,7 @@ import (
"github.com/coreos/flannel/pkg/ip"
"github.com/coreos/flannel/subnet"
log "k8s.io/klog"
"golang.org/x/net/context"
"k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -38,7 +39,6 @@ import (
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/cache"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/klog"
)
var (
@ -48,8 +48,6 @@ var (
const (
resyncPeriod = 5 * time.Minute
nodeControllerSyncTimeout = 10 * time.Minute
netConfPath = "/etc/kube-flannel/net-conf.json"
)
type kubeSubnetManager struct {
@ -62,21 +60,16 @@ type kubeSubnetManager struct {
events chan subnet.Event
}
func NewSubnetManager(apiUrl, flannelConf, kubeconfig, prefix string) (subnet.Manager, error) {
func NewSubnetManager(apiUrl, kubeconfig, prefix, netConfPath string) (subnet.Manager, error) {
var cfg *rest.Config
var err error
// Use out of cluster config if the URL or kubeconfig have been specified. Otherwise use incluster config.
if apiUrl != "" || kubeconfig != "" {
cfg, err = clientcmd.BuildConfigFromFlags(apiUrl, kubeconfig)
if err != nil {
return nil, fmt.Errorf("unable to create k8s config: %v", err)
}
} else {
cfg, err = rest.InClusterConfig()
if err != nil {
return nil, fmt.Errorf("unable to initialize inclusterconfig: %v", err)
}
// Try to build kubernetes config from a master url or a kubeconfig filepath. If neither masterUrl
// or kubeconfigPath are passed in we fall back to inClusterConfig. If inClusterConfig fails,
// we fallback to the default config.
cfg, err = clientcmd.BuildConfigFromFlags(apiUrl, kubeconfig)
if err != nil {
return nil, fmt.Errorf("fail to create kubernetes config: %v", err)
}
c, err := clientset.NewForConfig(cfg)
@ -105,10 +98,7 @@ func NewSubnetManager(apiUrl, flannelConf, kubeconfig, prefix string) (subnet.Ma
}
}
if flannelConf == "" {
flannelConf = netConfPath
}
netConf, err := ioutil.ReadFile(flannelConf)
netConf, err := ioutil.ReadFile(netConfPath)
if err != nil {
return nil, fmt.Errorf("failed to read net conf: %v", err)
}
@ -124,14 +114,14 @@ func NewSubnetManager(apiUrl, flannelConf, kubeconfig, prefix string) (subnet.Ma
}
go sm.Run(context.Background())
klog.Infof("Waiting %s for node controller to sync", nodeControllerSyncTimeout)
log.Infof("Waiting %s for node controller to sync", nodeControllerSyncTimeout)
err = wait.Poll(time.Second, nodeControllerSyncTimeout, func() (bool, error) {
return sm.nodeController.HasSynced(), nil
})
if err != nil {
return nil, fmt.Errorf("error waiting for nodeController to sync state: %v", err)
}
klog.Infof("Node controller sync successful")
log.Infof("Node controller sync successful")
return sm, nil
}
@ -169,12 +159,12 @@ func newKubeSubnetManager(c clientset.Interface, sc *subnet.Config, nodeName, pr
if !isNode {
deletedState, ok := obj.(cache.DeletedFinalStateUnknown)
if !ok {
klog.Infof("Error received unexpected object: %v", obj)
log.Infof("Error received unexpected object: %v", obj)
return
}
node, ok = deletedState.Obj.(*v1.Node)
if !ok {
klog.Infof("Error deletedFinalStateUnknown contained non-Node object: %v", deletedState.Obj)
log.Infof("Error deletedFinalStateUnknown contained non-Node object: %v", deletedState.Obj)
return
}
obj = node
@ -197,7 +187,7 @@ func (ksm *kubeSubnetManager) handleAddLeaseEvent(et subnet.EventType, obj inter
l, err := ksm.nodeToLease(*n)
if err != nil {
klog.Infof("Error turning node %q to lease: %v", n.ObjectMeta.Name, err)
log.Infof("Error turning node %q to lease: %v", n.ObjectMeta.Name, err)
return
}
ksm.events <- subnet.Event{et, l}
@ -217,7 +207,7 @@ func (ksm *kubeSubnetManager) handleUpdateLeaseEvent(oldObj, newObj interface{})
l, err := ksm.nodeToLease(*n)
if err != nil {
klog.Infof("Error turning node %q to lease: %v", n.ObjectMeta.Name, err)
log.Infof("Error turning node %q to lease: %v", n.ObjectMeta.Name, err)
return
}
ksm.events <- subnet.Event{subnet.EventAdded, l}
@ -254,7 +244,7 @@ func (ksm *kubeSubnetManager) AcquireLease(ctx context.Context, attrs *subnet.Le
n.Annotations[ksm.annotations.BackendData] = string(bd)
if n.Annotations[ksm.annotations.BackendPublicIPOverwrite] != "" {
if n.Annotations[ksm.annotations.BackendPublicIP] != n.Annotations[ksm.annotations.BackendPublicIPOverwrite] {
klog.Infof("Overriding public ip with '%s' from node annotation '%s'",
log.Infof("Overriding public ip with '%s' from node annotation '%s'",
n.Annotations[ksm.annotations.BackendPublicIPOverwrite],
ksm.annotations.BackendPublicIPOverwrite)
n.Annotations[ksm.annotations.BackendPublicIP] = n.Annotations[ksm.annotations.BackendPublicIPOverwrite]
@ -284,6 +274,10 @@ func (ksm *kubeSubnetManager) AcquireLease(ctx context.Context, attrs *subnet.Le
return nil, err
}
}
err = ksm.setNodeNetworkUnavailableFalse()
if err != nil {
log.Errorf("Unable to set NetworkUnavailable to False for %q: %v", ksm.nodeName, err)
}
return &subnet.Lease{
Subnet: ip.FromIPNet(cidr),
Attrs: *attrs,
@ -303,7 +297,7 @@ func (ksm *kubeSubnetManager) WatchLeases(ctx context.Context, cursor interface{
}
func (ksm *kubeSubnetManager) Run(ctx context.Context) {
klog.Infof("Starting kube subnet manager")
log.Infof("Starting kube subnet manager")
ksm.nodeController.Run(ctx.Done())
}
@ -325,7 +319,7 @@ func (ksm *kubeSubnetManager) nodeToLease(n v1.Node) (l subnet.Lease, err error)
return l, nil
}
// unimplemented
// RenewLease: unimplemented
func (ksm *kubeSubnetManager) RenewLease(ctx context.Context, lease *subnet.Lease) error {
return ErrUnimplemented
}
@ -337,3 +331,23 @@ func (ksm *kubeSubnetManager) WatchLease(ctx context.Context, sn ip.IP4Net, curs
func (ksm *kubeSubnetManager) Name() string {
return fmt.Sprintf("Kubernetes Subnet Manager - %s", ksm.nodeName)
}
// Set Kubernetes NodeNetworkUnavailable to false when starting
// https://kubernetes.io/docs/concepts/architecture/nodes/#condition
func (ksm *kubeSubnetManager) setNodeNetworkUnavailableFalse() error {
condition := v1.NodeCondition{
Type: v1.NodeNetworkUnavailable,
Status: v1.ConditionFalse,
Reason: "FlannelIsUp",
Message: "Flannel is running on this node",
LastTransitionTime: metav1.Now(),
LastHeartbeatTime: metav1.Now(),
}
raw, err := json.Marshal(&[]v1.NodeCondition{condition})
if err != nil {
return err
}
patch := []byte(fmt.Sprintf(`{"status":{"conditions":%s}}`, raw))
_, err = ksm.client.CoreV1().Nodes().PatchStatus(ksm.nodeName, patch)
return err
}

6
vendor/modules.txt vendored
View File

@ -119,6 +119,8 @@ github.com/bhendo/go-powershell/backend
github.com/bhendo/go-powershell/utils
# github.com/blang/semver v3.5.0+incompatible
github.com/blang/semver
# github.com/bronze1man/goStrongswanVici v0.0.0-20190828090544-27d02f80ba40
github.com/bronze1man/goStrongswanVici
# github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23
github.com/buger/jsonparser
# github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5
@ -358,8 +360,10 @@ github.com/coreos/etcd/clientv3/balancer/connectivity
github.com/coreos/etcd/pkg/systemd
github.com/coreos/etcd/raft
github.com/coreos/etcd/raft/raftpb
# github.com/coreos/flannel v0.11.0 => github.com/ibuildthecloud/flannel v0.10.1-0.20190131215433-823afe66b226
# github.com/coreos/flannel v0.11.0 => github.com/rancher/flannel v0.11.0-k3s.1
github.com/coreos/flannel/backend
github.com/coreos/flannel/backend/extension
github.com/coreos/flannel/backend/ipsec
github.com/coreos/flannel/backend/vxlan
github.com/coreos/flannel/network
github.com/coreos/flannel/pkg/ip