Support configurations for cloudproviders

Cloud providers may need specific configurations to run properly (e.g.
authentication parameters, uri, etc.).

This patch adds the simplest implementation for passing configurations
to cloudproviders: a new apiserver -cloud_config flag to specify the
path to an arbitrary configuration file.

Signed-off-by: Federico Simoncelli <fsimonce@redhat.com>
This commit is contained in:
Federico Simoncelli 2014-09-03 21:12:20 +00:00
parent 2221d33de1
commit 6add1993c9
4 changed files with 48 additions and 17 deletions

View File

@ -22,6 +22,7 @@ import (
"flag" "flag"
"net" "net"
"net/http" "net/http"
"os"
"strconv" "strconv"
"time" "time"
@ -39,6 +40,7 @@ var (
address = flag.String("address", "127.0.0.1", "The address on the local server to listen to. Default 127.0.0.1") address = flag.String("address", "127.0.0.1", "The address on the local server to listen to. Default 127.0.0.1")
apiPrefix = flag.String("api_prefix", "/api/v1beta1", "The prefix for API requests on the server. Default '/api/v1beta1'") apiPrefix = flag.String("api_prefix", "/api/v1beta1", "The prefix for API requests on the server. Default '/api/v1beta1'")
cloudProvider = flag.String("cloud_provider", "", "The provider for cloud services. Empty string for no provider.") cloudProvider = flag.String("cloud_provider", "", "The provider for cloud services. Empty string for no provider.")
cloudConfigFile = flag.String("cloud_config", "", "The path to the cloud provider configuration file. Empty string for no configuration file.")
minionRegexp = flag.String("minion_regexp", "", "If non empty, and -cloud_provider is specified, a regular expression for matching minion VMs") minionRegexp = flag.String("minion_regexp", "", "If non empty, and -cloud_provider is specified, a regular expression for matching minion VMs")
minionPort = flag.Uint("minion_port", 10250, "The port at which kubelet will be listening on the minions.") minionPort = flag.Uint("minion_port", 10250, "The port at which kubelet will be listening on the minions.")
healthCheckMinions = flag.Bool("health_check_minions", true, "If true, health check minions and filter unhealthy ones. [default true]") healthCheckMinions = flag.Bool("health_check_minions", true, "If true, health check minions and filter unhealthy ones. [default true]")
@ -63,6 +65,37 @@ func verifyMinionFlags() {
} }
} }
func initCloudProvider(name string, configFilePath string) cloudprovider.Interface {
var config *os.File
if name == "" {
glog.Info("No cloud provider specified.")
return nil
}
if configFilePath != "" {
var err error
config, err = os.Open(configFilePath)
if err != nil {
glog.Fatalf("Couldn't open cloud provider configuration %s: %#v",
configFilePath, err)
}
defer config.Close()
}
cloud, err := cloudprovider.GetCloudProvider(name, config)
if err != nil {
glog.Fatalf("Couldn't init cloud provider %q: %#v", name, err)
}
if cloud == nil {
glog.Fatalf("Unknown cloud provider: %s", name)
}
return cloud
}
func main() { func main() {
flag.Parse() flag.Parse()
util.InitLogs() util.InitLogs()
@ -75,17 +108,7 @@ func main() {
glog.Fatalf("-etcd_servers flag is required.") glog.Fatalf("-etcd_servers flag is required.")
} }
cloud, err := cloudprovider.GetCloudProvider(*cloudProvider) cloud := initCloudProvider(*cloudProvider, *cloudConfigFile)
if err != nil {
glog.Fatalf("Couldn't init cloud provider %q: %#v", *cloudProvider, err)
}
if cloud == nil {
if len(*cloudProvider) > 0 {
glog.Fatalf("Unknown cloud provider: %s", *cloudProvider)
} else {
glog.Info("No cloud provider specified.")
}
}
podInfoGetter := &client.HTTPPodInfoGetter{ podInfoGetter := &client.HTTPPodInfoGetter{
Client: http.DefaultClient, Client: http.DefaultClient,

View File

@ -18,6 +18,7 @@ package gce_cloud
import ( import (
"fmt" "fmt"
"io"
"io/ioutil" "io/ioutil"
"net" "net"
"net/http" "net/http"
@ -40,7 +41,7 @@ type GCECloud struct {
} }
func init() { func init() {
cloudprovider.RegisterCloudProvider("gce", func() (cloudprovider.Interface, error) { return newGCECloud() }) cloudprovider.RegisterCloudProvider("gce", func(config io.Reader) (cloudprovider.Interface, error) { return newGCECloud() })
} }
func getProjectAndZone() (string, string, error) { func getProjectAndZone() (string, string, error) {

View File

@ -17,13 +17,17 @@ limitations under the License.
package cloudprovider package cloudprovider
import ( import (
"io"
"sync" "sync"
"github.com/golang/glog" "github.com/golang/glog"
) )
// Factory is a function that returns a cloudprovider.Interface. // Factory is a function that returns a cloudprovider.Interface.
type Factory func() (Interface, error) // The config parameter provides an io.Reader handler to the factory in
// order to load specific configurations. If no configuration is provided
// the parameter is nil.
type Factory func(config io.Reader) (Interface, error)
// All registered cloud providers. // All registered cloud providers.
var providersMutex sync.Mutex var providersMutex sync.Mutex
@ -44,13 +48,15 @@ func RegisterCloudProvider(name string, cloud Factory) {
// GetCloudProvider creates an instance of the named cloud provider, or nil if // GetCloudProvider creates an instance of the named cloud provider, or nil if
// the name is not known. The error return is only used if the named provider // the name is not known. The error return is only used if the named provider
// was known but failed to initialize. // was known but failed to initialize. The config parameter specifies the
func GetCloudProvider(name string) (Interface, error) { // io.Reader handler of the configuration file for the cloud provider, or nil
// for no configuation.
func GetCloudProvider(name string, config io.Reader) (Interface, error) {
providersMutex.Lock() providersMutex.Lock()
defer providersMutex.Unlock() defer providersMutex.Unlock()
f, found := providers[name] f, found := providers[name]
if !found { if !found {
return nil, nil return nil, nil
} }
return f() return f(config)
} }

View File

@ -20,6 +20,7 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"io"
"io/ioutil" "io/ioutil"
"net" "net"
"net/http" "net/http"
@ -38,7 +39,7 @@ type VagrantCloud struct {
} }
func init() { func init() {
cloudprovider.RegisterCloudProvider("vagrant", func() (cloudprovider.Interface, error) { return newVagrantCloud() }) cloudprovider.RegisterCloudProvider("vagrant", func(config io.Reader) (cloudprovider.Interface, error) { return newVagrantCloud() })
} }
// SaltToken is an authorization token required by Salt REST API. // SaltToken is an authorization token required by Salt REST API.