-
Notifications
You must be signed in to change notification settings - Fork 107
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reconcile OperatorSource type #4
Conversation
// Type of operator source | ||
Type string `json:"type"` | ||
|
||
// Source points to the URL from where operator manifests can be fetched |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Endpoint points to
...
pkg/operatorsource/reconciler.go
Outdated
|
||
// Given a name of an instance of OperatorSource type, this function returns the name of the associated CatalogSourceConfig type object | ||
func getCatalogSourceConfigName(operatorSourceName string) string { | ||
return fmt.Sprintf("os-%s", operatorSourceName) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please change the os
prefix to something else given that is such an overloaded (Operating System, OpenShift etc) abbreviation. Plus I think it is an internal Go package name. I suggest opsrc
or some such thing.
Nit: you could go a step further and make the prefix a constant like we have for CatalogSourceConfig
.
pkg/operatorsource/reconciler.go
Outdated
return fmt.Sprintf("os-%s", operatorSourceName) | ||
} | ||
|
||
func (r *reconciler) IsAlreadyReconciled(os *v1alpha1.OperatorSource) (bool, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment as above for the os
variable name. I had to do a double take to realize you mean OperatorSource
:-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i like opsrc
:)
) | ||
|
||
func TestReconcile(t *testing.T) { | ||
os.Setenv("KUBERNETES_CONFIG", getKubeConfigFilePath()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same request as above
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
taken care of
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if the config doesn't exist? Won't it be better to catch that and make the test fail gracefully ?
b40a36a
to
53d849d
Compare
@aravindhp let me know if you have more comments |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Everything looks good except for the two unresolved comments.
) | ||
|
||
func TestReconcile(t *testing.T) { | ||
os.Setenv("KUBERNETES_CONFIG", getKubeConfigFilePath()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if the config doesn't exist? Won't it be better to catch that and make the test fail gracefully ?
LGTM to me except for #4 (comment) |
specified app registry server and making it available to the cluster
@@ -31,10 +31,12 @@ func main() { | |||
if err != nil { | |||
logrus.Fatalf("failed to get watch namespace: %v", err) | |||
} | |||
resyncPeriod := time.Duration(5) * time.Second | |||
logrus.Infof("Watching %s, %s, %s", resource, catalogSourceConfigKind, namespace) | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove blank lines.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
resyncPeriod
is shared by the two types here, hence it gets its own spacing.
@@ -0,0 +1,48 @@ | |||
package appregistry |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This whole file could be named as factory.go
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, good point. I thought about it. I also like the idea of a {package name}.go
file which has the entry level function for the given package. NewFactory
is the entry level function one must call to use the appregistry
package.
mediaType string = "helm" | ||
) | ||
|
||
// This interface (internal to this package) encapsulates nitty gritty details of go-appr client bindings |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment could have been a bit more clear on why 3 methods.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's all we need for this iteration. Do you want more clarity on why this interface exists? I don't think we need to explain why an interface has N number of methods.
} | ||
|
||
func (a *apprApiAdapterImpl) ListPackages() (appr_models.Packages, error) { | ||
params := appr_package.NewListPackagesParams() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't we allow listing packages within a namespace? I think we should allow some filtering here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I already have a new PR in review that allows to filter by namespace.
func TestRetrieveAll(t *testing.T) { | ||
factory := appregistry.NewClientFactory() | ||
|
||
client, err := factory.New("appregistry", "http://localhost:5000/cnr") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure, if the assumption is we have some service running on 5000? Or did you mock it somewhere?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test is hanging around here for debugging purposes. It will be replaced by a unit test.
@@ -0,0 +1,22 @@ | |||
package appregistry_test |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why a new package for testing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am treating this test as a black box test, hence a new package for test(s) and explicit import of package being tested.
return nil, err | ||
} | ||
|
||
list := make([]*OperatorMetadata, len(packages)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
operatorMetaDataList probably would have made more sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have to implement a operatorMetaDataList
. This is not a k8s type.
for i, pkg := range packages { | ||
manifest, err := c.RetrieveOne(pkg.Name, pkg.Default) | ||
if err != nil { | ||
return nil, err |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you want to return error, if retrieving one package is erroring? It could that one package is misbehaving, probably aggregated errorlist would make more sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a rudimentary version geared toward the proof of concept. I am working on prod ready reconciliation process now.
"io" | ||
) | ||
|
||
type blobDecoder interface { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you could have avoided interface altogether here and just used the struct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On the contrary, I can easily mock this interface when I am testing the unit that depends on this interface, Look at TestRetrieveOne_PackageExists_SuccessExpected
. Not shy to use interfaces :)
// Source: ./pkg/appregistry/adapter.go | ||
|
||
// Package appregistry is a generated GoMock package. | ||
package appregistry |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this here? Either we shouldn't checkin the generated code or if we absolutely need it we should create a script to generate it. I thought appregistry is not generated
} | ||
} | ||
|
||
type hashmapDatastore struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please change the name to something appropriate like DataStore
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, do you have any suggestions? MemoryDatastore
, TransientDatastore
or DummyDatastore
maybe? :)
} | ||
|
||
type hashmapDatastore struct { | ||
list map[string]*appregistry.OperatorMetadata |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change list to something appropriate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm, I can rename it to packages
. That is not so generic as list
} | ||
|
||
type Handler struct { | ||
// Fill me | ||
operatorSourceHanlder operatorsource.Handler |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good catch :)
Reconcile OperatorSource type by doing the following in order: