-
Notifications
You must be signed in to change notification settings - Fork 5
Ingest the remaining entities and relationships #5
Ingest the remaining entities and relationships #5
Conversation
Pinging @aiwilliams @ndowmon @austinkelleher |
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.
@neurovelho Thanks for all the work here! All the new entities and relationships look really good.
I peppered some requests throughout for you to review. In particular, I'd like you to take another look at the artifactory_permissions
entities and relationships. Let me know if any of my comments don't make sense and we can discuss in more detail.
src/steps/access.ts
Outdated
id: 'fetch-access-tokens', | ||
name: 'Fetch Access Tokens', | ||
entities: [entities.ACCESS_TOKEN], | ||
relationships: [relationships.ACCOUNT_HAS_ACCESS_TOKEN], |
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.
Looks like the particular access token based on your test data could be related to a user via the subject
field:
{
"expiry": 1601555179,
"issued_at": 1599135979,
"issuer": "jfrt@01eg8hb1g2dqb01cdtms0e0bv1",
"refreshable": false,
"subject": "jfrt@01eg8hb1g2dqb01cdtms0e0bv1/users/[email protected]",
"token_id": "ad667cc7-54a5-42b1-bed5-0c92c0fe0fa8",
}
I think we should probably add artifactory_user--ASSIGNED-->artifactory_access_token
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.
Looks like the admin can only create what's called admin access token, however it looks like it's actually possible to create regular access tokens that target a specific user using the rest api, so we'll change this.
clientPipelineAccessToken: { | ||
type: 'string', | ||
mask: true, | ||
}, |
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.
Can you update the development docs so devs also know they need to generate this token?
src/steps/repositories.ts
Outdated
function mapPackageTypeToStepEntityMetadata(type: string): StepEntityMetadata { | ||
if (type.match(/docker|vagrant/i)) { | ||
return entities.ARTIFACT_IMAGE; | ||
} | ||
|
||
return entities.ARTIFACT_CODEMODULE; | ||
} | ||
|
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 noticed that this matcher isn't really differentiating image
s from codemodule
s. Example from snapshot:
// this is a json but matched the repository name `/docker/i`
Object {
"_type": "artifactory_artifact_image",
"name": "https://codeworkr.jfrog.io/artifactory/docker-repo/hello-world/1.1.1/manifest.json",
... // other properties
},
// this appears to be an image
Object {
"_type": "artifactory_artifact_image",
"name": "https://codeworkr.jfrog.io/artifactory/docker-repo/hello-world/1.1.1/sha256__0e03bdcc26d7a9a57ef3b6f1bf1a210cff6239bff7c8cac72435984032851689",
... // other properties
},
Not sure if it makes sense to reconsider your regular expression matcher to avoid these types of mis-matchings. I'm personally not 100% sure it is worth differentiating between images and "code modules", considering that code module is basically a catch all for other files, including .pom
, .xml
, .json
, .jpeg
, .gz
and others which can be found in the snapshot. If others have a strong opinion about differentiating artifactory_artifact_image
vs artifactory_artifact_codemodule
, please speak up. I'd particularly like to hear @erichs' opinions here considering his comment #3 (comment)
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 I'm not too excited about this matcher either, I think it would be much better if we could just roll with one type.
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.
Spoke with @erichs about this. It really stinks that the API appears to only reliably return folder
and uri
properties, no additiona metadata:
{
"folder": false,
"uri": "https://codeworkr.jfrog.io/artifactory/docker-repo/hello-world/1.1.1/sha256__bf756fb1ae65adf866bd8c456593cd24beb6a0a061dedf42b26a993176745f6b",
}
Since there are no other properties we can rely on, it doesn't seem like a great idea for us to add any custom matcher in our code (following the philosophy that we at J1 only ingest the state of a target system, and don't build additional logic).
As long as you are pulling the projectType
property on artifactory_repository
entities, we can create J1QL like the following, which is good enough for now:
// look for maven builds
find
artifactory_repository that has
artifactory_artifact
where
artifactory_repository.packageType = 'Maven'
await fetchRepositories(context); | ||
await fetchPipelineSources(context); | ||
await fetchArtifacts(context); | ||
await fetchBuilds(context); |
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.
Looks like you're not testing fetchPermissions
here. Is that on purpose or just overlooked?
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.
Looks like we missed it, good catch.
_class: RelationshipClass.ALLOWS, | ||
sourceType: entities.PERMISSION._type, | ||
targetType: entities.REPOSITORY._type, | ||
}, |
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.
Is PERMISSION_DENIES_REPOSITORY
a valid relationship type? Just noticed that there are both PREMISSION_ALLOWS_BUILD
and PERMISSION_DENIES_BUILD
.
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.
Actually, read comments in /permissions.ts
. Not sure there should be any DENIES
relationships.
src/steps/permissions.ts
Outdated
}, | ||
}); | ||
|
||
await jobState.addEntity(permissionEntity); |
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.
Looks like this code is adding two artifactory_permission
entities for every permission. There should be just one artifactory_permission
entity created. That single entity should have relationships to both users and groups.
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 were going by this comment here: #3 (comment), but seeing as the response contains both users and groups, it would make more sense if we had both users and groups in the entity.
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 to clarify - you mean both users and groups in related to the entity, correct?
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, that's right.
); | ||
} | ||
|
||
function constructPermissionsMap( |
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.
Per artifactory docs, there can also be release bundle permissions, destination permissions, and pipeline permissions, PLUS "global permissions". Can you pull those additional permission targets in this function? I realize that some of those can't be used to target existing entities, but can you add code comments to implement others when they are implemented in the future?
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.
The api documentation seems to indicate that only repository, build and releaseBundle are available, though it could be that it's outdated 🤔
We'll definitely see if it's possible to add the rest.
src/steps/permissions.ts
Outdated
return targetPermissionsMap; | ||
} | ||
|
||
async function createPermissionBuildAllowsRelationships( |
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.
Jfrog docs discussing include and exclude patterns seem to indicate that both the statements are used to pattern match permission targets that are allowed by a given permission. I don't think the exclude pattern is actually a DENIES
statement in reality.
I would instead suggest creating only ALLOWS
statements for permissions targets that do match the include-pattern
and do not match the exclude-pattern
.
Also, I notice that artifactory exposes a pattern matching API - it would be better to use a matcher provided by the vendor than a nodejs utility. See https://www.jfrog.com/confluence/display/JFROG/Artifactory+REST+API
Usage: GET /api/search/pattern?pattern=repo-key:this/is/a/*pattern*.war
}; | ||
groups?: { | ||
[name: string]: 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 haven't used the API, but it seems to me that permission.repo
also has the include-patterns
and exclude-patterns
properties.
}; | ||
'include-patterns': string[]; | ||
'exclude-patterns': 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.
You should enumerate all of the permission target types, including destinations
, pipeline-sources
, release-bundles
, and possibly global
if it exists.
Alrighty, we've implemented the changes you requested @ndowmon. There's however a few complications though:
|
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.
Thanks for making the requested changes! This integration definitely looks ready for deployment to me.
I commented a few small requests but we can easily open new github issues for those and fix in the future.
src/steps/permissions.ts
Outdated
}, | ||
(buildEntity) => `${permissionEntity._key}|allows|${buildEntity._key}`, |
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 a big deal since it's functionally correct, but here it should be permissionEntity
.
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.
Did you mean repositoryEntity
? In any case, I renamed it since it was bothering me too much 🙂.
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! Thanks.
@@ -237,9 +272,11 @@ export const permissionsSteps: IntegrationStep<IntegrationConfig>[] = [ | |||
relationships.PERMISSION_ASSIGNED_GROUP, | |||
relationships.PERMISSION_ALLOWS_REPOSITORY, | |||
relationships.PERMISSION_ALLOWS_BUILD, | |||
relationships.PERMISSION_ALLOWS_REPOSITORY_GROUP, |
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.
Cool, thanks for adding this!
@@ -51,6 +52,7 @@ describe('JFrog Arrifactory', () => { | |||
await fetchPipelineSources(context); | |||
await fetchArtifacts(context); | |||
await fetchBuilds(context); | |||
await fetchPermissions(context); |
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.
Thanks for adding. Not necessary now, but let's add a GH issue to add an expect
statement for permissions 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.
Thanks @neurovelho. This is a great integration!
This PR includes the remaining of the high value entities and relationships as discussed in the issue thread.
Kindly let us know if something needs to be changed.