-
Notifications
You must be signed in to change notification settings - Fork 615
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
Filter out Internal APIs in Installed Operators #3877
Filter out Internal APIs in Installed Operators #3877
Conversation
be4f834
to
71b98df
Compare
Can you provide an example of CRD/CSV annotations that is used by this filter? |
Did you also filter it from the Operator Install page (one where you choose channels and namespace)? |
const INTERNAL = 'operators.operatorframework.io/internal-objects'; | ||
let internals: string = _.get(annotations, INTERNAL); | ||
if (internals) { | ||
internals = internals.replace(/'/g, '"'); |
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.
are we doing it because annotations are written this way?
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.
yes. you're right. and JSON doesn't work with '
.
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.
Cant this be changed from BE itself or its a convention to do so?
^^ @aruniiird
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.
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.
@cloudbehl I have put it in the description.
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.
Cant this be changed from BE itself or its a convention to do so?
^^ @aruniiird
@afreen23 , I have made (and submitted) the changes in the backend PR, red-hat-storage/ocs-operator#385, and it worked (without the special handling of internals
string).
But isn't it a good idea (or programming practice) to have a check, thus you don't have to be dependent on BE to provide a correct string? Regardless may have to handle parsing errors.
@@ -795,24 +814,27 @@ export const ClusterServiceVersionsDetailsPage: React.FC<ClusterServiceVersionsD | |||
props, | |||
) => { | |||
const instancePagesFor = (obj: ClusterServiceVersionKind) => { | |||
const internalObjects = getInternalNames(_.get(obj, 'metadata.annotations')); |
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.
const internalObjects = getInternalNames(_.get(obj, 'metadata.annotations')); | |
const internalObjects = getInternalObjects(_.get(obj, 'metadata.annotations')); |
[key: string]: string; | ||
}; | ||
|
||
const getInternalNames = (annotations: Annotations) => { |
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.
const getInternalNames = (annotations: Annotations) => { | |
const getInternalObjects = (annotations: Annotations) => { |
71b98df
to
f9a2a7d
Compare
const INTERNAL = 'operators.operatorframework.io/internal-objects'; | ||
let internals: string = _.get(annotations, INTERNAL); | ||
if (internals) { | ||
internals = internals.replace(/'/g, '"'); |
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.
Wait, why is this needed? It should parse as JSON with no changes.
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.
Ohh sorry, I missed you comment. I have the same concern.
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.
ack. I had once gotten a malformed string. Hence put it. But I will remove it.
|
||
export const getInternalObjects = (annotations: Annotation): string[] => { | ||
const INTERNAL = 'operators.operatorframework.io/internal-objects'; | ||
let internals: string = _.get(annotations, INTERNAL); |
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.
let internals: string = _.get(annotations, INTERNAL); | |
let internals: string = _.get(annotations, ['operators.operatorframework.io/internal-objects']); |
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.
ack
}; | ||
|
||
export const isInternalObject = (internalObjects: string[], objectName: string): boolean => | ||
internalObjects.some((obj) => obj.includes(objectName)); |
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 a substring match?
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.
ack. Will make it a strict match.
csv: ClusterServiceVersionKind, | ||
): string[] => { | ||
const { owned } = csv.spec.customresourcedefinitions; | ||
return owned.filter((obj) => isInternalObject(internalObjects, obj.name)).map((obj) => obj.kind); |
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.
kind
is not unique since it doesn't contain the API group, so we can't use this helper to hide items by kind
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.
ack. will use referenceForProvidedAPI.
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.
Just a couple of minor suggestions on the iterative methods we are using to filter and map items.
.filter((item) => !isInternalObject(internalObjects, item.name)) | ||
.reduce((acc, crd) => ({ ...acc, [crd.name]: crd.displayName }), {}), |
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.
Reduce can be used to filter. No need to filter and then reduce. We can expand the logic in the reduce callback to exclude items that should be filtered.
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.
ack
) : ( | ||
props.crdDescs | ||
.filter((crd) => !isInternalObject(internals, crd.name)) | ||
.map((desc) => ( |
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.
Suggest using reduce instead of filter -> map.
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.
ack
f9a2a7d
to
efac119
Compare
efac119
to
4843614
Compare
(acc, crd) => | ||
!isInternalObject(internalObjects, crd.name) | ||
? { ...acc, [crd.name]: crd.displayName } | ||
: { ...acc }, |
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.
No reason to make a copy here
: { ...acc }, | |
: acc, |
@@ -246,3 +246,7 @@ export type OperatorGroupKind = { | |||
lastUpdated: string; | |||
}; | |||
} & K8sResourceKind; | |||
|
|||
export type Annotation = { |
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'd use ObjectMetadata['annotations']
or export the type here:
https://github.com/openshift/console/blob/master/frontend/public/module/k8s/index.ts#L39
(acc, obj) => | ||
isInternalObject(internalObjects, obj.name) | ||
? [referenceForProvidedAPI(obj), ...acc] | ||
: [...acc], |
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.
: [...acc], | |
: acc, |
try { | ||
return JSON.parse(internals); | ||
} catch { | ||
return []; |
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.
We should add a console.error
for debugging
|
||
export const getInternalObjects = (annotations: Annotation): string[] => { | ||
const internals: string = _.get(annotations, 'operators.operatorframework.io/internal-objects'); | ||
if (internals) { |
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.
Prefer early returns, which are easier to reason aboue.
if (!internals) {
return [];
}
// parse json....
internalObjects.some((obj) => obj === objectName); | ||
|
||
export const internalAPIReferences = ( | ||
internalObjects: string[], |
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'd just parse the internal objects here instead of taking it in as a param. That makes the API simpler.
export const isInternalObject = (internalObjects: string[], objectName: string): boolean => | ||
internalObjects.some((obj) => obj === objectName); | ||
|
||
export const internalAPIReferences = ( |
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.
export const internalAPIReferences = ( | |
export const getInternalAPIReferences = ( |
358e1a0
to
50c8811
Compare
internalObjects.some((obj) => obj === objectName); | ||
|
||
export const getInternalAPIReferences = ( | ||
annotations: ObjectMetadata['annotations'], |
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.
No need to pass in the annotations. They can be ready from csv
import { ClusterServiceVersionKind } from './types'; | ||
import { referenceForProvidedAPI } from './components'; | ||
|
||
export const getInternalObjects = (annotations: ObjectMetadata['annotations']): string[] => { |
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 nit, but I think it's a better abstraction if this takes in the CSV obj instead of the annotations.
50c8811
to
d131ec8
Compare
This doesn't appear to be simply a timeout. There's an actual JS runtime error in the screenshot: |
|
900e9f7
to
a52c456
Compare
/retest |
/hold cancel |
Thanks for tracking the test failure down 👍 |
/retest |
frontend/packages/operator-lifecycle-manager/src/components/clusterserviceversion.tsx
Show resolved
Hide resolved
internalObjects.some((obj) => obj === objectName); | ||
|
||
export const getInternalAPIReferences = (csv: ClusterServiceVersionKind): string[] => { | ||
const owned: CRDDescription[] = _.flatten( |
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.
Isn't spec.customresourcedefinitions.owned
an array? I'd expect it to be simply
const owned: CRDDescription[] = csv?.spec?.customresourcedefinitions?.owned || [];
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.
Yes, you're right. I was doing this because I was taking all CRDs both owned and required. #shithappens ;)
a52c456
to
f13372e
Compare
f13372e
to
4ee8510
Compare
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.
/approve
/lgtm
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: bipuladh, cloudbehl, jeff-phillips-18, spadgett, TheRealJon, vojtechszocs The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
/retest |
/retest Please review the full test history for this PR and help us cut down flakes. |
5 similar comments
/retest Please review the full test history for this PR and help us cut down flakes. |
/retest Please review the full test history for this PR and help us cut down flakes. |
/retest Please review the full test history for this PR and help us cut down flakes. |
/retest Please review the full test history for this PR and help us cut down flakes. |
/retest Please review the full test history for this PR and help us cut down flakes. |
/retest |
/retest Please review the full test history for this PR and help us cut down flakes. |
All Instances
page.Example annotation:
operators.operatorframework.io/internal-objects: '["cephblockpools.ceph.rook.io", "cephobjectstores.ceph.rook.io"]'