Merge pull request #4 from zalando-incubator/disable_teams_api_db_access_flags
Allow disabling access to the DB and the Teams API. Command-line options --nodatabaseaccess and --noteamsapi disable all teams api interaction and access to the Postgres database. This is useful for debugging purposes when the operator runs out of cluster (with --outofcluster flag). The same effect can be achieved by setting enable_db_access and/or enable_teams_api to false.
This commit is contained in:
		
						commit
						deb36f33e0
					
				
							
								
								
									
										20
									
								
								cmd/main.go
								
								
								
								
							
							
						
						
									
										20
									
								
								cmd/main.go
								
								
								
								
							|  | @ -15,16 +15,20 @@ import ( | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| var ( | var ( | ||||||
| 	KubeConfigFile string | 	KubeConfigFile   string | ||||||
| 	podNamespace   string | 	podNamespace     string | ||||||
| 	configMapName  spec.NamespacedName | 	configMapName    spec.NamespacedName | ||||||
| 	OutOfCluster   bool | 	OutOfCluster     bool | ||||||
| 	version        string | 	noTeamsAPI       bool | ||||||
|  | 	noDatabaseAccess bool | ||||||
|  | 	version          string | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func init() { | func init() { | ||||||
| 	flag.StringVar(&KubeConfigFile, "kubeconfig", "", "Path to kubeconfig file with authorization and master location information.") | 	flag.StringVar(&KubeConfigFile, "kubeconfig", "", "Path to kubeconfig file with authorization and master location information.") | ||||||
| 	flag.BoolVar(&OutOfCluster, "outofcluster", false, "Whether the operator runs in- our outside of the Kubernetes cluster.") | 	flag.BoolVar(&OutOfCluster, "outofcluster", false, "Whether the operator runs in- our outside of the Kubernetes cluster.") | ||||||
|  | 	flag.BoolVar(&noDatabaseAccess, "nodatabaseaccess", false, "Disable all access to the database from the operator side.") | ||||||
|  | 	flag.BoolVar(&noTeamsAPI, "noteamsapi", false, "Disable all access to the teams API") | ||||||
| 	flag.Parse() | 	flag.Parse() | ||||||
| 
 | 
 | ||||||
| 	podNamespace = os.Getenv("MY_POD_NAMESPACE") | 	podNamespace = os.Getenv("MY_POD_NAMESPACE") | ||||||
|  | @ -87,6 +91,12 @@ func main() { | ||||||
| 	if configMapData["namespace"] == "" { // Namespace in ConfigMap has priority over env var
 | 	if configMapData["namespace"] == "" { // Namespace in ConfigMap has priority over env var
 | ||||||
| 		configMapData["namespace"] = podNamespace | 		configMapData["namespace"] = podNamespace | ||||||
| 	} | 	} | ||||||
|  | 	if noDatabaseAccess { | ||||||
|  | 		configMapData["enable_database_access"] = "false" | ||||||
|  | 	} | ||||||
|  | 	if noTeamsAPI { | ||||||
|  | 		configMapData["enable_teams_api"] = "false" | ||||||
|  | 	} | ||||||
| 	cfg := config.NewFromMap(configMapData) | 	cfg := config.NewFromMap(configMapData) | ||||||
| 
 | 
 | ||||||
| 	log.Printf("Config: %s", cfg.MustMarshal()) | 	log.Printf("Config: %s", cfg.MustMarshal()) | ||||||
|  |  | ||||||
|  | @ -227,18 +227,20 @@ func (c *Cluster) Create(stopCh <-chan struct{}) error { | ||||||
| 	} | 	} | ||||||
| 	c.logger.Infof("Pods are ready") | 	c.logger.Infof("Pods are ready") | ||||||
| 
 | 
 | ||||||
| 	if !c.masterLess { | 	if !(c.masterLess || c.DatabaseAccessDisabled()) { | ||||||
| 		if err = c.initDbConn(); err != nil { | 		if err := c.initDbConn(); err != nil { | ||||||
| 			return fmt.Errorf("Can't init db connection: %s", err) | 			return fmt.Errorf("Can't init db connection: %s", err) | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		if err = c.createUsers(); err != nil { |  | ||||||
| 			return fmt.Errorf("Can't create users: %s", err) |  | ||||||
| 		} else { | 		} else { | ||||||
| 			c.logger.Infof("Users have been successfully created") | 			if err = c.createUsers(); err != nil { | ||||||
|  | 				return fmt.Errorf("Can't create users: %s", err) | ||||||
|  | 			} else { | ||||||
|  | 				c.logger.Infof("Users have been successfully created") | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 	} else { | 	} else { | ||||||
| 		c.logger.Warnln("Cluster is masterless") | 		if c.masterLess { | ||||||
|  | 			c.logger.Warnln("Cluster is masterless") | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	c.ListResources() | 	c.ListResources() | ||||||
|  |  | ||||||
|  | @ -1,8 +1,8 @@ | ||||||
| package cluster | package cluster | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"fmt" |  | ||||||
| 	"encoding/json" | 	"encoding/json" | ||||||
|  | 	"fmt" | ||||||
| 
 | 
 | ||||||
| 	"k8s.io/client-go/pkg/api/resource" | 	"k8s.io/client-go/pkg/api/resource" | ||||||
| 	"k8s.io/client-go/pkg/api/v1" | 	"k8s.io/client-go/pkg/api/v1" | ||||||
|  |  | ||||||
|  | @ -32,22 +32,25 @@ func (c *Cluster) pgConnectionString() string { | ||||||
| 		strings.Replace(password, "$", "\\$", -1)) | 		strings.Replace(password, "$", "\\$", -1)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (c *Cluster) initDbConn() error { | func (c *Cluster) DatabaseAccessDisabled() bool { | ||||||
| 	//TODO: concurrent safe?
 | 	if c.OpConfig.EnableDBAccess == false { | ||||||
|  | 		c.logger.Debugf("Database access is disabled") | ||||||
|  | 	} | ||||||
|  | 	return c.OpConfig.EnableDBAccess == false | ||||||
|  | } | ||||||
|  | func (c *Cluster) initDbConn() (err error) { | ||||||
| 	if c.pgDb == nil { | 	if c.pgDb == nil { | ||||||
| 		if c.pgDb == nil { | 		conn, err := sql.Open("postgres", c.pgConnectionString()) | ||||||
| 			conn, err := sql.Open("postgres", c.pgConnectionString()) | 		if err != nil { | ||||||
| 			if err != nil { | 			return err | ||||||
| 				return err |  | ||||||
| 			} |  | ||||||
| 			err = conn.Ping() |  | ||||||
| 			if err != nil { |  | ||||||
| 				conn.Close() |  | ||||||
| 				return err |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			c.pgDb = conn |  | ||||||
| 		} | 		} | ||||||
|  | 		err = conn.Ping() | ||||||
|  | 		if err != nil { | ||||||
|  | 			conn.Close() | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		c.pgDb = conn | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return nil | 	return nil | ||||||
|  |  | ||||||
|  | @ -36,6 +36,9 @@ func (c *Cluster) SyncCluster(stopCh <-chan struct{}) { | ||||||
| 	if err := c.syncStatefulSet(); err != nil { | 	if err := c.syncStatefulSet(); err != nil { | ||||||
| 		c.logger.Errorf("Can't sync StatefulSets: %s", err) | 		c.logger.Errorf("Can't sync StatefulSets: %s", err) | ||||||
| 	} | 	} | ||||||
|  | 	if c.DatabaseAccessDisabled() { | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
| 	if err := c.initDbConn(); err != nil { | 	if err := c.initDbConn(); err != nil { | ||||||
| 		c.logger.Errorf("Can't init db connection: %s", err) | 		c.logger.Errorf("Can't init db connection: %s", err) | ||||||
| 	} else { | 	} else { | ||||||
|  |  | ||||||
|  | @ -50,7 +50,7 @@ func New(controllerConfig *Config, operatorConfig *config.Config) *Controller { | ||||||
| 		logger.Level = logrus.DebugLevel | 		logger.Level = logrus.DebugLevel | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	controllerConfig.TeamsAPIClient = teams.NewTeamsAPI(operatorConfig.TeamsAPIUrl, logger) | 	controllerConfig.TeamsAPIClient = teams.NewTeamsAPI(operatorConfig.TeamsAPIUrl, logger, operatorConfig.EnableTeamsAPI) | ||||||
| 	return &Controller{ | 	return &Controller{ | ||||||
| 		Config:   *controllerConfig, | 		Config:   *controllerConfig, | ||||||
| 		opConfig: operatorConfig, | 		opConfig: operatorConfig, | ||||||
|  |  | ||||||
|  | @ -4,9 +4,9 @@ import ( | ||||||
| 	"bytes" | 	"bytes" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 
 | 
 | ||||||
|  | 	remotecommandconsts "k8s.io/apimachinery/pkg/util/remotecommand" | ||||||
| 	"k8s.io/client-go/pkg/api" | 	"k8s.io/client-go/pkg/api" | ||||||
| 	"k8s.io/kubernetes/pkg/client/unversioned/remotecommand" | 	"k8s.io/kubernetes/pkg/client/unversioned/remotecommand" | ||||||
| 	remotecommandconsts "k8s.io/apimachinery/pkg/util/remotecommand" |  | ||||||
| 
 | 
 | ||||||
| 	"github.com/zalando-incubator/postgres-operator/pkg/spec" | 	"github.com/zalando-incubator/postgres-operator/pkg/spec" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | @ -52,6 +52,8 @@ type Config struct { | ||||||
| 	WALES3Bucket       string `name:"wal_s3_bucket"` | 	WALES3Bucket       string `name:"wal_s3_bucket"` | ||||||
| 	KubeIAMRole        string `name:"kube_iam_role"` | 	KubeIAMRole        string `name:"kube_iam_role"` | ||||||
| 	DebugLogging       bool   `name:"debug_logging" default:"false"` | 	DebugLogging       bool   `name:"debug_logging" default:"false"` | ||||||
|  | 	EnableDBAccess     bool   `name:"enable_database_access" default:"true"` | ||||||
|  | 	EnableTeamsAPI     bool   `name:"enable_teams_api" default:"true"` | ||||||
| 	DNSNameFormat      string `name:"dns_name_format" default:"%s.%s.%s"` | 	DNSNameFormat      string `name:"dns_name_format" default:"%s.%s.%s"` | ||||||
| 	Workers            uint32 `name:"workers" default:"4"` | 	Workers            uint32 `name:"workers" default:"4"` | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -42,13 +42,15 @@ type TeamsAPI struct { | ||||||
| 	httpClient         *http.Client | 	httpClient         *http.Client | ||||||
| 	logger             *logrus.Entry | 	logger             *logrus.Entry | ||||||
| 	RefreshTokenAction func() (string, error) | 	RefreshTokenAction func() (string, error) | ||||||
|  | 	enabled            bool | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func NewTeamsAPI(url string, log *logrus.Logger) *TeamsAPI { | func NewTeamsAPI(url string, log *logrus.Logger, enabled bool) *TeamsAPI { | ||||||
| 	t := TeamsAPI{ | 	t := TeamsAPI{ | ||||||
| 		url:        strings.TrimRight(url, "/"), | 		url:        strings.TrimRight(url, "/"), | ||||||
| 		httpClient: &http.Client{}, | 		httpClient: &http.Client{}, | ||||||
| 		logger:     log.WithField("pkg", "teamsapi"), | 		logger:     log.WithField("pkg", "teamsapi"), | ||||||
|  | 		enabled:    enabled, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return &t | 	return &t | ||||||
|  | @ -56,6 +58,10 @@ func NewTeamsAPI(url string, log *logrus.Logger) *TeamsAPI { | ||||||
| 
 | 
 | ||||||
| func (t *TeamsAPI) TeamInfo(teamId string) (*Team, error) { | func (t *TeamsAPI) TeamInfo(teamId string) (*Team, error) { | ||||||
| 	// TODO: avoid getting a new token on every call to the Teams API.
 | 	// TODO: avoid getting a new token on every call to the Teams API.
 | ||||||
|  | 	if !t.enabled { | ||||||
|  | 		t.logger.Debug("Team API is disabled, returning empty list of members") | ||||||
|  | 		return &Team{}, nil | ||||||
|  | 	} | ||||||
| 	token, err := t.RefreshTokenAction() | 	token, err := t.RefreshTokenAction() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue