Skip to content
This repository was archived by the owner on Oct 11, 2019. It is now read-only.

M2GOLD-12 Support external cluster registry in voyager aggregator - #149

Open
nickhiggs wants to merge 2 commits into
masterfrom
M2GOLD-12-support-external-cluster-registry
Open

M2GOLD-12 Support external cluster registry in voyager aggregator#149
nickhiggs wants to merge 2 commits into
masterfrom
M2GOLD-12-support-external-cluster-registry

Conversation

@nickhiggs

Copy link
Copy Markdown
Contributor

Threw together support for an external cluster registry stored in S3 or similar. Also added in some local config for the aggregator so it can be run outside a cluster for local dev.

@nickhiggs
nickhiggs requested review from amckague and ash2k February 11, 2019 19:26
@nickhiggs
nickhiggs force-pushed the M2GOLD-12-support-external-cluster-registry branch from 239e1c2 to c401960 Compare February 11, 2019 21:22
Comment thread Makefile
--config "$(CURDIR)/build/local/aggregator/config.yaml" \
--client-config-from=file \
--client-config-file-name="$$HOME/.kube/config" \
--kubeconfig="$$HOME/.kube/config" \

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Two config parameters?
  • Use KUBECONFIG like above

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From memory this was because different apiserver config components require different config flags when not running in-cluster

Comment thread Makefile
--kubeconfig="$$HOME/.kube/config" \
--client-config-context=$(VALIDATED_KUBE_CONTEXT) \
--secure-port=6443 \
--local=true \

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we move as many flags as possible into the config file?

}
if initializers, err := opts.ExtraAdmissionInitializers(config); err != nil {
return err
} else if err := opts.Admission.ApplyTo(&config.Config, config.SharedInformerFactory, config.ClientConfig, scheme, initializers...); err != nil {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove else =)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Allows reuse of the initializers which is only valid in this context


type ExternalClusterRegistry struct {
namespace string
rest *clusters.ClusterregistryV1alpha1Client

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should be an interface for it

clusters := map[string]interface{}{}

for _, c := range clusterList.Items {
if label, ok := c.Labels["customer"]; ok && label == "paas" {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't be hardcoded. Use k8s.io/apimachinery/pkg/labels package to abstract the details away. Put k8s.io/apimachinery/pkg/labels.Selector as a field and use it here via .Matches(). Configure the labels for it from config file.

}

func (e *ExternalClusterRegistry) GetClusters() ([]*cr_v1a1.Cluster, error) {
if time.Since(e.lastRun) > e.resyncPeriod {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • ExternalClusterRegistry is supposed to be thread-safe, right? Currently it is not because e.lastRun is read and written without any synchronization means.
  • Should likely avoid making multiple concurrent calls to the registry because why if you can do a single call and then serve data to multiple callers.
  • Since you are maintaining a cache here, why not make it asynchronous and decouple reads from cache refreshes? Have a goroutine that is periodically refreshing the cache and always serve data from it? Can even use watch if it is supported to refresh data in the cache. How sensitive are we to stale information in that cache?


clusters := e.cache.List()

typedClusters := make([]*cr_v1a1.Cluster, 0)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

preallocate

}

func (c *ClusterInformer) GetClusters() ([]*cr_v1a1.Cluster, error) {
clusters, err := c.informer.GetIndexer().ByIndex(ByClusterLabelIndexName, "paas")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

paas should not be hardcoded, move to config file

informer cache.SharedIndexInformer
}

func NewClusterInformer(config *ctrl.Config, cctx *ctrl.Context) (*ClusterInformer, error) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally this package should not depend on ctrl. All the plumbing logic should be in the controller constructor, like in all other controllers.


rest, err := clusters.NewForConfig(cfg)
if err != nil {
return nil, err

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Errors coming from external things need to be wrapped with errors.WithStack in many places (so when things go wrong we get a stack trace thanks golang)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants