{"action":"created","comment":{"url":"https://api.github.com/repos/openshift/origin/pulls/comments/70996766","id":70996766,"diff_hunk":"@@ -0,0 +1,114 @@\n+package secrets\n+\n+import (\n+\t\"fmt\"\n+\t\"io\"\n+\n+\tkapi \"k8s.io/kubernetes/pkg/api\"\n+\tkcmdutil \"k8s.io/kubernetes/pkg/kubectl/cmd/util\"\n+\n+\t\"github.com/spf13/cobra\"\n+)\n+\n+const (\n+\tUnlinkSecretRecommendedName = \"unlink\"\n+\n+\t// TODO: move to examples\n+\tunlinkSecretLong = `\n+Unlink (detach) secrets from a ServiceAccount\n+If a secret is no longer valid for a pod, build or image pull, you may unlink it from a service account.`\n+\n+\tunlinkSecretExample = ` # Unlink a secret currently associated with a service account like this:\n+%[1]s serviceaccount/sa-name secret/secret-name secret/another-secret-name ...`\n+)\n+\n+type UnlinkSecretOptions struct {\n+\tSecretOptions\n+}\n+\n+// NewCmdUnlinkSecret creates a command object for detaching one or more secret references from a service account\n+func NewCmdUnlinkSecret(name, fullName string, f *kcmdutil.Factory, out io.Writer) *cobra.Command {\n+\to := &UnlinkSecretOptions{SecretOptions{Out: out}}\n+\n+\tcmd := &cobra.Command{\n+\t\tUse:     fmt.Sprintf(\"%s serviceaccount/sa-name secret/secret-name [secret/another-secret-name] ...\", name),\n+\t\tShort:   \"Detach secrets from a ServiceAccount\",\n+\t\tLong:    unlinkSecretLong,\n+\t\tExample: fmt.Sprintf(unlinkSecretExample, fullName),\n+\t\tRun: func(c *cobra.Command, args []string) {\n+\t\t\tif err := o.Complete(f, args, nil); err != nil {\n+\t\t\t\tkcmdutil.CheckErr(kcmdutil.UsageError(c, err.Error()))\n+\t\t\t}\n+\t\t\tif err := o.Validate(); err != nil {\n+\t\t\t\tkcmdutil.CheckErr(kcmdutil.UsageError(c, err.Error()))\n+\t\t\t}\n+\n+\t\t\tif err := o.UnlinkSecrets(); err != nil {\n+\t\t\t\tkcmdutil.CheckErr(err)\n+\t\t\t}\n+\n+\t\t},\n+\t}\n+\n+\treturn cmd\n+}\n+\n+func (o UnlinkSecretOptions) UnlinkSecrets() error {\n+\tserviceaccount, err := o.GetServiceAccount()\n+\tif err != nil {\n+\t\treturn err\n+\t}\n+\n+\tif err = o.unlinkSecretsFromServiceAccount(serviceaccount); err != nil {\n+\t\treturn err\n+\t}\n+\n+\treturn nil\n+}\n+\n+// unlinkSecretsFromServiceAccount detatches pull and mount secrets from the service account.\n+func (o UnlinkSecretOptions) unlinkSecretsFromServiceAccount(serviceaccount *kapi.ServiceAccount) error {\n+\t// All of the requested secrets must be present in either the Mount or Pull secrets\n+\t// If any of them are not present, we'll return an error and push no changes.\n+\trmSecrets, err := o.GetSecrets()\n+\tif err != nil {\n+\t\treturn err\n+\t}\n+\trmSecretNames := o.GetSecretNames(rmSecrets)\n+\n+\tvar found bool\n+\n+\tfor _, secretname := range rmSecretNames.List() {\n+\t\tfound = false\n+\n+\t\t// Check the mount secrets\n+\t\tfor i := len(serviceaccount.Secrets) - 1; i >= 0; i-- {\n+\t\t\tif secretname == serviceaccount.Secrets[i].Name {\n+\t\t\t\tfound = true\n+\n+\t\t\t\t// Unlink this entry from Secrets\n+\t\t\t\tserviceaccount.Secrets = append(serviceaccount.Secrets[:i], serviceaccount.Secrets[i+1:]...)\n+\t\t\t}\n+\t\t}\n+\n+\t\t// Check the image pull secrets\n+\t\tfor i := len(serviceaccount.ImagePullSecrets) - 1; i >= 0; i-- {\n+\t\t\tif secretname == serviceaccount.ImagePullSecrets[i].Name {\n+\t\t\t\tfound = true\n+\n+\t\t\t\t// Unlink this entry from ImagePullSecrets\n+\t\t\t\tserviceaccount.ImagePullSecrets = append(serviceaccount.ImagePullSecrets[:i], serviceaccount.ImagePullSecrets[i+1:]...)\n+\t\t\t}\n+\t\t}\n+\n+\t\tif !found {\n+\t\t\t// This secret didn't appear in either secret type\n+\t\t\treturn fmt.Errorf(\"%s is not associated with service account %s\",","path":"pkg/cmd/cli/secrets/unlink_secret_from_object.go","position":106,"original_position":106,"commit_id":"5388db317f2a4b67112b1a0dbc4d1859139241b9","original_commit_id":"5388db317f2a4b67112b1a0dbc4d1859139241b9","user":{"login":"sgallagher","id":739555,"avatar_url":"https://avatars.githubusercontent.com/u/739555?v=3","gravatar_id":"","url":"https://api.github.com/users/sgallagher","html_url":"https://github.com/sgallagher","followers_url":"https://api.github.com/users/sgallagher/followers","following_url":"https://api.github.com/users/sgallagher/following{/other_user}","gists_url":"https://api.github.com/users/sgallagher/gists{/gist_id}","starred_url":"https://api.github.com/users/sgallagher/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sgallagher/subscriptions","organizations_url":"https://api.github.com/users/sgallagher/orgs","repos_url":"https://api.github.com/users/sgallagher/repos","events_url":"https://api.github.com/users/sgallagher/events{/privacy}","received_events_url":"https://api.github.com/users/sgallagher/received_events","type":"User","site_admin":false},"body":"@smarterclayton I had originally discussed this with @pweil- in person. The reason I did it that way was to be protective of users making mistakes. If someone mistyped the name of a secret and received no error back from the CLI, then they're going to assume all is well. Meanwhile, the real secret is still exposed to the container.\r\n\r\nFor some linkages, I think the silent failure is fine, but when dealing with things like passwords, there's probably a really good reason why the admin is opting to unlink them and I think we probably don't want to quietly leave them linked.\r\n\r\nIf you agree, I'll work on the `--force` option.","created_at":"2016-07-15T15:58:06Z","updated_at":"2016-07-15T15:58:06Z","html_url":"https://github.com/openshift/origin/pull/9234#discussion_r70996766","pull_request_url":"https://api.github.com/repos/openshift/origin/pulls/9234","_links":{"self":{"href":"https://api.github.com/repos/openshift/origin/pulls/comments/70996766"},"html":{"href":"https://github.com/openshift/origin/pull/9234#discussion_r70996766"},"pull_request":{"href":"https://api.github.com/repos/openshift/origin/pulls/9234"}}},"pull_request":{"url":"https://api.github.com/repos/openshift/origin/pulls/9234","id":73119094,"html_url":"https://github.com/openshift/origin/pull/9234","diff_url":"https://github.com/openshift/origin/pull/9234.diff","patch_url":"https://github.com/openshift/origin/pull/9234.patch","issue_url":"https://api.github.com/repos/openshift/origin/issues/9234","number":9234,"state":"open","locked":false,"title":"Add `oc secrets unlink`","user":{"login":"sgallagher","id":739555,"avatar_url":"https://avatars.githubusercontent.com/u/739555?v=3","gravatar_id":"","url":"https://api.github.com/users/sgallagher","html_url":"https://github.com/sgallagher","followers_url":"https://api.github.com/users/sgallagher/followers","following_url":"https://api.github.com/users/sgallagher/following{/other_user}","gists_url":"https://api.github.com/users/sgallagher/gists{/gist_id}","starred_url":"https://api.github.com/users/sgallagher/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sgallagher/subscriptions","organizations_url":"https://api.github.com/users/sgallagher/orgs","repos_url":"https://api.github.com/users/sgallagher/repos","events_url":"https://api.github.com/users/sgallagher/events{/privacy}","received_events_url":"https://api.github.com/users/sgallagher/received_events","type":"User","site_admin":false},"body":"New command to remove the link between a service account and a\r\nSecret object.\r\n\r\nThis patch refactors add_secret_to_obj.go to provide several\r\ncommon routines that are also used by remove_secret_from_obj.go\r\n\r\nSigned-off-by: Stephen Gallagher <sgallagh@redhat.com>","created_at":"2016-06-08T20:58:12Z","updated_at":"2016-07-15T15:58:06Z","closed_at":null,"merged_at":null,"merge_commit_sha":"cc0214aba6169f61cd05fbcf775bfeec15f8d4a8","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/openshift/origin/pulls/9234/commits","review_comments_url":"https://api.github.com/repos/openshift/origin/pulls/9234/comments","review_comment_url":"https://api.github.com/repos/openshift/origin/pulls/comments{/number}","comments_url":"https://api.github.com/repos/openshift/origin/issues/9234/comments","statuses_url":"https://api.github.com/repos/openshift/origin/statuses/5388db317f2a4b67112b1a0dbc4d1859139241b9","head":{"label":"sgallagher:setecastronomy","ref":"setecastronomy","sha":"5388db317f2a4b67112b1a0dbc4d1859139241b9","user":{"login":"sgallagher","id":739555,"avatar_url":"https://avatars.githubusercontent.com/u/739555?v=3","gravatar_id":"","url":"https://api.github.com/users/sgallagher","html_url":"https://github.com/sgallagher","followers_url":"https://api.github.com/users/sgallagher/followers","following_url":"https://api.github.com/users/sgallagher/following{/other_user}","gists_url":"https://api.github.com/users/sgallagher/gists{/gist_id}","starred_url":"https://api.github.com/users/sgallagher/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sgallagher/subscriptions","organizations_url":"https://api.github.com/users/sgallagher/orgs","repos_url":"https://api.github.com/users/sgallagher/repos","events_url":"https://api.github.com/users/sgallagher/events{/privacy}","received_events_url":"https://api.github.com/users/sgallagher/received_events","type":"User","site_admin":false},"repo":{"id":50381938,"name":"origin","full_name":"sgallagher/origin","owner":{"login":"sgallagher","id":739555,"avatar_url":"https://avatars.githubusercontent.com/u/739555?v=3","gravatar_id":"","url":"https://api.github.com/users/sgallagher","html_url":"https://github.com/sgallagher","followers_url":"https://api.github.com/users/sgallagher/followers","following_url":"https://api.github.com/users/sgallagher/following{/other_user}","gists_url":"https://api.github.com/users/sgallagher/gists{/gist_id}","starred_url":"https://api.github.com/users/sgallagher/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sgallagher/subscriptions","organizations_url":"https://api.github.com/users/sgallagher/orgs","repos_url":"https://api.github.com/users/sgallagher/repos","events_url":"https://api.github.com/users/sgallagher/events{/privacy}","received_events_url":"https://api.github.com/users/sgallagher/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/sgallagher/origin","description":"OpenShift 3 - build, deploy, and manage your applications with Docker and Kubernetes","fork":true,"url":"https://api.github.com/repos/sgallagher/origin","forks_url":"https://api.github.com/repos/sgallagher/origin/forks","keys_url":"https://api.github.com/repos/sgallagher/origin/keys{/key_id}","collaborators_url":"https://api.github.com/repos/sgallagher/origin/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/sgallagher/origin/teams","hooks_url":"https://api.github.com/repos/sgallagher/origin/hooks","issue_events_url":"https://api.github.com/repos/sgallagher/origin/issues/events{/number}","events_url":"https://api.github.com/repos/sgallagher/origin/events","assignees_url":"https://api.github.com/repos/sgallagher/origin/assignees{/user}","branches_url":"https://api.github.com/repos/sgallagher/origin/branches{/branch}","tags_url":"https://api.github.com/repos/sgallagher/origin/tags","blobs_url":"https://api.github.com/repos/sgallagher/origin/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/sgallagher/origin/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/sgallagher/origin/git/refs{/sha}","trees_url":"https://api.github.com/repos/sgallagher/origin/git/trees{/sha}","statuses_url":"https://api.github.com/repos/sgallagher/origin/statuses/{sha}","languages_url":"https://api.github.com/repos/sgallagher/origin/languages","stargazers_url":"https://api.github.com/repos/sgallagher/origin/stargazers","contributors_url":"https://api.github.com/repos/sgallagher/origin/contributors","subscribers_url":"https://api.github.com/repos/sgallagher/origin/subscribers","subscription_url":"https://api.github.com/repos/sgallagher/origin/subscription","commits_url":"https://api.github.com/repos/sgallagher/origin/commits{/sha}","git_commits_url":"https://api.github.com/repos/sgallagher/origin/git/commits{/sha}","comments_url":"https://api.github.com/repos/sgallagher/origin/comments{/number}","issue_comment_url":"https://api.github.com/repos/sgallagher/origin/issues/comments{/number}","contents_url":"https://api.github.com/repos/sgallagher/origin/contents/{+path}","compare_url":"https://api.github.com/repos/sgallagher/origin/compare/{base}...{head}","merges_url":"https://api.github.com/repos/sgallagher/origin/merges","archive_url":"https://api.github.com/repos/sgallagher/origin/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/sgallagher/origin/downloads","issues_url":"https://api.github.com/repos/sgallagher/origin/issues{/number}","pulls_url":"https://api.github.com/repos/sgallagher/origin/pulls{/number}","milestones_url":"https://api.github.com/repos/sgallagher/origin/milestones{/number}","notifications_url":"https://api.github.com/repos/sgallagher/origin/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/sgallagher/origin/labels{/name}","releases_url":"https://api.github.com/repos/sgallagher/origin/releases{/id}","deployments_url":"https://api.github.com/repos/sgallagher/origin/deployments","created_at":"2016-01-25T21:23:57Z","updated_at":"2016-01-25T21:24:03Z","pushed_at":"2016-07-15T15:49:16Z","git_url":"git://github.com/sgallagher/origin.git","ssh_url":"git@github.com:sgallagher/origin.git","clone_url":"https://github.com/sgallagher/origin.git","svn_url":"https://github.com/sgallagher/origin","homepage":"http://www.openshift.org","size":297731,"stargazers_count":0,"watchers_count":0,"language":"Go","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"openshift:master","ref":"master","sha":"5d153b24493d6463f4102ecd6fc3fe58bedb1552","user":{"login":"openshift","id":792337,"avatar_url":"https://avatars.githubusercontent.com/u/792337?v=3","gravatar_id":"","url":"https://api.github.com/users/openshift","html_url":"https://github.com/openshift","followers_url":"https://api.github.com/users/openshift/followers","following_url":"https://api.github.com/users/openshift/following{/other_user}","gists_url":"https://api.github.com/users/openshift/gists{/gist_id}","starred_url":"https://api.github.com/users/openshift/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/openshift/subscriptions","organizations_url":"https://api.github.com/users/openshift/orgs","repos_url":"https://api.github.com/users/openshift/repos","events_url":"https://api.github.com/users/openshift/events{/privacy}","received_events_url":"https://api.github.com/users/openshift/received_events","type":"Organization","site_admin":false},"repo":{"id":22442668,"name":"origin","full_name":"openshift/origin","owner":{"login":"openshift","id":792337,"avatar_url":"https://avatars.githubusercontent.com/u/792337?v=3","gravatar_id":"","url":"https://api.github.com/users/openshift","html_url":"https://github.com/openshift","followers_url":"https://api.github.com/users/openshift/followers","following_url":"https://api.github.com/users/openshift/following{/other_user}","gists_url":"https://api.github.com/users/openshift/gists{/gist_id}","starred_url":"https://api.github.com/users/openshift/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/openshift/subscriptions","organizations_url":"https://api.github.com/users/openshift/orgs","repos_url":"https://api.github.com/users/openshift/repos","events_url":"https://api.github.com/users/openshift/events{/privacy}","received_events_url":"https://api.github.com/users/openshift/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/openshift/origin","description":"Enterprise-Ready Kubernetes for Developers","fork":false,"url":"https://api.github.com/repos/openshift/origin","forks_url":"https://api.github.com/repos/openshift/origin/forks","keys_url":"https://api.github.com/repos/openshift/origin/keys{/key_id}","collaborators_url":"https://api.github.com/repos/openshift/origin/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/openshift/origin/teams","hooks_url":"https://api.github.com/repos/openshift/origin/hooks","issue_events_url":"https://api.github.com/repos/openshift/origin/issues/events{/number}","events_url":"https://api.github.com/repos/openshift/origin/events","assignees_url":"https://api.github.com/repos/openshift/origin/assignees{/user}","branches_url":"https://api.github.com/repos/openshift/origin/branches{/branch}","tags_url":"https://api.github.com/repos/openshift/origin/tags","blobs_url":"https://api.github.com/repos/openshift/origin/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/openshift/origin/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/openshift/origin/git/refs{/sha}","trees_url":"https://api.github.com/repos/openshift/origin/git/trees{/sha}","statuses_url":"https://api.github.com/repos/openshift/origin/statuses/{sha}","languages_url":"https://api.github.com/repos/openshift/origin/languages","stargazers_url":"https://api.github.com/repos/openshift/origin/stargazers","contributors_url":"https://api.github.com/repos/openshift/origin/contributors","subscribers_url":"https://api.github.com/repos/openshift/origin/subscribers","subscription_url":"https://api.github.com/repos/openshift/origin/subscription","commits_url":"https://api.github.com/repos/openshift/origin/commits{/sha}","git_commits_url":"https://api.github.com/repos/openshift/origin/git/commits{/sha}","comments_url":"https://api.github.com/repos/openshift/origin/comments{/number}","issue_comment_url":"https://api.github.com/repos/openshift/origin/issues/comments{/number}","contents_url":"https://api.github.com/repos/openshift/origin/contents/{+path}","compare_url":"https://api.github.com/repos/openshift/origin/compare/{base}...{head}","merges_url":"https://api.github.com/repos/openshift/origin/merges","archive_url":"https://api.github.com/repos/openshift/origin/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/openshift/origin/downloads","issues_url":"https://api.github.com/repos/openshift/origin/issues{/number}","pulls_url":"https://api.github.com/repos/openshift/origin/pulls{/number}","milestones_url":"https://api.github.com/repos/openshift/origin/milestones{/number}","notifications_url":"https://api.github.com/repos/openshift/origin/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/openshift/origin/labels{/name}","releases_url":"https://api.github.com/repos/openshift/origin/releases{/id}","deployments_url":"https://api.github.com/repos/openshift/origin/deployments","created_at":"2014-07-30T20:04:05Z","updated_at":"2016-07-15T15:44:23Z","pushed_at":"2016-07-15T15:34:10Z","git_url":"git://github.com/openshift/origin.git","ssh_url":"git@github.com:openshift/origin.git","clone_url":"https://github.com/openshift/origin.git","svn_url":"https://github.com/openshift/origin","homepage":"http://www.openshift.org","size":544274,"stargazers_count":1485,"watchers_count":1485,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":880,"mirror_url":null,"open_issues_count":1072,"forks":880,"open_issues":1072,"watchers":1485,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/openshift/origin/pulls/9234"},"html":{"href":"https://github.com/openshift/origin/pull/9234"},"issue":{"href":"https://api.github.com/repos/openshift/origin/issues/9234"},"comments":{"href":"https://api.github.com/repos/openshift/origin/issues/9234/comments"},"review_comments":{"href":"https://api.github.com/repos/openshift/origin/pulls/9234/comments"},"review_comment":{"href":"https://api.github.com/repos/openshift/origin/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/openshift/origin/pulls/9234/commits"},"statuses":{"href":"https://api.github.com/repos/openshift/origin/statuses/5388db317f2a4b67112b1a0dbc4d1859139241b9"}}}}
{"actor":{"display_login":"sgallagher"}}