-
Notifications
You must be signed in to change notification settings - Fork 764
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
Gh 271 GitHub secrets #362
Conversation
Required: true, | ||
Sensitive: true, | ||
}, | ||
"key_id": { |
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.
Perhaps it's better to not have these arguments and instead just fetch and use the public key on create?
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.
It's a good shout. I initially provided these to allow users to determine the key / key id without the need for github_actions_secrets_public_key
but I think just not including them as you suggest is better.
Delete: resourceGithubActionsSecretDelete, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"owner": { |
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 the owner
argument required? Given you use checkOrganization
func, that checks that organization is configured in provider settings, you could get the value from provider config via meta
. As an example, take a look at repository webhook code.
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 was unaware that I could pull the organisation from the meta
to be honest!
Thinking about this, would there be any case that you would want to manage a secret that wasn't part of the organisation in the provider? I think it might be possible in the current implementation but should not be encouraged - forcing users to have an individual provider per organisation seems more appropriate?
If you 👍 my assertions above I am happy to remove the owner
argument
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, same ideology is used when managing other repository resources, webhooks is one example.
return err | ||
} | ||
|
||
d.SetId(fmt.Sprintf("%s/%s:%s", owner, repo, secretName)) |
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.
If we assume that owner
comes from provider configuration, then you can't have more than a single owner value and the owner part in Id becomes redundant. Have you considered using two part id consisting of repo name and secret name, and combining them using buildTwoPartID
utility func, you can find example 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 agree. I saw that function but wanted to use all 3 values. If we remove owner
as per above I will implement this suggestion
d.SetId("") | ||
return 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.
How come there are no d.Set()
method calls? I think the secrets information could be stored in state. The UpdatedAt
value from github.Secret
could be used to determine if the value has changed in GitHub, for example, if UpdatedAt
stored in state differs from value you got in GetSecret
response, it means someone has updated the value outside of Terraform, and we probably want to sync it up (reapply value defined in Terraform).
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 wasn't aware that the d.Set()
functions were required to pass things to state. My understanding was that the existing d
values passed in would get persisted.
I fully agree with the use of UpdatedAt
- would you recommend saving the full state of the github.Secret
?
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 I would store the repo
and name
as par of Id, then store plaintext_value
as it is and lastly store updated_at
as computed getting the value from create/update operation.
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.
Sounds like a solid plan - I will also include created_at
since we have it available and might as well make it available
client := meta.(*Organization).client | ||
ctx := context.WithValue(context.Background(), ctxId, d.Id()) | ||
|
||
orgName := d.Get("owner").(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.
Consider getting orgName
from provider config via meta
here.
ctx := context.WithValue(context.Background(), ctxId, d.Id()) | ||
|
||
orgName := d.Get("owner").(string) | ||
repoName := d.Get("repository").(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.
Perhaps it's better to obtain repoName
and secretName
by extracting it from d.GetId()
using parseTwoPartID
utility func?
repoName, secretName, err := parseTwoPartID(d.Id(), "repository", "secret_name")
if err != nil {
return err
}
Can't really figure out from the code, are we always updating the secret on GitHub, even if it has not changed locally? |
I didn't think we are updating every time, though reading this review, I was unaware that the secret data wasn't being saved to state so maybe we are always updating. As discussed further up in the review, I think we should add to the state and this will resolve your concern |
@benj-fletch sweet, if you need any help let me know. I'm happy to review again after you have meade the changes discussed above. |
Thanks for the comments @martinssipenko! I have updated the PR to hopefully address all of them. I'll leave it in draft still until the update to go github v29 has occured as I imagine it will create conflicts to resolve |
Type: schema.TypeString, | ||
Required: true, | ||
}, | ||
"owner": { |
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 this too should come from provider settings via meta
.
"log" | ||
) | ||
|
||
func dataSourceGithubActionsSecrets() *schema.Resource { |
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'll be frank, I don't see any benefit of having this data source as the data you can obtain from secret is practically unusable.
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 initially added this as I thought it might be useful in future resources / data sources for GitHub actions. Reviewing the available API endpoints I think I agree that this data is useless in the long run. I will remove this data source.
}, | ||
"secret_name": { | ||
Type: schema.TypeString, | ||
Required: 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.
Shall we add ForceNew: true
here?
owner := meta.(*Organization).name | ||
ctx := context.Background() | ||
|
||
repo := d.Get("repository").(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.
The repo and secret name should be extracted from Id:
repoName, secretName, err := parseTwoPartID(d.Id(), "repository", "secret_name")
if err != nil {
return 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.
Yes, I should have caught this in the previous PR comment resolution! Thanks.
return err | ||
} | ||
|
||
d.SetId(buildTwoPartID(&repo, &secretName)) |
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 Id should not be set here, it should already exist by this point either coming from state or set by resourceGithubActionsSecretCreateOrUpdate
func.
} | ||
|
||
d.SetId(buildTwoPartID(&repo, &secretName)) | ||
d.Set("plaintext_value", d.Get("plaintext_value")) |
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 100% sure but I think is not required, as it already should exist in state.
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 also not sure on this point. I left it there such that it was obvious (and definite) it would be set. I don't see any issue with leaving this line in?
secretName := d.Get("secret_name").(string) | ||
|
||
secret, _, err := client.Actions.GetSecret(ctx, owner, repo, secretName) | ||
if err != nil || secret.Name != secretName { |
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 || secret.Name != secretName
part needed 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 don't think it is on review!
if err != nil { | ||
return 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.
You should set the Id here using d.SetId(buildTwoPartID(&repo, &secretName))
. Afterwards this func calls resourceGithubActionsSecretRead
func, which instead should extract repo and secret name from the d.GetId()
via parseTwoPartID
func, I've given the example in this comment.
Can you rebase from master? #342 was merged, but unfortunatley it includes v29.0.3, but we need v29.0.3 for this to work. The question is should we make update to latest in this or seperate PR? |
Hi @martinssipenko, thanks a lot for the re-review. I have rebased onto master and hopefully have addressed all your concerns, are you able to have another look? N.B. This PR now relies on #369 for the go-github v29.0.3 upgrade and will need rebasing again to master following its merge. |
@benj-fletch #369 has been merged into master now. This can be rebased and hopefully merged! Thank you for all the work on this! |
GH-271 - Added actions_public_key data resource GH-271 - Added actions_secrets data source Further testing is required on this data source GH-271 - Added actions_secret resource GH-271 - Adding actions_secret resource documentation updates Fix formatting Updates following PR comments Updates following PR comments GH-271 - Resolving more PR comments Updating documentation GH-271 - removing references to old TF SDK
Thanks for the prod @btkostner - I have rebased, fixed a couple of conflicts and squashed the commits. This should be ready for review now! 💯 |
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 looking great with no concerns from me on the first pass.
My next step is to validate acceptance tests are 👌 and forecast this merging by end of week.
## Import | ||
|
||
Repositories can be imported using the `name`, e.g. | ||
|
||
``` | ||
$ terraform import github_repository.terraform terraform | ||
``` |
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 needs to be updated or removed
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, classic copy paste error! Will update
@@ -13,6 +13,9 @@ | |||
<li> | |||
<a href="#">Data Sources</a> | |||
<ul class="nav nav-visible"> | |||
<li> | |||
<a href="/docs/providers/github/d/actions_public_key.html">github_actions_public_key</a> |
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 always miss this file, thanks.
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.
Acceptance tests are passing for me locally. 🚀
…github-secrets Gh 271 GitHub secrets
This PR covers functionality described in GH-271
The following functionality has been provided by this new code:
Data source
github_actions_public_key
- retrieving the public key of a repositoryData source
github_actions_secrets
- retrieval of all secrets in a repositoryResource
github_actions_secret
- management of Actions SecretsSee the documentation for details around config for each new item.
Note that this requires #342 to be merged prior to this and so it has been raised as a draft PR