7104d31d |
package router
import (
"errors" |
f88e8dc5 |
"fmt" |
131728ad |
"os" |
7104d31d |
|
5958daa5 |
"github.com/golang/glog" |
f88e8dc5 |
"github.com/spf13/cobra" |
7104d31d |
"github.com/spf13/pflag"
|
f88e8dc5 |
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
131728ad |
ocmd "github.com/openshift/origin/pkg/cmd/cli/cmd" |
6267dded |
"github.com/openshift/origin/pkg/cmd/templates" |
7104d31d |
"github.com/openshift/origin/pkg/cmd/util" |
f88e8dc5 |
"github.com/openshift/origin/pkg/cmd/util/clientcmd" |
90e3620d |
"github.com/openshift/origin/pkg/router/controller" |
a398a60d |
f5plugin "github.com/openshift/origin/pkg/router/f5" |
7104d31d |
)
|
6267dded |
var (
f5Long = templates.LongDesc(`
Start an F5 route synchronizer |
f88e8dc5 |
|
6267dded |
This command launches a process that will synchronize an F5 to the route configuration of your master. |
30f5837b |
|
6267dded |
You may restrict the set of routes exposed to a single project (with --namespace), projects your client has
access to with a set of labels (--project-labels), namespaces matching a label (--namespace-labels), or all
namespaces (no argument). You can limit the routes to those matching a --labels or --fields selector. Note
that you must have a cluster-wide administrative role to view all namespaces.`) |
f88e8dc5 |
)
// F5RouterOptions represent the complete structure needed to start an F5 router
// sync process.
type F5RouterOptions struct {
Config *clientcmd.Config
F5Router
RouterSelection
}
// F5Router is the config necessary to start an F5 router plugin.
type F5Router struct { |
7d07c18b |
RouterName string
|
7104d31d |
// Host specifies the hostname or IP address of the F5 BIG-IP host.
Host string
// Username specifies the username with which the plugin should authenticate
// with the F5 BIG-IP host.
Username string
// Password specifies the password with which the plugin should authenticate
// with the F5 BIG-IP host.
Password string
// HttpVserver specifies the name of the vserver object in F5 BIG-IP that the
// plugin will configure for HTTP connections.
HttpVserver string
// HttpsVserver specifies the name of the vserver object in F5 BIG-IP that the
// plugin will configure for HTTPS connections.
HttpsVserver string
// PrivateKey specifies the filename of an SSH private key for
// authenticating with F5. This key is required to copy certificates
// to the F5 BIG-IP host.
PrivateKey string
// Insecure specifies whether the F5 plugin should perform strict certificate
// validation for connections to the F5 BIG-IP host.
Insecure bool |
5958daa5 |
|
2eabbdc5 |
// PartitionPath specifies the path to the F5 partition. This is |
5958daa5 |
// normally used to create access control boundaries for users
// and applications.
PartitionPath string |
7104d31d |
}
|
f88e8dc5 |
// Bind binds F5Router arguments to flags
func (o *F5Router) Bind(flag *pflag.FlagSet) { |
7d07c18b |
flag.StringVar(&o.RouterName, "name", util.Env("ROUTER_SERVICE_NAME", "public"), "The name the router will identify itself with in the route status") |
f88e8dc5 |
flag.StringVar(&o.Host, "f5-host", util.Env("ROUTER_EXTERNAL_HOST_HOSTNAME", ""), "The host of F5 BIG-IP's management interface")
flag.StringVar(&o.Username, "f5-username", util.Env("ROUTER_EXTERNAL_HOST_USERNAME", ""), "The username for F5 BIG-IP's management utility")
flag.StringVar(&o.Password, "f5-password", util.Env("ROUTER_EXTERNAL_HOST_PASSWORD", ""), "The password for F5 BIG-IP's management utility")
flag.StringVar(&o.HttpVserver, "f5-http-vserver", util.Env("ROUTER_EXTERNAL_HOST_HTTP_VSERVER", "ose-vserver"), "The F5 BIG-IP virtual server for HTTP connections")
flag.StringVar(&o.HttpsVserver, "f5-https-vserver", util.Env("ROUTER_EXTERNAL_HOST_HTTPS_VSERVER", "https-ose-vserver"), "The F5 BIG-IP virtual server for HTTPS connections")
flag.StringVar(&o.PrivateKey, "f5-private-key", util.Env("ROUTER_EXTERNAL_HOST_PRIVKEY", ""), "The path to the F5 BIG-IP SSH private key file")
flag.BoolVar(&o.Insecure, "f5-insecure", util.Env("ROUTER_EXTERNAL_HOST_INSECURE", "") == "true", "Skip strict certificate verification") |
2eabbdc5 |
flag.StringVar(&o.PartitionPath, "f5-partition-path", util.Env("ROUTER_EXTERNAL_HOST_PARTITION_PATH", f5plugin.F5DefaultPartitionPath), "The F5 BIG-IP partition path to use") |
7104d31d |
}
|
f88e8dc5 |
// Validate verifies the required F5 flags are present
func (o *F5Router) Validate() error {
if o.Host == "" {
return errors.New("F5 host must be specified")
}
if o.Username == "" {
return errors.New("F5 username must be specified") |
7104d31d |
}
|
f88e8dc5 |
if o.Password == "" {
return errors.New("F5 password must be specified") |
7104d31d |
}
|
f88e8dc5 |
if len(o.HttpVserver) == 0 && len(o.HttpsVserver) == 0 {
return errors.New("F5 HTTP and HTTPS vservers cannot both be blank")
} |
5958daa5 |
|
f88e8dc5 |
return nil
}
|
a064a461 |
// NewCommandF5Router provides CLI handler for the F5 router sync plugin. |
f88e8dc5 |
func NewCommandF5Router(name string) *cobra.Command {
options := &F5RouterOptions{
Config: clientcmd.NewConfig(), |
7104d31d |
} |
f88e8dc5 |
options.Config.FromFile = true
cmd := &cobra.Command{
Use: fmt.Sprintf("%s%s", name, clientcmd.ConfigSyntax),
Short: "Start an F5 route synchronizer",
Long: f5Long,
Run: func(c *cobra.Command, args []string) {
options.RouterSelection.Namespace = cmdutil.GetFlagString(c, "namespace")
cmdutil.CheckErr(options.Complete())
cmdutil.CheckErr(options.Validate())
cmdutil.CheckErr(options.Run())
},
}
|
131728ad |
cmd.AddCommand(ocmd.NewCmdVersion(name, nil, os.Stdout, ocmd.VersionOptions{})) |
f88e8dc5 |
flag := cmd.Flags()
options.Config.Bind(flag) |
a064a461 |
options.F5Router.Bind(flag) |
f88e8dc5 |
options.RouterSelection.Bind(flag)
return cmd
}
func (o *F5RouterOptions) Complete() error { |
5958daa5 |
if len(o.PartitionPath) == 0 {
o.PartitionPath = f5plugin.F5DefaultPartitionPath
glog.Warningf("Partition path was empty, using default: %q",
f5plugin.F5DefaultPartitionPath)
}
|
f88e8dc5 |
return o.RouterSelection.Complete()
}
func (o *F5RouterOptions) Validate() error {
return o.F5Router.Validate()
} |
7104d31d |
|
f88e8dc5 |
// Run launches an F5 route sync process using the provided options. It never exits.
func (o *F5RouterOptions) Run() error {
cfg := f5plugin.F5PluginConfig{ |
5958daa5 |
Host: o.Host,
Username: o.Username,
Password: o.Password,
HttpVserver: o.HttpVserver,
HttpsVserver: o.HttpsVserver,
PrivateKey: o.PrivateKey,
Insecure: o.Insecure,
PartitionPath: o.PartitionPath, |
f88e8dc5 |
} |
90e3620d |
f5Plugin, err := f5plugin.NewF5Plugin(cfg) |
f88e8dc5 |
if err != nil {
return err |
7104d31d |
}
|
f88e8dc5 |
oc, kc, err := o.Config.Clients()
if err != nil {
return err |
7104d31d |
} |
f88e8dc5 |
|
7d07c18b |
statusPlugin := controller.NewStatusAdmitter(f5Plugin, oc, o.RouterName)
plugin := controller.NewUniqueHost(statusPlugin, o.RouteSelectionFunc(), statusPlugin)
|
f88e8dc5 |
factory := o.RouterSelection.NewFactory(oc, kc)
controller := factory.Create(plugin)
controller.Run()
select {} |
7104d31d |
} |