mirror of https://github.com/k3s-io/k3s
Port to wrangler
parent
16f7aaab66
commit
c0702b0492
5
main.go
5
main.go
|
@ -1,5 +1,6 @@
|
||||||
//go:generate go run types/codegen/cleanup/main.go
|
//go:generate go run pkg/codegen/cleanup/main.go
|
||||||
//go:generate go run types/codegen/main.go
|
//go:generate /bin/rm -rf pkg/generated
|
||||||
|
//go:generate go run pkg/codegen/main.go
|
||||||
//go:generate go fmt pkg/deploy/zz_generated_bindata.go
|
//go:generate go fmt pkg/deploy/zz_generated_bindata.go
|
||||||
//go:generate go fmt pkg/static/zz_generated_bindata.go
|
//go:generate go fmt pkg/static/zz_generated_bindata.go
|
||||||
//go:generate go fmt pkg/openapi/zz_generated_bindata.go
|
//go:generate go fmt pkg/openapi/zz_generated_bindata.go
|
||||||
|
|
|
@ -21,8 +21,8 @@ import (
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/rancher/k3s/pkg/cli/cmds"
|
"github.com/rancher/k3s/pkg/cli/cmds"
|
||||||
|
"github.com/rancher/k3s/pkg/clientaccess"
|
||||||
"github.com/rancher/k3s/pkg/daemons/config"
|
"github.com/rancher/k3s/pkg/daemons/config"
|
||||||
"github.com/rancher/norman/pkg/clientaccess"
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"k8s.io/apimachinery/pkg/util/json"
|
"k8s.io/apimachinery/pkg/util/json"
|
||||||
"k8s.io/apimachinery/pkg/util/net"
|
"k8s.io/apimachinery/pkg/util/net"
|
||||||
|
|
|
@ -6,7 +6,7 @@ import (
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/rancher/k3s/pkg/daemons/config"
|
"github.com/rancher/k3s/pkg/daemons/config"
|
||||||
"github.com/rancher/norman/pkg/proxy"
|
"github.com/rancher/k3s/pkg/proxy"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -16,9 +16,9 @@ import (
|
||||||
"github.com/rancher/k3s/pkg/agent/syssetup"
|
"github.com/rancher/k3s/pkg/agent/syssetup"
|
||||||
"github.com/rancher/k3s/pkg/agent/tunnel"
|
"github.com/rancher/k3s/pkg/agent/tunnel"
|
||||||
"github.com/rancher/k3s/pkg/cli/cmds"
|
"github.com/rancher/k3s/pkg/cli/cmds"
|
||||||
|
"github.com/rancher/k3s/pkg/clientaccess"
|
||||||
"github.com/rancher/k3s/pkg/daemons/agent"
|
"github.com/rancher/k3s/pkg/daemons/agent"
|
||||||
"github.com/rancher/k3s/pkg/rootless"
|
"github.com/rancher/k3s/pkg/rootless"
|
||||||
"github.com/rancher/norman/pkg/clientaccess"
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ import (
|
||||||
|
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
"github.com/rancher/k3s/pkg/daemons/config"
|
"github.com/rancher/k3s/pkg/daemons/config"
|
||||||
"github.com/rancher/norman/pkg/remotedialer"
|
"github.com/rancher/remotedialer"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"k8s.io/client-go/tools/clientcmd"
|
"k8s.io/client-go/tools/clientcmd"
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
/*
|
||||||
|
Copyright The Kubernetes 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Code generated by main. DO NOT EDIT.
|
||||||
|
|
||||||
|
// +k8s:deepcopy-gen=package
|
||||||
|
// +groupName=k3s.cattle.io
|
||||||
|
package v1
|
|
@ -7,6 +7,9 @@ import (
|
||||||
"k8s.io/apimachinery/pkg/util/intstr"
|
"k8s.io/apimachinery/pkg/util/intstr"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// +genclient
|
||||||
|
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||||
|
|
||||||
type ListenerConfig struct {
|
type ListenerConfig struct {
|
||||||
metav1.TypeMeta `json:",inline"`
|
metav1.TypeMeta `json:",inline"`
|
||||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||||
|
@ -14,6 +17,9 @@ type ListenerConfig struct {
|
||||||
Status dynamiclistener.ListenerStatus `json:"status,omitempty"`
|
Status dynamiclistener.ListenerStatus `json:"status,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// +genclient
|
||||||
|
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||||
|
|
||||||
type Addon struct {
|
type Addon struct {
|
||||||
metav1.TypeMeta `json:",inline"`
|
metav1.TypeMeta `json:",inline"`
|
||||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||||
|
@ -31,6 +37,9 @@ type AddonStatus struct {
|
||||||
GVKs []schema.GroupVersionKind `json:"gvks,omitempty"`
|
GVKs []schema.GroupVersionKind `json:"gvks,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// +genclient
|
||||||
|
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||||
|
|
||||||
type HelmChart struct {
|
type HelmChart struct {
|
||||||
metav1.TypeMeta `json:",inline"`
|
metav1.TypeMeta `json:",inline"`
|
||||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||||
|
|
|
@ -8,10 +8,11 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/rancher/wrangler/pkg/signals"
|
||||||
|
|
||||||
"github.com/rancher/k3s/pkg/agent"
|
"github.com/rancher/k3s/pkg/agent"
|
||||||
"github.com/rancher/k3s/pkg/cli/cmds"
|
"github.com/rancher/k3s/pkg/cli/cmds"
|
||||||
"github.com/rancher/k3s/pkg/datadir"
|
"github.com/rancher/k3s/pkg/datadir"
|
||||||
"github.com/rancher/norman/signal"
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
|
@ -67,7 +68,7 @@ func Run(ctx *cli.Context) error {
|
||||||
cfg.DataDir = dataDir
|
cfg.DataDir = dataDir
|
||||||
cfg.Labels = append(cfg.Labels, "node-role.kubernetes.io/worker=true")
|
cfg.Labels = append(cfg.Labels, "node-role.kubernetes.io/worker=true")
|
||||||
|
|
||||||
contextCtx := signal.SigTermCancelContext(context.Background())
|
contextCtx := signals.SetupSignalHandler(context.Background())
|
||||||
|
|
||||||
return agent.Run(contextCtx, cfg)
|
return agent.Run(contextCtx, cfg)
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ import (
|
||||||
"github.com/rancher/k3s/pkg/datadir"
|
"github.com/rancher/k3s/pkg/datadir"
|
||||||
"github.com/rancher/k3s/pkg/rootless"
|
"github.com/rancher/k3s/pkg/rootless"
|
||||||
"github.com/rancher/k3s/pkg/server"
|
"github.com/rancher/k3s/pkg/server"
|
||||||
"github.com/rancher/norman/signal"
|
"github.com/rancher/wrangler/pkg/signals"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
"k8s.io/apimachinery/pkg/util/net"
|
"k8s.io/apimachinery/pkg/util/net"
|
||||||
|
@ -145,7 +145,7 @@ func run(app *cli.Context, cfg *cmds.Server) error {
|
||||||
notifySocket := os.Getenv("NOTIFY_SOCKET")
|
notifySocket := os.Getenv("NOTIFY_SOCKET")
|
||||||
os.Unsetenv("NOTIFY_SOCKET")
|
os.Unsetenv("NOTIFY_SOCKET")
|
||||||
|
|
||||||
ctx := signal.SigTermCancelContext(context.Background())
|
ctx := signals.SetupSignalHandler(context.Background())
|
||||||
certs, err := server.StartServer(ctx, &serverConfig)
|
certs, err := server.StartServer(ctx, &serverConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -0,0 +1,277 @@
|
||||||
|
package clientaccess
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/sha256"
|
||||||
|
"crypto/tls"
|
||||||
|
"crypto/x509"
|
||||||
|
"encoding/hex"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"k8s.io/client-go/tools/clientcmd"
|
||||||
|
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
insecureClient = &http.Client{
|
||||||
|
Transport: &http.Transport{
|
||||||
|
TLSClientConfig: &tls.Config{
|
||||||
|
InsecureSkipVerify: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
type OverrideURLCallback func(config []byte) (*url.URL, error)
|
||||||
|
|
||||||
|
type clientToken struct {
|
||||||
|
caHash string
|
||||||
|
username string
|
||||||
|
password string
|
||||||
|
}
|
||||||
|
|
||||||
|
func AgentAccessInfoToTempKubeConfig(tempDir, server, token string) (string, error) {
|
||||||
|
f, err := ioutil.TempFile(tempDir, "tmp-")
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if err := f.Close(); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
err = accessInfoToKubeConfig(f.Name(), server, token)
|
||||||
|
if err != nil {
|
||||||
|
os.Remove(f.Name())
|
||||||
|
}
|
||||||
|
return f.Name(), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func AgentAccessInfoToKubeConfig(destFile, server, token string) error {
|
||||||
|
return accessInfoToKubeConfig(destFile, server, token)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Info struct {
|
||||||
|
URL string `json:"url,omitempty"`
|
||||||
|
CACerts []byte `json:"cacerts,omitempty"`
|
||||||
|
username string
|
||||||
|
password string
|
||||||
|
Token string `json:"token,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *Info) WriteKubeConfig(destFile string) error {
|
||||||
|
return clientcmd.WriteToFile(*i.KubeConfig(), destFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *Info) KubeConfig() *clientcmdapi.Config {
|
||||||
|
config := clientcmdapi.NewConfig()
|
||||||
|
|
||||||
|
cluster := clientcmdapi.NewCluster()
|
||||||
|
cluster.CertificateAuthorityData = i.CACerts
|
||||||
|
cluster.Server = i.URL
|
||||||
|
|
||||||
|
authInfo := clientcmdapi.NewAuthInfo()
|
||||||
|
if i.password != "" {
|
||||||
|
authInfo.Username = i.username
|
||||||
|
authInfo.Password = i.password
|
||||||
|
} else if i.Token != "" {
|
||||||
|
if username, pass, ok := ParseUsernamePassword(i.Token); ok {
|
||||||
|
authInfo.Username = username
|
||||||
|
authInfo.Password = pass
|
||||||
|
} else {
|
||||||
|
authInfo.Token = i.Token
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
context := clientcmdapi.NewContext()
|
||||||
|
context.AuthInfo = "default"
|
||||||
|
context.Cluster = "default"
|
||||||
|
|
||||||
|
config.Clusters["default"] = cluster
|
||||||
|
config.AuthInfos["default"] = authInfo
|
||||||
|
config.Contexts["default"] = context
|
||||||
|
config.CurrentContext = "default"
|
||||||
|
|
||||||
|
return config
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseAndValidateToken(server, token string) (*Info, error) {
|
||||||
|
url, err := url.Parse(server)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "Invalid url, failed to parse %s", server)
|
||||||
|
}
|
||||||
|
|
||||||
|
if url.Scheme != "https" {
|
||||||
|
return nil, fmt.Errorf("only https:// URLs are supported, invalid scheme: %s", server)
|
||||||
|
}
|
||||||
|
|
||||||
|
for strings.HasSuffix(url.Path, "/") {
|
||||||
|
url.Path = url.Path[:len(url.Path)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
parsedToken, err := parseToken(token)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
cacerts, err := GetCACerts(*url)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(cacerts) > 0 && len(parsedToken.caHash) > 0 {
|
||||||
|
if ok, hash, newHash := validateCACerts(cacerts, parsedToken.caHash); !ok {
|
||||||
|
return nil, fmt.Errorf("token does not match the server %s != %s", hash, newHash)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := validateToken(*url, cacerts, parsedToken.username, parsedToken.password); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Info{
|
||||||
|
URL: url.String(),
|
||||||
|
CACerts: cacerts,
|
||||||
|
username: parsedToken.username,
|
||||||
|
password: parsedToken.password,
|
||||||
|
Token: token,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func accessInfoToKubeConfig(destFile, server, token string) error {
|
||||||
|
info, err := ParseAndValidateToken(server, token)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return info.WriteKubeConfig(destFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateToken(u url.URL, cacerts []byte, username, password string) error {
|
||||||
|
u.Path = "/apis"
|
||||||
|
_, err := get(u.String(), GetHTTPClient(cacerts), username, password)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "token is not valid")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateCACerts(cacerts []byte, hash string) (bool, string, string) {
|
||||||
|
if len(cacerts) == 0 && hash == "" {
|
||||||
|
return true, "", ""
|
||||||
|
}
|
||||||
|
|
||||||
|
digest := sha256.Sum256([]byte(cacerts))
|
||||||
|
newHash := hex.EncodeToString(digest[:])
|
||||||
|
return hash == newHash, hash, newHash
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseUsernamePassword(token string) (string, string, bool) {
|
||||||
|
parsed, err := parseToken(token)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", false
|
||||||
|
}
|
||||||
|
return parsed.username, parsed.password, true
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseToken(token string) (clientToken, error) {
|
||||||
|
var result clientToken
|
||||||
|
|
||||||
|
if !strings.HasPrefix(token, "K10") {
|
||||||
|
return result, fmt.Errorf("token is not a valid token format")
|
||||||
|
}
|
||||||
|
|
||||||
|
token = token[3:]
|
||||||
|
|
||||||
|
parts := strings.SplitN(token, "::", 2)
|
||||||
|
token = parts[0]
|
||||||
|
if len(parts) > 1 {
|
||||||
|
result.caHash = parts[0]
|
||||||
|
token = parts[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
parts = strings.SplitN(token, ":", 2)
|
||||||
|
if len(parts) != 2 {
|
||||||
|
return result, fmt.Errorf("token credentials are the wrong format")
|
||||||
|
}
|
||||||
|
|
||||||
|
result.username = parts[0]
|
||||||
|
result.password = parts[1]
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetHTTPClient(cacerts []byte) *http.Client {
|
||||||
|
if len(cacerts) == 0 {
|
||||||
|
return http.DefaultClient
|
||||||
|
}
|
||||||
|
|
||||||
|
pool := x509.NewCertPool()
|
||||||
|
pool.AppendCertsFromPEM(cacerts)
|
||||||
|
|
||||||
|
return &http.Client{
|
||||||
|
Transport: &http.Transport{
|
||||||
|
DisableKeepAlives: true,
|
||||||
|
TLSClientConfig: &tls.Config{
|
||||||
|
RootCAs: pool,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Get(path string, info *Info) ([]byte, error) {
|
||||||
|
u, err := url.Parse(info.URL)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
u.Path = path
|
||||||
|
return get(u.String(), GetHTTPClient(info.CACerts), info.username, info.password)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetCACerts(u url.URL) ([]byte, error) {
|
||||||
|
u.Path = "/cacerts"
|
||||||
|
url := u.String()
|
||||||
|
|
||||||
|
_, err := get(url, http.DefaultClient, "", "")
|
||||||
|
if err == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
cacerts, err := get(url, insecureClient, "", "")
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "failed to get CA certs at %s", url)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = get(url, GetHTTPClient(cacerts), "", "")
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "server %s is not trusted", url)
|
||||||
|
}
|
||||||
|
|
||||||
|
return cacerts, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func get(u string, client *http.Client, username, password string) ([]byte, error) {
|
||||||
|
req, err := http.NewRequest(http.MethodGet, u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if username != "" {
|
||||||
|
req.SetBasicAuth(username, password)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
return nil, fmt.Errorf("%s: %s", u, resp.Status)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ioutil.ReadAll(resp.Body)
|
||||||
|
}
|
|
@ -1,12 +1,12 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/rancher/norman/generator/cleanup"
|
"github.com/rancher/wrangler/pkg/cleanup"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
if err := cleanup.Cleanup("./types"); err != nil {
|
if err := cleanup.Cleanup("./pkg/apis"); err != nil {
|
||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
bindata "github.com/jteeuwen/go-bindata"
|
bindata "github.com/jteeuwen/go-bindata"
|
||||||
v1 "github.com/rancher/k3s/types/apis/k3s.cattle.io/v1"
|
v1 "github.com/rancher/k3s/pkg/apis/k3s.cattle.io/v1"
|
||||||
"github.com/rancher/norman/generator"
|
controllergen "github.com/rancher/wrangler/pkg/controller-gen"
|
||||||
|
"github.com/rancher/wrangler/pkg/controller-gen/args"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
appsv1 "k8s.io/api/apps/v1"
|
appsv1 "k8s.io/api/apps/v1"
|
||||||
batchv1 "k8s.io/api/batch/v1"
|
batchv1 "k8s.io/api/batch/v1"
|
||||||
|
@ -16,6 +19,7 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
os.Unsetenv("GOPATH")
|
||||||
bc := &bindata.Config{
|
bc := &bindata.Config{
|
||||||
Input: []bindata.InputConfig{
|
Input: []bindata.InputConfig{
|
||||||
{
|
{
|
||||||
|
@ -82,38 +86,56 @@ func main() {
|
||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := generator.DefaultGenerate(v1.Schemas, basePackage, false, nil); err != nil {
|
controllergen.Run(args.Options{
|
||||||
logrus.Fatal(err)
|
OutputPackage: "github.com/rancher/k3s/pkg/generated",
|
||||||
}
|
Boilerplate: "scripts/boilerplate.go.txt",
|
||||||
|
Groups: map[string]args.Group{
|
||||||
if err := generator.ControllersForForeignTypes(basePackage, corev1.SchemeGroupVersion, []interface{}{
|
"k3s.cattle.io": {
|
||||||
corev1.ServiceAccount{},
|
Types: []interface{}{
|
||||||
corev1.Endpoints{},
|
v1.ListenerConfig{},
|
||||||
corev1.Service{},
|
v1.Addon{},
|
||||||
corev1.Pod{},
|
v1.HelmChart{},
|
||||||
corev1.ConfigMap{},
|
},
|
||||||
}, []interface{}{
|
GenerateTypes: true,
|
||||||
corev1.Node{},
|
},
|
||||||
}); err != nil {
|
"": {
|
||||||
logrus.Fatal(err)
|
Types: []interface{}{
|
||||||
}
|
corev1.ServiceAccount{},
|
||||||
|
corev1.Endpoints{},
|
||||||
if err := generator.ControllersForForeignTypes(basePackage, appsv1.SchemeGroupVersion, []interface{}{
|
corev1.Service{},
|
||||||
appsv1.DaemonSet{},
|
corev1.Pod{},
|
||||||
appsv1.Deployment{},
|
corev1.ConfigMap{},
|
||||||
}, nil); err != nil {
|
corev1.Node{},
|
||||||
logrus.Fatal(err)
|
},
|
||||||
}
|
InformersPackage: "k8s.io/client-go/informers",
|
||||||
|
ClientSetPackage: "k8s.io/client-go/kubernetes",
|
||||||
if err := generator.ControllersForForeignTypes(basePackage, batchv1.SchemeGroupVersion, []interface{}{
|
ListersPackage: "k8s.io/client-go/listers",
|
||||||
batchv1.Job{},
|
},
|
||||||
}, nil); err != nil {
|
"apps": {
|
||||||
logrus.Fatal(err)
|
Types: []interface{}{
|
||||||
}
|
appsv1.Deployment{},
|
||||||
|
appsv1.DaemonSet{},
|
||||||
if err := generator.ControllersForForeignTypes(basePackage, rbacv1.SchemeGroupVersion, nil, []interface{}{
|
},
|
||||||
rbacv1.ClusterRoleBinding{},
|
InformersPackage: "k8s.io/client-go/informers",
|
||||||
}); err != nil {
|
ClientSetPackage: "k8s.io/client-go/kubernetes",
|
||||||
logrus.Fatal(err)
|
ListersPackage: "k8s.io/client-go/listers",
|
||||||
}
|
},
|
||||||
|
"batch": {
|
||||||
|
Types: []interface{}{
|
||||||
|
batchv1.Job{},
|
||||||
|
},
|
||||||
|
InformersPackage: "k8s.io/client-go/informers",
|
||||||
|
ClientSetPackage: "k8s.io/client-go/kubernetes",
|
||||||
|
ListersPackage: "k8s.io/client-go/listers",
|
||||||
|
},
|
||||||
|
"rbac": {
|
||||||
|
Types: []interface{}{
|
||||||
|
rbacv1.ClusterRoleBinding{},
|
||||||
|
},
|
||||||
|
InformersPackage: "k8s.io/client-go/informers",
|
||||||
|
ClientSetPackage: "k8s.io/client-go/kubernetes",
|
||||||
|
ListersPackage: "k8s.io/client-go/listers",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,8 +23,8 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
certutil "github.com/rancher/dynamiclistener/cert"
|
||||||
"github.com/rancher/k3s/pkg/daemons/config"
|
"github.com/rancher/k3s/pkg/daemons/config"
|
||||||
certutil "github.com/rancher/norman/pkg/cert"
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"k8s.io/apiserver/pkg/authentication/authenticator"
|
"k8s.io/apiserver/pkg/authentication/authenticator"
|
||||||
"k8s.io/kubernetes/cmd/kube-apiserver/app"
|
"k8s.io/kubernetes/cmd/kube-apiserver/app"
|
||||||
|
|
|
@ -6,8 +6,8 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/rancher/norman/pkg/kv"
|
"github.com/rancher/remotedialer"
|
||||||
"github.com/rancher/norman/pkg/remotedialer"
|
"github.com/rancher/wrangler/pkg/kv"
|
||||||
utilnet "k8s.io/apimachinery/pkg/util/net"
|
utilnet "k8s.io/apimachinery/pkg/util/net"
|
||||||
"k8s.io/apiserver/pkg/endpoints/request"
|
"k8s.io/apiserver/pkg/endpoints/request"
|
||||||
"k8s.io/kubernetes/cmd/kube-apiserver/app"
|
"k8s.io/kubernetes/cmd/kube-apiserver/app"
|
||||||
|
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/rancher/norman/pkg/resolvehome"
|
"github.com/rancher/wrangler/pkg/resolvehome"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
|
@ -14,20 +14,16 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
errors2 "github.com/pkg/errors"
|
errors2 "github.com/pkg/errors"
|
||||||
|
v12 "github.com/rancher/k3s/pkg/apis/k3s.cattle.io/v1"
|
||||||
v1 "github.com/rancher/k3s/types/apis/k3s.cattle.io/v1"
|
v1 "github.com/rancher/k3s/pkg/generated/controllers/k3s.cattle.io/v1"
|
||||||
"github.com/rancher/norman"
|
"github.com/rancher/wrangler/pkg/apply"
|
||||||
"github.com/rancher/norman/objectclient"
|
"github.com/rancher/wrangler/pkg/merr"
|
||||||
"github.com/rancher/norman/pkg/objectset"
|
"github.com/rancher/wrangler/pkg/objectset"
|
||||||
"github.com/rancher/norman/types"
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"k8s.io/apimachinery/pkg/api/errors"
|
"k8s.io/apimachinery/pkg/api/errors"
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
|
||||||
yamlDecoder "k8s.io/apimachinery/pkg/util/yaml"
|
yamlDecoder "k8s.io/apimachinery/pkg/util/yaml"
|
||||||
"k8s.io/client-go/discovery"
|
|
||||||
"k8s.io/client-go/rest"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -35,21 +31,15 @@ const (
|
||||||
startKey = "_start_"
|
startKey = "_start_"
|
||||||
)
|
)
|
||||||
|
|
||||||
func WatchFiles(ctx context.Context, bases ...string) error {
|
func WatchFiles(ctx context.Context, addons v1.AddonController, bases ...string) error {
|
||||||
server := norman.GetServer(ctx)
|
|
||||||
addons := v1.ClientsFrom(ctx).Addon
|
|
||||||
|
|
||||||
w := &watcher{
|
w := &watcher{
|
||||||
addonCache: addons.Cache(),
|
addonCache: addons.Cache(),
|
||||||
addons: addons,
|
addons: addons,
|
||||||
bases: bases,
|
bases: bases,
|
||||||
restConfig: *server.Runtime.LocalConfig,
|
|
||||||
discovery: server.K8sClient.Discovery(),
|
|
||||||
clients: map[schema.GroupVersionKind]*objectclient.ObjectClient{},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addons.Enqueue("", startKey)
|
addons.Enqueue("", startKey)
|
||||||
addons.Interface().AddHandler(ctx, "addon-start", func(key string, _ *v1.Addon) (runtime.Object, error) {
|
addons.OnChange(ctx, "addon-start", func(key string, _ *v12.Addon) (*v12.Addon, error) {
|
||||||
if key == startKey {
|
if key == startKey {
|
||||||
go w.start(ctx)
|
go w.start(ctx)
|
||||||
}
|
}
|
||||||
|
@ -60,13 +50,10 @@ func WatchFiles(ctx context.Context, bases ...string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
type watcher struct {
|
type watcher struct {
|
||||||
addonCache v1.AddonClientCache
|
apply apply.Apply
|
||||||
|
addonCache v1.AddonCache
|
||||||
addons v1.AddonClient
|
addons v1.AddonClient
|
||||||
bases []string
|
bases []string
|
||||||
restConfig rest.Config
|
|
||||||
discovery discovery.DiscoveryInterface
|
|
||||||
clients map[schema.GroupVersionKind]*objectclient.ObjectClient
|
|
||||||
namespaced map[schema.GroupVersionKind]bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *watcher) start(ctx context.Context) {
|
func (w *watcher) start(ctx context.Context) {
|
||||||
|
@ -93,7 +80,7 @@ func (w *watcher) listFiles(force bool) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return types.NewErrors(errs...)
|
return merr.NewErrors(errs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *watcher) listFilesIn(base string, force bool) error {
|
func (w *watcher) listFilesIn(base string, force bool) error {
|
||||||
|
@ -122,7 +109,7 @@ func (w *watcher) listFilesIn(base string, force bool) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return types.NewErrors(errs...)
|
return merr.NewErrors(errs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *watcher) deploy(path string, compareChecksum bool) error {
|
func (w *watcher) deploy(path string, compareChecksum bool) error {
|
||||||
|
@ -148,24 +135,14 @@ func (w *watcher) deploy(path string, compareChecksum bool) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
clients, err := w.apply(addon, objectSet)
|
if err := w.apply.WithOwner(&addon).Apply(objectSet); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if w.clients == nil {
|
|
||||||
w.clients = map[schema.GroupVersionKind]*objectclient.ObjectClient{}
|
|
||||||
}
|
|
||||||
|
|
||||||
addon.Spec.Source = path
|
addon.Spec.Source = path
|
||||||
addon.Spec.Checksum = checksum
|
addon.Spec.Checksum = checksum
|
||||||
addon.Status.GVKs = nil
|
addon.Status.GVKs = nil
|
||||||
|
|
||||||
for gvk, client := range clients {
|
|
||||||
addon.Status.GVKs = append(addon.Status.GVKs, gvk)
|
|
||||||
w.clients[gvk] = client
|
|
||||||
}
|
|
||||||
|
|
||||||
if addon.UID == "" {
|
if addon.UID == "" {
|
||||||
_, err := w.addons.Create(&addon)
|
_, err := w.addons.Create(&addon)
|
||||||
return err
|
return err
|
||||||
|
@ -175,55 +152,16 @@ func (w *watcher) deploy(path string, compareChecksum bool) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *watcher) addon(name string) (v1.Addon, error) {
|
func (w *watcher) addon(name string) (v12.Addon, error) {
|
||||||
addon, err := w.addonCache.Get(ns, name)
|
addon, err := w.addonCache.Get(ns, name)
|
||||||
if errors.IsNotFound(err) {
|
if errors.IsNotFound(err) {
|
||||||
addon = v1.NewAddon(ns, name, v1.Addon{})
|
addon = v12.NewAddon(ns, name, v12.Addon{})
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return v1.Addon{}, err
|
return v12.Addon{}, err
|
||||||
}
|
}
|
||||||
return *addon, nil
|
return *addon, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *watcher) apply(addon v1.Addon, set *objectset.ObjectSet) (map[schema.GroupVersionKind]*objectclient.ObjectClient, error) {
|
|
||||||
var (
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
|
|
||||||
op := objectset.NewProcessor(addon.Name)
|
|
||||||
op.AllowDiscovery(w.discovery, w.restConfig)
|
|
||||||
|
|
||||||
ds := op.NewDesiredSet(nil, set)
|
|
||||||
|
|
||||||
for _, gvk := range addon.Status.GVKs {
|
|
||||||
var (
|
|
||||||
namespaced bool
|
|
||||||
)
|
|
||||||
|
|
||||||
client, ok := w.clients[gvk]
|
|
||||||
if ok {
|
|
||||||
namespaced = w.namespaced[gvk]
|
|
||||||
} else {
|
|
||||||
client, namespaced, err = objectset.NewDiscoveredClient(gvk, w.restConfig, w.discovery)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if w.namespaced == nil {
|
|
||||||
w.namespaced = map[schema.GroupVersionKind]bool{}
|
|
||||||
}
|
|
||||||
w.namespaced[gvk] = namespaced
|
|
||||||
}
|
|
||||||
|
|
||||||
ds.AddDiscoveredClient(gvk, client, namespaced)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := ds.Apply(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return ds.DiscoveredClients(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func objectSet(content []byte) (*objectset.ObjectSet, error) {
|
func objectSet(content []byte) (*objectset.ObjectSet, error) {
|
||||||
objs, err := yamlToObjects(bytes.NewBuffer(content))
|
objs, err := yamlToObjects(bytes.NewBuffer(content))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -5,38 +5,39 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
coreclient "github.com/rancher/k3s/types/apis/core/v1"
|
coreclient "github.com/rancher/k3s/pkg/generated/controllers/core/v1"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
core "k8s.io/api/core/v1"
|
core "k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func Register(ctx context.Context) error {
|
func Register(ctx context.Context, configMap coreclient.ConfigMapController, nodes coreclient.NodeController) error {
|
||||||
clients := coreclient.ClientsFrom(ctx)
|
|
||||||
h := &handler{
|
h := &handler{
|
||||||
configCache: clients.ConfigMap.Cache(),
|
configCache: configMap.Cache(),
|
||||||
configClient: clients.ConfigMap,
|
configClient: configMap,
|
||||||
}
|
}
|
||||||
clients.Node.OnChange(ctx, "node", h.onChange)
|
nodes.OnChange(ctx, "node", h.onChange)
|
||||||
clients.Node.OnRemove(ctx, "node", h.onRemove)
|
nodes.OnRemove(ctx, "node", h.onRemove)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type handler struct {
|
type handler struct {
|
||||||
configCache coreclient.ConfigMapClientCache
|
configCache coreclient.ConfigMapCache
|
||||||
configClient coreclient.ConfigMapClient
|
configClient coreclient.ConfigMapClient
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *handler) onChange(node *core.Node) (runtime.Object, error) {
|
func (h *handler) onChange(key string, node *core.Node) (*core.Node, error) {
|
||||||
|
if node == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
return h.updateHosts(node, false)
|
return h.updateHosts(node, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *handler) onRemove(node *core.Node) (runtime.Object, error) {
|
func (h *handler) onRemove(key string, node *core.Node) (*core.Node, error) {
|
||||||
return h.updateHosts(node, true)
|
return h.updateHosts(node, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *handler) updateHosts(node *core.Node, removed bool) (runtime.Object, error) {
|
func (h *handler) updateHosts(node *core.Node, removed bool) (*core.Node, error) {
|
||||||
var (
|
var (
|
||||||
newHosts string
|
newHosts string
|
||||||
nodeAddress string
|
nodeAddress string
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
package proxy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/tls"
|
||||||
|
"crypto/x509"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
"k8s.io/apimachinery/pkg/util/proxy"
|
||||||
|
"k8s.io/client-go/rest"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
er = &errorResponder{}
|
||||||
|
)
|
||||||
|
|
||||||
|
type errorResponder struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *errorResponder) Error(w http.ResponseWriter, req *http.Request, err error) {
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
w.Write([]byte(err.Error()))
|
||||||
|
}
|
||||||
|
|
||||||
|
type SimpleProxy struct {
|
||||||
|
url *url.URL
|
||||||
|
transport http.RoundTripper
|
||||||
|
overrideHostHeader bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSimpleProxy(host string, caData []byte, overrideHostHeader bool) (*SimpleProxy, error) {
|
||||||
|
hostURL, _, err := rest.DefaultServerURL(host, "", schema.GroupVersion{}, true)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ht := &http.Transport{}
|
||||||
|
if len(caData) > 0 {
|
||||||
|
certPool := x509.NewCertPool()
|
||||||
|
certPool.AppendCertsFromPEM(caData)
|
||||||
|
ht.TLSClientConfig = &tls.Config{
|
||||||
|
RootCAs: certPool,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &SimpleProxy{
|
||||||
|
url: hostURL,
|
||||||
|
transport: ht,
|
||||||
|
overrideHostHeader: overrideHostHeader,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SimpleProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||||
|
u := *s.url
|
||||||
|
u.Path = req.URL.Path
|
||||||
|
u.RawQuery = req.URL.RawQuery
|
||||||
|
req.URL.Scheme = "https"
|
||||||
|
req.URL.Host = req.Host
|
||||||
|
if s.overrideHostHeader {
|
||||||
|
req.Host = u.Host
|
||||||
|
}
|
||||||
|
httpProxy := proxy.NewUpgradeAwareHandler(&u, s.transport, false, false, er)
|
||||||
|
httpProxy.ServeHTTP(rw, req)
|
||||||
|
}
|
|
@ -4,21 +4,20 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
coreClients "github.com/rancher/k3s/pkg/generated/controllers/core/v1"
|
||||||
"github.com/rancher/k3s/pkg/rootless"
|
"github.com/rancher/k3s/pkg/rootless"
|
||||||
coreClients "github.com/rancher/k3s/types/apis/core/v1"
|
|
||||||
"github.com/rootless-containers/rootlesskit/pkg/api/client"
|
"github.com/rootless-containers/rootlesskit/pkg/api/client"
|
||||||
"github.com/rootless-containers/rootlesskit/pkg/port"
|
"github.com/rootless-containers/rootlesskit/pkg/port"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/labels"
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
all = "_all_"
|
all = "_all_"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Register(ctx context.Context, httpsPort int) error {
|
func Register(ctx context.Context, serviceController coreClients.ServiceController, httpsPort int) error {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
rootlessClient client.Client
|
rootlessClient client.Client
|
||||||
|
@ -28,7 +27,6 @@ func Register(ctx context.Context, httpsPort int) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
coreClients := coreClients.ClientsFrom(ctx)
|
|
||||||
for i := 0; i < 30; i++ {
|
for i := 0; i < 30; i++ {
|
||||||
rootlessClient, err = client.New(rootless.Sock)
|
rootlessClient, err = client.New(rootless.Sock)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
@ -44,26 +42,26 @@ func Register(ctx context.Context, httpsPort int) error {
|
||||||
|
|
||||||
h := &handler{
|
h := &handler{
|
||||||
rootlessClient: rootlessClient,
|
rootlessClient: rootlessClient,
|
||||||
serviceClient: coreClients.Service,
|
serviceClient: serviceController,
|
||||||
serviceCache: coreClients.Service.Cache(),
|
serviceCache: serviceController.Cache(),
|
||||||
httpsPort: httpsPort,
|
httpsPort: httpsPort,
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
}
|
}
|
||||||
coreClients.Service.Interface().Controller().AddHandler(ctx, "rootlessports", h.serviceChanged)
|
serviceController.OnChange(ctx, "rootlessports", h.serviceChanged)
|
||||||
coreClients.Service.Enqueue("", all)
|
serviceController.Enqueue("", all)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type handler struct {
|
type handler struct {
|
||||||
rootlessClient client.Client
|
rootlessClient client.Client
|
||||||
serviceClient coreClients.ServiceClient
|
serviceClient coreClients.ServiceController
|
||||||
serviceCache coreClients.ServiceClientCache
|
serviceCache coreClients.ServiceCache
|
||||||
httpsPort int
|
httpsPort int
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *handler) serviceChanged(key string, svc *v1.Service) (runtime.Object, error) {
|
func (h *handler) serviceChanged(key string, svc *v1.Service) (*v1.Service, error) {
|
||||||
if key != all {
|
if key != all {
|
||||||
h.serviceClient.Enqueue("", all)
|
h.serviceClient.Enqueue("", all)
|
||||||
return svc, nil
|
return svc, nil
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/rancher/k3s/pkg/generated/controllers/apps"
|
||||||
|
"github.com/rancher/k3s/pkg/generated/controllers/core"
|
||||||
|
"github.com/rancher/k3s/pkg/generated/controllers/k3s.cattle.io"
|
||||||
|
"github.com/rancher/wrangler/pkg/apply"
|
||||||
|
"github.com/rancher/wrangler/pkg/crd"
|
||||||
|
"github.com/rancher/wrangler/pkg/start"
|
||||||
|
"k8s.io/client-go/rest"
|
||||||
|
"k8s.io/kubernetes/staging/src/k8s.io/client-go/kubernetes"
|
||||||
|
"k8s.io/kubernetes/staging/src/k8s.io/client-go/tools/clientcmd"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Context struct {
|
||||||
|
K3s *k3s.Factory
|
||||||
|
Apps *apps.Factory
|
||||||
|
Core *core.Factory
|
||||||
|
K8s kubernetes.Interface
|
||||||
|
Apply apply.Apply
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Context) Start(ctx context.Context) error {
|
||||||
|
return start.All(ctx, 5, c.K3s, c.Apps, c.Core)
|
||||||
|
}
|
||||||
|
|
||||||
|
func newContext(ctx context.Context, cfg string) (*Context, error) {
|
||||||
|
restConfig, err := clientcmd.BuildConfigFromFlags("", cfg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := crds(ctx, restConfig); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
k8s := kubernetes.NewForConfigOrDie(restConfig)
|
||||||
|
return &Context{
|
||||||
|
K3s: k3s.NewFactoryFromConfigOrDie(restConfig),
|
||||||
|
K8s: k8s,
|
||||||
|
Apps: apps.NewFactoryFromConfigOrDie(restConfig),
|
||||||
|
Core: core.NewFactoryFromConfigOrDie(restConfig),
|
||||||
|
Apply: apply.New(k8s, apply.NewClientFactory(restConfig)),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func crds(ctx context.Context, config *rest.Config) error {
|
||||||
|
factory, err := crd.NewFactoryFromClient(config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
factory.BatchCreateCRDs(ctx, crd.NamespacedTypes(
|
||||||
|
"ListenerConfig.k3s.cattle.io/v1",
|
||||||
|
"Addon.k3s.cattle.io/v1",
|
||||||
|
"HelmChart.k3s.cattle.io/v1")...)
|
||||||
|
|
||||||
|
return factory.BatchWait()
|
||||||
|
}
|
|
@ -15,9 +15,9 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
|
certutil "github.com/rancher/dynamiclistener/cert"
|
||||||
"github.com/rancher/k3s/pkg/daemons/config"
|
"github.com/rancher/k3s/pkg/daemons/config"
|
||||||
"github.com/rancher/k3s/pkg/openapi"
|
"github.com/rancher/k3s/pkg/openapi"
|
||||||
certutil "github.com/rancher/norman/pkg/cert"
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"k8s.io/apimachinery/pkg/util/json"
|
"k8s.io/apimachinery/pkg/util/json"
|
||||||
"k8s.io/kubernetes/pkg/master"
|
"k8s.io/kubernetes/pkg/master"
|
||||||
|
|
|
@ -14,26 +14,19 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
"github.com/rancher/dynamiclistener"
|
||||||
|
"github.com/rancher/k3s/pkg/clientaccess"
|
||||||
"github.com/rancher/k3s/pkg/daemons/config"
|
"github.com/rancher/k3s/pkg/daemons/config"
|
||||||
"github.com/rancher/k3s/pkg/daemons/control"
|
"github.com/rancher/k3s/pkg/daemons/control"
|
||||||
"github.com/rancher/k3s/pkg/datadir"
|
"github.com/rancher/k3s/pkg/datadir"
|
||||||
"github.com/rancher/k3s/pkg/deploy"
|
"github.com/rancher/k3s/pkg/deploy"
|
||||||
"github.com/rancher/k3s/pkg/helm"
|
|
||||||
"github.com/rancher/k3s/pkg/node"
|
"github.com/rancher/k3s/pkg/node"
|
||||||
"github.com/rancher/k3s/pkg/rootlessports"
|
"github.com/rancher/k3s/pkg/rootlessports"
|
||||||
"github.com/rancher/k3s/pkg/servicelb"
|
"github.com/rancher/k3s/pkg/servicelb"
|
||||||
"github.com/rancher/k3s/pkg/static"
|
"github.com/rancher/k3s/pkg/static"
|
||||||
"github.com/rancher/k3s/pkg/tls"
|
"github.com/rancher/k3s/pkg/tls"
|
||||||
appsv1 "github.com/rancher/k3s/types/apis/apps/v1"
|
"github.com/rancher/wrangler/pkg/leader"
|
||||||
batchv1 "github.com/rancher/k3s/types/apis/batch/v1"
|
"github.com/rancher/wrangler/pkg/resolvehome"
|
||||||
corev1 "github.com/rancher/k3s/types/apis/core/v1"
|
|
||||||
v1 "github.com/rancher/k3s/types/apis/k3s.cattle.io/v1"
|
|
||||||
rbacv1 "github.com/rancher/k3s/types/apis/rbac.authorization.k8s.io/v1"
|
|
||||||
"github.com/rancher/norman"
|
|
||||||
"github.com/rancher/norman/pkg/clientaccess"
|
|
||||||
"github.com/rancher/norman/pkg/dynamiclistener"
|
|
||||||
"github.com/rancher/norman/pkg/resolvehome"
|
|
||||||
"github.com/rancher/norman/types"
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"k8s.io/apimachinery/pkg/util/net"
|
"k8s.io/apimachinery/pkg/util/net"
|
||||||
)
|
)
|
||||||
|
@ -44,7 +37,6 @@ func resolveDataDir(dataDir string) (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func StartServer(ctx context.Context, config *Config) (string, error) {
|
func StartServer(ctx context.Context, config *Config) (string, error) {
|
||||||
|
|
||||||
if err := setupDataDirAndChdir(&config.ControlConfig); err != nil {
|
if err := setupDataDirAndChdir(&config.ControlConfig); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
@ -57,7 +49,7 @@ func StartServer(ctx context.Context, config *Config) (string, error) {
|
||||||
return "", errors.Wrap(err, "starting kubernetes")
|
return "", errors.Wrap(err, "starting kubernetes")
|
||||||
}
|
}
|
||||||
|
|
||||||
certs, err := startNorman(ctx, config)
|
certs, err := startWrangler(ctx, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.Wrap(err, "starting tls server")
|
return "", errors.Wrap(err, "starting tls server")
|
||||||
}
|
}
|
||||||
|
@ -76,7 +68,7 @@ func StartServer(ctx context.Context, config *Config) (string, error) {
|
||||||
return certs, nil
|
return certs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func startNorman(ctx context.Context, config *Config) (string, error) {
|
func startWrangler(ctx context.Context, config *Config) (string, error) {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
tlsServer dynamiclistener.ServerInterface
|
tlsServer dynamiclistener.ServerInterface
|
||||||
|
@ -91,76 +83,90 @@ func startNorman(ctx context.Context, config *Config) (string, error) {
|
||||||
return tlsServer.CACert()
|
return tlsServer.CACert()
|
||||||
})
|
})
|
||||||
|
|
||||||
normanConfig := &norman.Config{
|
sc, err := newContext(ctx, controlConfig.Runtime.KubeConfigSystem)
|
||||||
Name: "k3s",
|
if err != nil {
|
||||||
KubeConfig: controlConfig.Runtime.KubeConfigSystem,
|
|
||||||
Clients: []norman.ClientFactory{
|
|
||||||
v1.Factory,
|
|
||||||
appsv1.Factory,
|
|
||||||
corev1.Factory,
|
|
||||||
batchv1.Factory,
|
|
||||||
rbacv1.Factory,
|
|
||||||
},
|
|
||||||
Schemas: []*types.Schemas{
|
|
||||||
v1.Schemas,
|
|
||||||
},
|
|
||||||
CRDs: map[*types.APIVersion][]string{
|
|
||||||
&v1.APIVersion: {
|
|
||||||
v1.ListenerConfigGroupVersionKind.Kind,
|
|
||||||
v1.AddonGroupVersionKind.Kind,
|
|
||||||
v1.HelmChartGroupVersionKind.Kind,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
IgnoredKubeConfigEnv: true,
|
|
||||||
GlobalSetup: func(ctx context.Context) (context.Context, error) {
|
|
||||||
tlsServer, err = tls.NewServer(ctx, v1.ClientsFrom(ctx).ListenerConfig, *tlsConfig)
|
|
||||||
return ctx, err
|
|
||||||
},
|
|
||||||
DisableLeaderElection: true,
|
|
||||||
MasterControllers: []norman.ControllerRegister{
|
|
||||||
node.Register,
|
|
||||||
helm.Register,
|
|
||||||
func(ctx context.Context) error {
|
|
||||||
return servicelb.Register(ctx, norman.GetServer(ctx).K8sClient, !config.DisableServiceLB,
|
|
||||||
config.Rootless)
|
|
||||||
},
|
|
||||||
func(ctx context.Context) error {
|
|
||||||
dataDir := filepath.Join(controlConfig.DataDir, "static")
|
|
||||||
return static.Stage(dataDir)
|
|
||||||
},
|
|
||||||
func(ctx context.Context) error {
|
|
||||||
dataDir := filepath.Join(controlConfig.DataDir, "manifests")
|
|
||||||
templateVars := map[string]string{"%{CLUSTER_DNS}%": controlConfig.ClusterDNS.String(), "%{CLUSTER_DOMAIN}%": controlConfig.ClusterDomain}
|
|
||||||
if err := deploy.Stage(dataDir, templateVars, controlConfig.Skips); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := deploy.WatchFiles(ctx, dataDir); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
func(ctx context.Context) error {
|
|
||||||
if !config.DisableServiceLB && config.Rootless {
|
|
||||||
return rootlessports.Register(ctx, config.TLSConfig.HTTPSPort)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, _, err = normanConfig.Build(ctx, nil); err != nil {
|
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
for {
|
if err := stageFiles(ctx, sc, controlConfig); err != nil {
|
||||||
certs, err := tlsServer.CACert()
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
tlsServer, err = tls.NewServer(ctx, sc.K3s.K3s().V1().ListenerConfig(), *tlsConfig)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := sc.Start(ctx); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
certs := ""
|
||||||
|
for certs == "" {
|
||||||
|
certs, err = tlsServer.CACert()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Infof("waiting to generate CA certs")
|
logrus.Infof("waiting to generate CA certs")
|
||||||
time.Sleep(time.Second)
|
time.Sleep(time.Second)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
return certs, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
go leader.RunOrDie(ctx, "", "k3s", sc.K8s, func(ctx context.Context) {
|
||||||
|
if err := masterControllers(ctx, sc, config); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if err := sc.Start(ctx); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return certs, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func masterControllers(ctx context.Context, sc *Context, config *Config) error {
|
||||||
|
if err := node.Register(ctx, sc.Core.Core().V1().ConfigMap(), sc.Core.Core().V1().Node()); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
//helm.Register
|
||||||
|
|
||||||
|
if err := servicelb.Register(ctx,
|
||||||
|
sc.K8s,
|
||||||
|
sc.Apply,
|
||||||
|
sc.Apps.Apps().V1().DaemonSet(),
|
||||||
|
sc.Apps.Apps().V1().Deployment(),
|
||||||
|
sc.Core.Core().V1().Node(),
|
||||||
|
sc.Core.Core().V1().Pod(),
|
||||||
|
sc.Core.Core().V1().Service(),
|
||||||
|
sc.Core.Core().V1().Endpoints(),
|
||||||
|
!config.DisableServiceLB, config.Rootless); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !config.DisableServiceLB && config.Rootless {
|
||||||
|
return rootlessports.Register(ctx, sc.Core.Core().V1().Service(), config.TLSConfig.HTTPSPort)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func stageFiles(ctx context.Context, sc *Context, controlConfig *config.Control) error {
|
||||||
|
dataDir := filepath.Join(controlConfig.DataDir, "static")
|
||||||
|
if err := static.Stage(dataDir); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
dataDir = filepath.Join(controlConfig.DataDir, "manifests")
|
||||||
|
templateVars := map[string]string{
|
||||||
|
"%{CLUSTER_DNS}%": controlConfig.ClusterDNS.String(),
|
||||||
|
"%{CLUSTER_DOMAIN}%": controlConfig.ClusterDomain,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := deploy.Stage(dataDir, templateVars, controlConfig.Skips); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return deploy.WatchFiles(ctx, sc.K3s.K3s().V1().Addon(), dataDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
func HomeKubeConfig(write, rootless bool) (string, error) {
|
func HomeKubeConfig(write, rootless bool) (string, error) {
|
||||||
|
@ -198,7 +204,6 @@ func printTokens(certs, advertiseIP string, tlsConfig *dynamiclistener.UserConfi
|
||||||
if len(nodeFile) > 0 {
|
if len(nodeFile) > 0 {
|
||||||
printToken(tlsConfig.HTTPSPort, advertiseIP, "To join node to cluster:", "agent")
|
printToken(tlsConfig.HTTPSPort, advertiseIP, "To join node to cluster:", "agent")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeKubeConfig(certs string, tlsConfig *dynamiclistener.UserConfig, config *Config) {
|
func writeKubeConfig(certs string, tlsConfig *dynamiclistener.UserConfig, config *Config) {
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/rancher/dynamiclistener"
|
||||||
"github.com/rancher/k3s/pkg/daemons/config"
|
"github.com/rancher/k3s/pkg/daemons/config"
|
||||||
"github.com/rancher/norman/pkg/dynamiclistener"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
|
|
|
@ -6,12 +6,15 @@ import (
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
appclient "github.com/rancher/k3s/types/apis/apps/v1"
|
"github.com/rancher/wrangler/pkg/slice"
|
||||||
coreclient "github.com/rancher/k3s/types/apis/core/v1"
|
|
||||||
"github.com/rancher/norman/condition"
|
"github.com/rancher/wrangler/pkg/relatedresource"
|
||||||
"github.com/rancher/norman/pkg/changeset"
|
|
||||||
"github.com/rancher/norman/pkg/objectset"
|
appclient "github.com/rancher/k3s/pkg/generated/controllers/apps/v1"
|
||||||
"github.com/rancher/norman/types/slice"
|
coreclient "github.com/rancher/k3s/pkg/generated/controllers/core/v1"
|
||||||
|
"github.com/rancher/wrangler/pkg/apply"
|
||||||
|
"github.com/rancher/wrangler/pkg/condition"
|
||||||
|
"github.com/rancher/wrangler/pkg/objectset"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
apps "k8s.io/api/apps/v1"
|
apps "k8s.io/api/apps/v1"
|
||||||
core "k8s.io/api/core/v1"
|
core "k8s.io/api/core/v1"
|
||||||
|
@ -37,31 +40,37 @@ var (
|
||||||
trueVal = true
|
trueVal = true
|
||||||
)
|
)
|
||||||
|
|
||||||
func Register(ctx context.Context, kubernetes kubernetes.Interface, enabled, rootless bool) error {
|
func Register(ctx context.Context,
|
||||||
clients := coreclient.ClientsFrom(ctx)
|
kubernetes kubernetes.Interface,
|
||||||
appClients := appclient.ClientsFrom(ctx)
|
apply apply.Apply,
|
||||||
|
daemonSetController appclient.DaemonSetController,
|
||||||
|
deployments appclient.DeploymentController,
|
||||||
|
nodes coreclient.NodeController,
|
||||||
|
pods coreclient.PodController,
|
||||||
|
services coreclient.ServiceController,
|
||||||
|
endpoints coreclient.EndpointsController,
|
||||||
|
enabled, rootless bool) error {
|
||||||
h := &handler{
|
h := &handler{
|
||||||
rootless: rootless,
|
rootless: rootless,
|
||||||
enabled: enabled,
|
enabled: enabled,
|
||||||
nodeCache: clients.Node.Cache(),
|
nodeCache: nodes.Cache(),
|
||||||
podCache: clients.Pod.Cache(),
|
podCache: pods.Cache(),
|
||||||
deploymentCache: appClients.Deployment.Cache(),
|
deploymentCache: deployments.Cache(),
|
||||||
processor: objectset.NewProcessor("svccontroller").
|
processor: apply.WithSetID("svccontroller").
|
||||||
Client(appClients.DaemonSet),
|
WithCacheTypes(daemonSetController),
|
||||||
serviceCache: clients.Service.Cache(),
|
serviceCache: services.Cache(),
|
||||||
services: kubernetes.CoreV1(),
|
services: kubernetes.CoreV1(),
|
||||||
daemonsets: kubernetes.AppsV1(),
|
daemonsets: kubernetes.AppsV1(),
|
||||||
deployments: kubernetes.AppsV1(),
|
deployments: kubernetes.AppsV1(),
|
||||||
}
|
}
|
||||||
|
|
||||||
clients.Service.OnChange(ctx, "svccontroller", h.onChangeService)
|
services.OnChange(ctx, "svccontroller", h.onChangeService)
|
||||||
clients.Node.OnChange(ctx, "svccontroller", h.onChangeNode)
|
nodes.OnChange(ctx, "svccontroller", h.onChangeNode)
|
||||||
changeset.Watch(ctx, "svccontroller-watcher",
|
relatedresource.Watch(ctx, "svccontroller-watcher",
|
||||||
h.onResourceChange,
|
h.onResourceChange,
|
||||||
clients.Service,
|
services,
|
||||||
clients.Pod,
|
pods,
|
||||||
clients.Endpoints)
|
endpoints)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -69,19 +78,19 @@ func Register(ctx context.Context, kubernetes kubernetes.Interface, enabled, roo
|
||||||
type handler struct {
|
type handler struct {
|
||||||
rootless bool
|
rootless bool
|
||||||
enabled bool
|
enabled bool
|
||||||
nodeCache coreclient.NodeClientCache
|
nodeCache coreclient.NodeCache
|
||||||
podCache coreclient.PodClientCache
|
podCache coreclient.PodCache
|
||||||
deploymentCache appclient.DeploymentClientCache
|
deploymentCache appclient.DeploymentCache
|
||||||
processor *objectset.Processor
|
processor apply.Apply
|
||||||
serviceCache coreclient.ServiceClientCache
|
serviceCache coreclient.ServiceCache
|
||||||
services coregetter.ServicesGetter
|
services coregetter.ServicesGetter
|
||||||
daemonsets v1getter.DaemonSetsGetter
|
daemonsets v1getter.DaemonSetsGetter
|
||||||
deployments v1getter.DeploymentsGetter
|
deployments v1getter.DeploymentsGetter
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *handler) onResourceChange(name, namespace string, obj runtime.Object) ([]changeset.Key, error) {
|
func (h *handler) onResourceChange(name, namespace string, obj runtime.Object) ([]relatedresource.Key, error) {
|
||||||
if ep, ok := obj.(*core.Endpoints); ok {
|
if ep, ok := obj.(*core.Endpoints); ok {
|
||||||
return []changeset.Key{
|
return []relatedresource.Key{
|
||||||
{
|
{
|
||||||
Name: ep.Name,
|
Name: ep.Name,
|
||||||
Namespace: ep.Namespace,
|
Namespace: ep.Namespace,
|
||||||
|
@ -103,7 +112,7 @@ func (h *handler) onResourceChange(name, namespace string, obj runtime.Object) (
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return []changeset.Key{
|
return []relatedresource.Key{
|
||||||
{
|
{
|
||||||
Name: serviceName,
|
Name: serviceName,
|
||||||
Namespace: pod.Namespace,
|
Namespace: pod.Namespace,
|
||||||
|
@ -111,7 +120,11 @@ func (h *handler) onResourceChange(name, namespace string, obj runtime.Object) (
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *handler) onChangeService(svc *core.Service) (runtime.Object, error) {
|
func (h *handler) onChangeService(key string, svc *core.Service) (*core.Service, error) {
|
||||||
|
if svc == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
if svc.Spec.Type != core.ServiceTypeLoadBalancer || svc.Spec.ClusterIP == "" ||
|
if svc.Spec.Type != core.ServiceTypeLoadBalancer || svc.Spec.ClusterIP == "" ||
|
||||||
svc.Spec.ClusterIP == "None" {
|
svc.Spec.ClusterIP == "None" {
|
||||||
return svc, nil
|
return svc, nil
|
||||||
|
@ -126,7 +139,10 @@ func (h *handler) onChangeService(svc *core.Service) (runtime.Object, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *handler) onChangeNode(node *core.Node) (runtime.Object, error) {
|
func (h *handler) onChangeNode(key string, node *core.Node) (*core.Node, error) {
|
||||||
|
if node == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
if _, ok := node.Labels[daemonsetNodeLabel]; !ok {
|
if _, ok := node.Labels[daemonsetNodeLabel]; !ok {
|
||||||
return node, nil
|
return node, nil
|
||||||
}
|
}
|
||||||
|
@ -195,7 +211,7 @@ func (h *handler) podIPs(pods []*core.Pod) ([]string, error) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
node, err := h.nodeCache.Get("", pod.Spec.NodeName)
|
node, err := h.nodeCache.Get(pod.Spec.NodeName)
|
||||||
if errors.IsNotFound(err) {
|
if errors.IsNotFound(err) {
|
||||||
continue
|
continue
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
|
@ -227,7 +243,7 @@ func (h *handler) deployPod(svc *core.Service) error {
|
||||||
}
|
}
|
||||||
objs := objectset.NewObjectSet()
|
objs := objectset.NewObjectSet()
|
||||||
if !h.enabled {
|
if !h.enabled {
|
||||||
return h.processor.NewDesiredSet(svc, objs).Apply()
|
return h.processor.WithOwner(svc).Apply(objs)
|
||||||
}
|
}
|
||||||
|
|
||||||
ds, err := h.newDaemonSet(svc)
|
ds, err := h.newDaemonSet(svc)
|
||||||
|
@ -237,7 +253,7 @@ func (h *handler) deployPod(svc *core.Service) error {
|
||||||
if ds != nil {
|
if ds != nil {
|
||||||
objs.Add(ds)
|
objs.Add(ds)
|
||||||
}
|
}
|
||||||
return h.processor.NewDesiredSet(svc, objs).Apply()
|
return h.processor.WithOwner(svc).Apply(objs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *handler) newDaemonSet(svc *core.Service) (*apps.DaemonSet, error) {
|
func (h *handler) newDaemonSet(svc *core.Service) (*apps.DaemonSet, error) {
|
||||||
|
@ -335,7 +351,7 @@ func (h *handler) newDaemonSet(svc *core.Service) (*apps.DaemonSet, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
nodesWithLabel, err := h.nodeCache.List("", selector)
|
nodesWithLabel, err := h.nodeCache.List(selector)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,11 +3,11 @@ package tls
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
v1 "github.com/rancher/k3s/types/apis/k3s.cattle.io/v1"
|
"github.com/rancher/dynamiclistener"
|
||||||
"github.com/rancher/norman/pkg/dynamiclistener"
|
v1 "github.com/rancher/k3s/pkg/apis/k3s.cattle.io/v1"
|
||||||
|
k3sclient "github.com/rancher/k3s/pkg/generated/controllers/k3s.cattle.io/v1"
|
||||||
"k8s.io/apimachinery/pkg/api/errors"
|
"k8s.io/apimachinery/pkg/api/errors"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -15,14 +15,21 @@ const (
|
||||||
name = "tls-config"
|
name = "tls-config"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewServer(ctx context.Context, listenerClient v1.ListenerConfigClient, config dynamiclistener.UserConfig) (dynamiclistener.ServerInterface, error) {
|
func NewServer(ctx context.Context, listenerConfigs k3sclient.ListenerConfigController, config dynamiclistener.UserConfig) (dynamiclistener.ServerInterface, error) {
|
||||||
storage := &listenerConfigStorage{
|
storage := &listenerConfigStorage{
|
||||||
client: listenerClient,
|
client: listenerConfigs,
|
||||||
cache: listenerClient.Cache(),
|
cache: listenerConfigs.Cache(),
|
||||||
}
|
}
|
||||||
|
|
||||||
server, err := dynamiclistener.NewServer(storage, config)
|
server, err := dynamiclistener.NewServer(storage, config)
|
||||||
listenerClient.OnChange(ctx, "listen-config", func(obj *v1.ListenerConfig) (runtime.Object, error) {
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
listenerConfigs.OnChange(ctx, "listen-config", func(key string, obj *v1.ListenerConfig) (*v1.ListenerConfig, error) {
|
||||||
|
if obj == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
return obj, server.Update(fromStorage(obj))
|
return obj, server.Update(fromStorage(obj))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -30,8 +37,8 @@ func NewServer(ctx context.Context, listenerClient v1.ListenerConfigClient, conf
|
||||||
}
|
}
|
||||||
|
|
||||||
type listenerConfigStorage struct {
|
type listenerConfigStorage struct {
|
||||||
cache v1.ListenerConfigClientCache
|
cache k3sclient.ListenerConfigCache
|
||||||
client v1.ListenerConfigClient
|
client k3sclient.ListenerConfigClient
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *listenerConfigStorage) Set(config *dynamiclistener.ListenerStatus) (*dynamiclistener.ListenerStatus, error) {
|
func (l *listenerConfigStorage) Set(config *dynamiclistener.ListenerStatus) (*dynamiclistener.ListenerStatus, error) {
|
||||||
|
@ -65,6 +72,9 @@ func (l *listenerConfigStorage) Get() (*dynamiclistener.ListenerStatus, error) {
|
||||||
if errors.IsNotFound(err) {
|
if errors.IsNotFound(err) {
|
||||||
obj, err = l.client.Get(ns, name, metav1.GetOptions{})
|
obj, err = l.client.Get(ns, name, metav1.GetOptions{})
|
||||||
}
|
}
|
||||||
|
if errors.IsNotFound(err) {
|
||||||
|
return &dynamiclistener.ListenerStatus{}, nil
|
||||||
|
}
|
||||||
return fromStorage(obj), err
|
return fromStorage(obj), err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
/*
|
||||||
|
Copyright The Kubernetes 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.
|
||||||
|
*/
|
||||||
|
|
Loading…
Reference in New Issue