Separate common functions for `oc secrets add`
This is in preparation for reusing these routines for
`oc secrets unlink`
Signed-off-by: Stephen Gallagher <sgallagh@redhat.com>
Missing secrets should warn, not fail.
Signed-off-by: Stephen Gallagher <sgallagh@redhat.com>
oc secrets: rename "add" to "link"
Maintain compatibility with "add"
Signed-off-by: Stephen Gallagher <sgallagh@redhat.com>
Rework help documentation for `oc secrets link`
Also drop prefixes in examples
Signed-off-by: Stephen Gallagher <sgallagh@redhat.com>
Add `oc secrets unlink`
New command to remove the link between a service account and a
Secret object.
Signed-off-by: Stephen Gallagher <sgallagh@redhat.com>
oc secrets: Return non-success on any error
Signed-off-by: Stephen Gallagher <sgallagh@redhat.com>
| ... | ... |
@@ -3524,6 +3524,91 @@ _oc_secrets_new-sshauth() |
| 3524 | 3524 |
noun_aliases=() |
| 3525 | 3525 |
} |
| 3526 | 3526 |
|
| 3527 |
+_oc_secrets_link() |
|
| 3528 |
+{
|
|
| 3529 |
+ last_command="oc_secrets_link" |
|
| 3530 |
+ commands=() |
|
| 3531 |
+ |
|
| 3532 |
+ flags=() |
|
| 3533 |
+ two_word_flags=() |
|
| 3534 |
+ flags_with_completion=() |
|
| 3535 |
+ flags_completion=() |
|
| 3536 |
+ |
|
| 3537 |
+ flags+=("--for=")
|
|
| 3538 |
+ flags+=("--api-version=")
|
|
| 3539 |
+ flags+=("--as=")
|
|
| 3540 |
+ flags+=("--certificate-authority=")
|
|
| 3541 |
+ flags_with_completion+=("--certificate-authority")
|
|
| 3542 |
+ flags_completion+=("_filedir")
|
|
| 3543 |
+ flags+=("--client-certificate=")
|
|
| 3544 |
+ flags_with_completion+=("--client-certificate")
|
|
| 3545 |
+ flags_completion+=("_filedir")
|
|
| 3546 |
+ flags+=("--client-key=")
|
|
| 3547 |
+ flags_with_completion+=("--client-key")
|
|
| 3548 |
+ flags_completion+=("_filedir")
|
|
| 3549 |
+ flags+=("--cluster=")
|
|
| 3550 |
+ flags+=("--config=")
|
|
| 3551 |
+ flags_with_completion+=("--config")
|
|
| 3552 |
+ flags_completion+=("_filedir")
|
|
| 3553 |
+ flags+=("--context=")
|
|
| 3554 |
+ flags+=("--insecure-skip-tls-verify")
|
|
| 3555 |
+ flags+=("--log-flush-frequency=")
|
|
| 3556 |
+ flags+=("--loglevel=")
|
|
| 3557 |
+ flags+=("--logspec=")
|
|
| 3558 |
+ flags+=("--match-server-version")
|
|
| 3559 |
+ flags+=("--namespace=")
|
|
| 3560 |
+ two_word_flags+=("-n")
|
|
| 3561 |
+ flags+=("--server=")
|
|
| 3562 |
+ flags+=("--token=")
|
|
| 3563 |
+ flags+=("--user=")
|
|
| 3564 |
+ |
|
| 3565 |
+ must_have_one_flag=() |
|
| 3566 |
+ must_have_one_noun=() |
|
| 3567 |
+ noun_aliases=() |
|
| 3568 |
+} |
|
| 3569 |
+ |
|
| 3570 |
+_oc_secrets_unlink() |
|
| 3571 |
+{
|
|
| 3572 |
+ last_command="oc_secrets_unlink" |
|
| 3573 |
+ commands=() |
|
| 3574 |
+ |
|
| 3575 |
+ flags=() |
|
| 3576 |
+ two_word_flags=() |
|
| 3577 |
+ flags_with_completion=() |
|
| 3578 |
+ flags_completion=() |
|
| 3579 |
+ |
|
| 3580 |
+ flags+=("--api-version=")
|
|
| 3581 |
+ flags+=("--as=")
|
|
| 3582 |
+ flags+=("--certificate-authority=")
|
|
| 3583 |
+ flags_with_completion+=("--certificate-authority")
|
|
| 3584 |
+ flags_completion+=("_filedir")
|
|
| 3585 |
+ flags+=("--client-certificate=")
|
|
| 3586 |
+ flags_with_completion+=("--client-certificate")
|
|
| 3587 |
+ flags_completion+=("_filedir")
|
|
| 3588 |
+ flags+=("--client-key=")
|
|
| 3589 |
+ flags_with_completion+=("--client-key")
|
|
| 3590 |
+ flags_completion+=("_filedir")
|
|
| 3591 |
+ flags+=("--cluster=")
|
|
| 3592 |
+ flags+=("--config=")
|
|
| 3593 |
+ flags_with_completion+=("--config")
|
|
| 3594 |
+ flags_completion+=("_filedir")
|
|
| 3595 |
+ flags+=("--context=")
|
|
| 3596 |
+ flags+=("--insecure-skip-tls-verify")
|
|
| 3597 |
+ flags+=("--log-flush-frequency=")
|
|
| 3598 |
+ flags+=("--loglevel=")
|
|
| 3599 |
+ flags+=("--logspec=")
|
|
| 3600 |
+ flags+=("--match-server-version")
|
|
| 3601 |
+ flags+=("--namespace=")
|
|
| 3602 |
+ two_word_flags+=("-n")
|
|
| 3603 |
+ flags+=("--server=")
|
|
| 3604 |
+ flags+=("--token=")
|
|
| 3605 |
+ flags+=("--user=")
|
|
| 3606 |
+ |
|
| 3607 |
+ must_have_one_flag=() |
|
| 3608 |
+ must_have_one_noun=() |
|
| 3609 |
+ noun_aliases=() |
|
| 3610 |
+} |
|
| 3611 |
+ |
|
| 3527 | 3612 |
_oc_secrets_add() |
| 3528 | 3613 |
{
|
| 3529 | 3614 |
last_command="oc_secrets_add" |
| ... | ... |
@@ -3575,6 +3660,8 @@ _oc_secrets() |
| 3575 | 3575 |
commands+=("new-dockercfg")
|
| 3576 | 3576 |
commands+=("new-basicauth")
|
| 3577 | 3577 |
commands+=("new-sshauth")
|
| 3578 |
+ commands+=("link")
|
|
| 3579 |
+ commands+=("unlink")
|
|
| 3578 | 3580 |
commands+=("add")
|
| 3579 | 3581 |
|
| 3580 | 3582 |
flags=() |
| ... | ... |
@@ -7882,6 +7882,93 @@ _openshift_cli_secrets_new-sshauth() |
| 7882 | 7882 |
noun_aliases=() |
| 7883 | 7883 |
} |
| 7884 | 7884 |
|
| 7885 |
+_openshift_cli_secrets_link() |
|
| 7886 |
+{
|
|
| 7887 |
+ last_command="openshift_cli_secrets_link" |
|
| 7888 |
+ commands=() |
|
| 7889 |
+ |
|
| 7890 |
+ flags=() |
|
| 7891 |
+ two_word_flags=() |
|
| 7892 |
+ flags_with_completion=() |
|
| 7893 |
+ flags_completion=() |
|
| 7894 |
+ |
|
| 7895 |
+ flags+=("--for=")
|
|
| 7896 |
+ flags+=("--api-version=")
|
|
| 7897 |
+ flags+=("--as=")
|
|
| 7898 |
+ flags+=("--certificate-authority=")
|
|
| 7899 |
+ flags_with_completion+=("--certificate-authority")
|
|
| 7900 |
+ flags_completion+=("_filedir")
|
|
| 7901 |
+ flags+=("--client-certificate=")
|
|
| 7902 |
+ flags_with_completion+=("--client-certificate")
|
|
| 7903 |
+ flags_completion+=("_filedir")
|
|
| 7904 |
+ flags+=("--client-key=")
|
|
| 7905 |
+ flags_with_completion+=("--client-key")
|
|
| 7906 |
+ flags_completion+=("_filedir")
|
|
| 7907 |
+ flags+=("--cluster=")
|
|
| 7908 |
+ flags+=("--config=")
|
|
| 7909 |
+ flags_with_completion+=("--config")
|
|
| 7910 |
+ flags_completion+=("_filedir")
|
|
| 7911 |
+ flags+=("--context=")
|
|
| 7912 |
+ flags+=("--google-json-key=")
|
|
| 7913 |
+ flags+=("--insecure-skip-tls-verify")
|
|
| 7914 |
+ flags+=("--log-flush-frequency=")
|
|
| 7915 |
+ flags+=("--loglevel=")
|
|
| 7916 |
+ flags+=("--logspec=")
|
|
| 7917 |
+ flags+=("--match-server-version")
|
|
| 7918 |
+ flags+=("--namespace=")
|
|
| 7919 |
+ two_word_flags+=("-n")
|
|
| 7920 |
+ flags+=("--server=")
|
|
| 7921 |
+ flags+=("--token=")
|
|
| 7922 |
+ flags+=("--user=")
|
|
| 7923 |
+ |
|
| 7924 |
+ must_have_one_flag=() |
|
| 7925 |
+ must_have_one_noun=() |
|
| 7926 |
+ noun_aliases=() |
|
| 7927 |
+} |
|
| 7928 |
+ |
|
| 7929 |
+_openshift_cli_secrets_unlink() |
|
| 7930 |
+{
|
|
| 7931 |
+ last_command="openshift_cli_secrets_unlink" |
|
| 7932 |
+ commands=() |
|
| 7933 |
+ |
|
| 7934 |
+ flags=() |
|
| 7935 |
+ two_word_flags=() |
|
| 7936 |
+ flags_with_completion=() |
|
| 7937 |
+ flags_completion=() |
|
| 7938 |
+ |
|
| 7939 |
+ flags+=("--api-version=")
|
|
| 7940 |
+ flags+=("--as=")
|
|
| 7941 |
+ flags+=("--certificate-authority=")
|
|
| 7942 |
+ flags_with_completion+=("--certificate-authority")
|
|
| 7943 |
+ flags_completion+=("_filedir")
|
|
| 7944 |
+ flags+=("--client-certificate=")
|
|
| 7945 |
+ flags_with_completion+=("--client-certificate")
|
|
| 7946 |
+ flags_completion+=("_filedir")
|
|
| 7947 |
+ flags+=("--client-key=")
|
|
| 7948 |
+ flags_with_completion+=("--client-key")
|
|
| 7949 |
+ flags_completion+=("_filedir")
|
|
| 7950 |
+ flags+=("--cluster=")
|
|
| 7951 |
+ flags+=("--config=")
|
|
| 7952 |
+ flags_with_completion+=("--config")
|
|
| 7953 |
+ flags_completion+=("_filedir")
|
|
| 7954 |
+ flags+=("--context=")
|
|
| 7955 |
+ flags+=("--google-json-key=")
|
|
| 7956 |
+ flags+=("--insecure-skip-tls-verify")
|
|
| 7957 |
+ flags+=("--log-flush-frequency=")
|
|
| 7958 |
+ flags+=("--loglevel=")
|
|
| 7959 |
+ flags+=("--logspec=")
|
|
| 7960 |
+ flags+=("--match-server-version")
|
|
| 7961 |
+ flags+=("--namespace=")
|
|
| 7962 |
+ two_word_flags+=("-n")
|
|
| 7963 |
+ flags+=("--server=")
|
|
| 7964 |
+ flags+=("--token=")
|
|
| 7965 |
+ flags+=("--user=")
|
|
| 7966 |
+ |
|
| 7967 |
+ must_have_one_flag=() |
|
| 7968 |
+ must_have_one_noun=() |
|
| 7969 |
+ noun_aliases=() |
|
| 7970 |
+} |
|
| 7971 |
+ |
|
| 7885 | 7972 |
_openshift_cli_secrets_add() |
| 7886 | 7973 |
{
|
| 7887 | 7974 |
last_command="openshift_cli_secrets_add" |
| ... | ... |
@@ -7934,6 +8021,8 @@ _openshift_cli_secrets() |
| 7934 | 7934 |
commands+=("new-dockercfg")
|
| 7935 | 7935 |
commands+=("new-basicauth")
|
| 7936 | 7936 |
commands+=("new-sshauth")
|
| 7937 |
+ commands+=("link")
|
|
| 7938 |
+ commands+=("unlink")
|
|
| 7937 | 7939 |
commands+=("add")
|
| 7938 | 7940 |
|
| 7939 | 7941 |
flags=() |
| ... | ... |
@@ -3685,6 +3685,91 @@ _oc_secrets_new-sshauth() |
| 3685 | 3685 |
noun_aliases=() |
| 3686 | 3686 |
} |
| 3687 | 3687 |
|
| 3688 |
+_oc_secrets_link() |
|
| 3689 |
+{
|
|
| 3690 |
+ last_command="oc_secrets_link" |
|
| 3691 |
+ commands=() |
|
| 3692 |
+ |
|
| 3693 |
+ flags=() |
|
| 3694 |
+ two_word_flags=() |
|
| 3695 |
+ flags_with_completion=() |
|
| 3696 |
+ flags_completion=() |
|
| 3697 |
+ |
|
| 3698 |
+ flags+=("--for=")
|
|
| 3699 |
+ flags+=("--api-version=")
|
|
| 3700 |
+ flags+=("--as=")
|
|
| 3701 |
+ flags+=("--certificate-authority=")
|
|
| 3702 |
+ flags_with_completion+=("--certificate-authority")
|
|
| 3703 |
+ flags_completion+=("_filedir")
|
|
| 3704 |
+ flags+=("--client-certificate=")
|
|
| 3705 |
+ flags_with_completion+=("--client-certificate")
|
|
| 3706 |
+ flags_completion+=("_filedir")
|
|
| 3707 |
+ flags+=("--client-key=")
|
|
| 3708 |
+ flags_with_completion+=("--client-key")
|
|
| 3709 |
+ flags_completion+=("_filedir")
|
|
| 3710 |
+ flags+=("--cluster=")
|
|
| 3711 |
+ flags+=("--config=")
|
|
| 3712 |
+ flags_with_completion+=("--config")
|
|
| 3713 |
+ flags_completion+=("_filedir")
|
|
| 3714 |
+ flags+=("--context=")
|
|
| 3715 |
+ flags+=("--insecure-skip-tls-verify")
|
|
| 3716 |
+ flags+=("--log-flush-frequency=")
|
|
| 3717 |
+ flags+=("--loglevel=")
|
|
| 3718 |
+ flags+=("--logspec=")
|
|
| 3719 |
+ flags+=("--match-server-version")
|
|
| 3720 |
+ flags+=("--namespace=")
|
|
| 3721 |
+ two_word_flags+=("-n")
|
|
| 3722 |
+ flags+=("--server=")
|
|
| 3723 |
+ flags+=("--token=")
|
|
| 3724 |
+ flags+=("--user=")
|
|
| 3725 |
+ |
|
| 3726 |
+ must_have_one_flag=() |
|
| 3727 |
+ must_have_one_noun=() |
|
| 3728 |
+ noun_aliases=() |
|
| 3729 |
+} |
|
| 3730 |
+ |
|
| 3731 |
+_oc_secrets_unlink() |
|
| 3732 |
+{
|
|
| 3733 |
+ last_command="oc_secrets_unlink" |
|
| 3734 |
+ commands=() |
|
| 3735 |
+ |
|
| 3736 |
+ flags=() |
|
| 3737 |
+ two_word_flags=() |
|
| 3738 |
+ flags_with_completion=() |
|
| 3739 |
+ flags_completion=() |
|
| 3740 |
+ |
|
| 3741 |
+ flags+=("--api-version=")
|
|
| 3742 |
+ flags+=("--as=")
|
|
| 3743 |
+ flags+=("--certificate-authority=")
|
|
| 3744 |
+ flags_with_completion+=("--certificate-authority")
|
|
| 3745 |
+ flags_completion+=("_filedir")
|
|
| 3746 |
+ flags+=("--client-certificate=")
|
|
| 3747 |
+ flags_with_completion+=("--client-certificate")
|
|
| 3748 |
+ flags_completion+=("_filedir")
|
|
| 3749 |
+ flags+=("--client-key=")
|
|
| 3750 |
+ flags_with_completion+=("--client-key")
|
|
| 3751 |
+ flags_completion+=("_filedir")
|
|
| 3752 |
+ flags+=("--cluster=")
|
|
| 3753 |
+ flags+=("--config=")
|
|
| 3754 |
+ flags_with_completion+=("--config")
|
|
| 3755 |
+ flags_completion+=("_filedir")
|
|
| 3756 |
+ flags+=("--context=")
|
|
| 3757 |
+ flags+=("--insecure-skip-tls-verify")
|
|
| 3758 |
+ flags+=("--log-flush-frequency=")
|
|
| 3759 |
+ flags+=("--loglevel=")
|
|
| 3760 |
+ flags+=("--logspec=")
|
|
| 3761 |
+ flags+=("--match-server-version")
|
|
| 3762 |
+ flags+=("--namespace=")
|
|
| 3763 |
+ two_word_flags+=("-n")
|
|
| 3764 |
+ flags+=("--server=")
|
|
| 3765 |
+ flags+=("--token=")
|
|
| 3766 |
+ flags+=("--user=")
|
|
| 3767 |
+ |
|
| 3768 |
+ must_have_one_flag=() |
|
| 3769 |
+ must_have_one_noun=() |
|
| 3770 |
+ noun_aliases=() |
|
| 3771 |
+} |
|
| 3772 |
+ |
|
| 3688 | 3773 |
_oc_secrets_add() |
| 3689 | 3774 |
{
|
| 3690 | 3775 |
last_command="oc_secrets_add" |
| ... | ... |
@@ -3736,6 +3821,8 @@ _oc_secrets() |
| 3736 | 3736 |
commands+=("new-dockercfg")
|
| 3737 | 3737 |
commands+=("new-basicauth")
|
| 3738 | 3738 |
commands+=("new-sshauth")
|
| 3739 |
+ commands+=("link")
|
|
| 3740 |
+ commands+=("unlink")
|
|
| 3739 | 3741 |
commands+=("add")
|
| 3740 | 3742 |
|
| 3741 | 3743 |
flags=() |
| ... | ... |
@@ -8043,6 +8043,93 @@ _openshift_cli_secrets_new-sshauth() |
| 8043 | 8043 |
noun_aliases=() |
| 8044 | 8044 |
} |
| 8045 | 8045 |
|
| 8046 |
+_openshift_cli_secrets_link() |
|
| 8047 |
+{
|
|
| 8048 |
+ last_command="openshift_cli_secrets_link" |
|
| 8049 |
+ commands=() |
|
| 8050 |
+ |
|
| 8051 |
+ flags=() |
|
| 8052 |
+ two_word_flags=() |
|
| 8053 |
+ flags_with_completion=() |
|
| 8054 |
+ flags_completion=() |
|
| 8055 |
+ |
|
| 8056 |
+ flags+=("--for=")
|
|
| 8057 |
+ flags+=("--api-version=")
|
|
| 8058 |
+ flags+=("--as=")
|
|
| 8059 |
+ flags+=("--certificate-authority=")
|
|
| 8060 |
+ flags_with_completion+=("--certificate-authority")
|
|
| 8061 |
+ flags_completion+=("_filedir")
|
|
| 8062 |
+ flags+=("--client-certificate=")
|
|
| 8063 |
+ flags_with_completion+=("--client-certificate")
|
|
| 8064 |
+ flags_completion+=("_filedir")
|
|
| 8065 |
+ flags+=("--client-key=")
|
|
| 8066 |
+ flags_with_completion+=("--client-key")
|
|
| 8067 |
+ flags_completion+=("_filedir")
|
|
| 8068 |
+ flags+=("--cluster=")
|
|
| 8069 |
+ flags+=("--config=")
|
|
| 8070 |
+ flags_with_completion+=("--config")
|
|
| 8071 |
+ flags_completion+=("_filedir")
|
|
| 8072 |
+ flags+=("--context=")
|
|
| 8073 |
+ flags+=("--google-json-key=")
|
|
| 8074 |
+ flags+=("--insecure-skip-tls-verify")
|
|
| 8075 |
+ flags+=("--log-flush-frequency=")
|
|
| 8076 |
+ flags+=("--loglevel=")
|
|
| 8077 |
+ flags+=("--logspec=")
|
|
| 8078 |
+ flags+=("--match-server-version")
|
|
| 8079 |
+ flags+=("--namespace=")
|
|
| 8080 |
+ two_word_flags+=("-n")
|
|
| 8081 |
+ flags+=("--server=")
|
|
| 8082 |
+ flags+=("--token=")
|
|
| 8083 |
+ flags+=("--user=")
|
|
| 8084 |
+ |
|
| 8085 |
+ must_have_one_flag=() |
|
| 8086 |
+ must_have_one_noun=() |
|
| 8087 |
+ noun_aliases=() |
|
| 8088 |
+} |
|
| 8089 |
+ |
|
| 8090 |
+_openshift_cli_secrets_unlink() |
|
| 8091 |
+{
|
|
| 8092 |
+ last_command="openshift_cli_secrets_unlink" |
|
| 8093 |
+ commands=() |
|
| 8094 |
+ |
|
| 8095 |
+ flags=() |
|
| 8096 |
+ two_word_flags=() |
|
| 8097 |
+ flags_with_completion=() |
|
| 8098 |
+ flags_completion=() |
|
| 8099 |
+ |
|
| 8100 |
+ flags+=("--api-version=")
|
|
| 8101 |
+ flags+=("--as=")
|
|
| 8102 |
+ flags+=("--certificate-authority=")
|
|
| 8103 |
+ flags_with_completion+=("--certificate-authority")
|
|
| 8104 |
+ flags_completion+=("_filedir")
|
|
| 8105 |
+ flags+=("--client-certificate=")
|
|
| 8106 |
+ flags_with_completion+=("--client-certificate")
|
|
| 8107 |
+ flags_completion+=("_filedir")
|
|
| 8108 |
+ flags+=("--client-key=")
|
|
| 8109 |
+ flags_with_completion+=("--client-key")
|
|
| 8110 |
+ flags_completion+=("_filedir")
|
|
| 8111 |
+ flags+=("--cluster=")
|
|
| 8112 |
+ flags+=("--config=")
|
|
| 8113 |
+ flags_with_completion+=("--config")
|
|
| 8114 |
+ flags_completion+=("_filedir")
|
|
| 8115 |
+ flags+=("--context=")
|
|
| 8116 |
+ flags+=("--google-json-key=")
|
|
| 8117 |
+ flags+=("--insecure-skip-tls-verify")
|
|
| 8118 |
+ flags+=("--log-flush-frequency=")
|
|
| 8119 |
+ flags+=("--loglevel=")
|
|
| 8120 |
+ flags+=("--logspec=")
|
|
| 8121 |
+ flags+=("--match-server-version")
|
|
| 8122 |
+ flags+=("--namespace=")
|
|
| 8123 |
+ two_word_flags+=("-n")
|
|
| 8124 |
+ flags+=("--server=")
|
|
| 8125 |
+ flags+=("--token=")
|
|
| 8126 |
+ flags+=("--user=")
|
|
| 8127 |
+ |
|
| 8128 |
+ must_have_one_flag=() |
|
| 8129 |
+ must_have_one_noun=() |
|
| 8130 |
+ noun_aliases=() |
|
| 8131 |
+} |
|
| 8132 |
+ |
|
| 8046 | 8133 |
_openshift_cli_secrets_add() |
| 8047 | 8134 |
{
|
| 8048 | 8135 |
last_command="openshift_cli_secrets_add" |
| ... | ... |
@@ -8095,6 +8182,8 @@ _openshift_cli_secrets() |
| 8095 | 8095 |
commands+=("new-dockercfg")
|
| 8096 | 8096 |
commands+=("new-basicauth")
|
| 8097 | 8097 |
commands+=("new-sshauth")
|
| 8098 |
+ commands+=("link")
|
|
| 8099 |
+ commands+=("unlink")
|
|
| 8098 | 8100 |
commands+=("add")
|
| 8099 | 8101 |
|
| 8100 | 8102 |
flags=() |
| ... | ... |
@@ -2092,20 +2092,39 @@ Change the number of pods in a deployment |
| 2092 | 2092 |
|
| 2093 | 2093 |
|
| 2094 | 2094 |
== oc secrets add |
| 2095 |
-Add secrets to a ServiceAccount |
|
| 2095 |
+DEPRECATED: secrets link |
|
| 2096 | 2096 |
|
| 2097 | 2097 |
==== |
| 2098 | 2098 |
|
| 2099 | 2099 |
[options="nowrap"] |
| 2100 | 2100 |
---- |
| 2101 |
- // To use your secret inside of a pod or as a push, pull, or source secret for a build, you must add a 'mount' secret to your service account like this: |
|
| 2102 |
- oc secrets add serviceaccount/sa-name secrets/secret-name secrets/another-secret-name |
|
| 2101 |
+ # Add an image pull secret to a service account to automatically use it for pulling pod images: |
|
| 2102 |
+ oc serviceaccount-name pull-secret --for=pull |
|
| 2103 | 2103 |
|
| 2104 |
- // To use your secret as an image pull secret, you must add a 'pull' secret to your service account like this: |
|
| 2105 |
- oc secrets add serviceaccount/sa-name secrets/secret-name --for=pull |
|
| 2104 |
+ # Add an image pull secret to a service account to automatically use it for both pulling and pushing build images: |
|
| 2105 |
+ oc builder builder-image-secret --for=pull,mount |
|
| 2106 | 2106 |
|
| 2107 |
- // To use your secret for image pulls or inside a pod: |
|
| 2108 |
- oc secrets add serviceaccount/sa-name secrets/secret-name --for=pull,mount |
|
| 2107 |
+ # If the cluster's serviceAccountConfig is operating with limitSecretReferences: True, secrets must be added to the pod's service account whitelist in order to be available to the pod: |
|
| 2108 |
+ oc pod-sa pod-secret |
|
| 2109 |
+---- |
|
| 2110 |
+==== |
|
| 2111 |
+ |
|
| 2112 |
+ |
|
| 2113 |
+== oc secrets link |
|
| 2114 |
+Link secrets to a ServiceAccount |
|
| 2115 |
+ |
|
| 2116 |
+==== |
|
| 2117 |
+ |
|
| 2118 |
+[options="nowrap"] |
|
| 2119 |
+---- |
|
| 2120 |
+ # Add an image pull secret to a service account to automatically use it for pulling pod images: |
|
| 2121 |
+ oc secrets link serviceaccount-name pull-secret --for=pull |
|
| 2122 |
+ |
|
| 2123 |
+ # Add an image pull secret to a service account to automatically use it for both pulling and pushing build images: |
|
| 2124 |
+ oc secrets link builder builder-image-secret --for=pull,mount |
|
| 2125 |
+ |
|
| 2126 |
+ # If the cluster's serviceAccountConfig is operating with limitSecretReferences: True, secrets must be added to the pod's service account whitelist in order to be available to the pod: |
|
| 2127 |
+ oc secrets link pod-sa pod-secret |
|
| 2109 | 2128 |
---- |
| 2110 | 2129 |
==== |
| 2111 | 2130 |
|
| ... | ... |
@@ -2195,6 +2214,19 @@ Create a new secret for SSH authentication |
| 2195 | 2195 |
==== |
| 2196 | 2196 |
|
| 2197 | 2197 |
|
| 2198 |
+== oc secrets unlink |
|
| 2199 |
+Detach secrets from a ServiceAccount |
|
| 2200 |
+ |
|
| 2201 |
+==== |
|
| 2202 |
+ |
|
| 2203 |
+[options="nowrap"] |
|
| 2204 |
+---- |
|
| 2205 |
+ # Unlink a secret currently associated with a service account: |
|
| 2206 |
+oc secrets unlink serviceaccount-name secret-name another-secret-name ... |
|
| 2207 |
+---- |
|
| 2208 |
+==== |
|
| 2209 |
+ |
|
| 2210 |
+ |
|
| 2198 | 2211 |
== oc serviceaccounts get-token |
| 2199 | 2212 |
Get a token assigned to a service account. |
| 2200 | 2213 |
|
| ... | ... |
@@ -170,10 +170,12 @@ oc-rsync.1 |
| 170 | 170 |
oc-run.1 |
| 171 | 171 |
oc-scale.1 |
| 172 | 172 |
oc-secrets-add.1 |
| 173 |
+oc-secrets-link.1 |
|
| 173 | 174 |
oc-secrets-new-basicauth.1 |
| 174 | 175 |
oc-secrets-new-dockercfg.1 |
| 175 | 176 |
oc-secrets-new-sshauth.1 |
| 176 | 177 |
oc-secrets-new.1 |
| 178 |
+oc-secrets-unlink.1 |
|
| 177 | 179 |
oc-secrets.1 |
| 178 | 180 |
oc-serviceaccounts-get-token.1 |
| 179 | 181 |
oc-serviceaccounts-new-token.1 |
| ... | ... |
@@ -249,10 +249,12 @@ openshift-cli-rsync.1 |
| 249 | 249 |
openshift-cli-run.1 |
| 250 | 250 |
openshift-cli-scale.1 |
| 251 | 251 |
openshift-cli-secrets-add.1 |
| 252 |
+openshift-cli-secrets-link.1 |
|
| 252 | 253 |
openshift-cli-secrets-new-basicauth.1 |
| 253 | 254 |
openshift-cli-secrets-new-dockercfg.1 |
| 254 | 255 |
openshift-cli-secrets-new-sshauth.1 |
| 255 | 256 |
openshift-cli-secrets-new.1 |
| 257 |
+openshift-cli-secrets-unlink.1 |
|
| 256 | 258 |
openshift-cli-secrets.1 |
| 257 | 259 |
openshift-cli-serviceaccounts-get-token.1 |
| 258 | 260 |
openshift-cli-serviceaccounts-new-token.1 |
| ... | ... |
@@ -3,7 +3,7 @@ |
| 3 | 3 |
|
| 4 | 4 |
.SH NAME |
| 5 | 5 |
.PP |
| 6 |
-oc secrets add \- Add secrets to a ServiceAccount |
|
| 6 |
+oc secrets add \- DEPRECATED: secrets link |
|
| 7 | 7 |
|
| 8 | 8 |
|
| 9 | 9 |
.SH SYNOPSIS |
| ... | ... |
@@ -13,16 +13,13 @@ oc secrets add \- Add secrets to a ServiceAccount |
| 13 | 13 |
|
| 14 | 14 |
.SH DESCRIPTION |
| 15 | 15 |
.PP |
| 16 |
-Add secrets to a ServiceAccount |
|
| 17 |
- |
|
| 18 |
-.PP |
|
| 19 |
-After you have created a secret, you probably want to make use of that secret inside of a pod, for a build, or as an image pull secret. In order to do that, you must add your secret to a service account. |
|
| 16 |
+DEPRECATED: This command has been moved to "oc secrets link" |
|
| 20 | 17 |
|
| 21 | 18 |
|
| 22 | 19 |
.SH OPTIONS |
| 23 | 20 |
.PP |
| 24 | 21 |
\fB\-\-for\fP=[mount] |
| 25 |
- type of secret to add: mount or pull |
|
| 22 |
+ type of secret to link: mount or pull |
|
| 26 | 23 |
|
| 27 | 24 |
|
| 28 | 25 |
.SH OPTIONS INHERITED FROM PARENT COMMANDS |
| ... | ... |
@@ -96,14 +93,14 @@ After you have created a secret, you probably want to make use of that secret in |
| 96 | 96 |
.RS |
| 97 | 97 |
|
| 98 | 98 |
.nf |
| 99 |
- // To use your secret inside of a pod or as a push, pull, or source secret for a build, you must add a 'mount' secret to your service account like this: |
|
| 100 |
- oc secrets add serviceaccount/sa\-name secrets/secret\-name secrets/another\-secret\-name |
|
| 99 |
+ # Add an image pull secret to a service account to automatically use it for pulling pod images: |
|
| 100 |
+ oc serviceaccount\-name pull\-secret \-\-for=pull |
|
| 101 | 101 |
|
| 102 |
- // To use your secret as an image pull secret, you must add a 'pull' secret to your service account like this: |
|
| 103 |
- oc secrets add serviceaccount/sa\-name secrets/secret\-name \-\-for=pull |
|
| 102 |
+ # Add an image pull secret to a service account to automatically use it for both pulling and pushing build images: |
|
| 103 |
+ oc builder builder\-image\-secret \-\-for=pull,mount |
|
| 104 | 104 |
|
| 105 |
- // To use your secret for image pulls or inside a pod: |
|
| 106 |
- oc secrets add serviceaccount/sa\-name secrets/secret\-name \-\-for=pull,mount |
|
| 105 |
+ # If the cluster's serviceAccountConfig is operating with limitSecretReferences: True, secrets must be added to the pod's service account whitelist in order to be available to the pod: |
|
| 106 |
+ oc pod\-sa pod\-secret |
|
| 107 | 107 |
|
| 108 | 108 |
.fi |
| 109 | 109 |
.RE |
| 110 | 110 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,119 @@ |
| 0 |
+.TH "OC SECRETS" "1" " Openshift CLI User Manuals" "Openshift" "June 2016" "" |
|
| 1 |
+ |
|
| 2 |
+ |
|
| 3 |
+.SH NAME |
|
| 4 |
+.PP |
|
| 5 |
+oc secrets link \- Link secrets to a ServiceAccount |
|
| 6 |
+ |
|
| 7 |
+ |
|
| 8 |
+.SH SYNOPSIS |
|
| 9 |
+.PP |
|
| 10 |
+\fBoc secrets link\fP [OPTIONS] |
|
| 11 |
+ |
|
| 12 |
+ |
|
| 13 |
+.SH DESCRIPTION |
|
| 14 |
+.PP |
|
| 15 |
+Link secrets to a service account |
|
| 16 |
+ |
|
| 17 |
+.PP |
|
| 18 |
+Linking a secret enables a service account to automatically use that secret for some forms of authentication |
|
| 19 |
+ |
|
| 20 |
+ |
|
| 21 |
+.SH OPTIONS |
|
| 22 |
+.PP |
|
| 23 |
+\fB\-\-for\fP=[mount] |
|
| 24 |
+ type of secret to link: mount or pull |
|
| 25 |
+ |
|
| 26 |
+ |
|
| 27 |
+.SH OPTIONS INHERITED FROM PARENT COMMANDS |
|
| 28 |
+.PP |
|
| 29 |
+\fB\-\-api\-version\fP="" |
|
| 30 |
+ DEPRECATED: The API version to use when talking to the server |
|
| 31 |
+ |
|
| 32 |
+.PP |
|
| 33 |
+\fB\-\-as\fP="" |
|
| 34 |
+ Username to impersonate for the operation. |
|
| 35 |
+ |
|
| 36 |
+.PP |
|
| 37 |
+\fB\-\-certificate\-authority\fP="" |
|
| 38 |
+ Path to a cert. file for the certificate authority. |
|
| 39 |
+ |
|
| 40 |
+.PP |
|
| 41 |
+\fB\-\-client\-certificate\fP="" |
|
| 42 |
+ Path to a client certificate file for TLS. |
|
| 43 |
+ |
|
| 44 |
+.PP |
|
| 45 |
+\fB\-\-client\-key\fP="" |
|
| 46 |
+ Path to a client key file for TLS. |
|
| 47 |
+ |
|
| 48 |
+.PP |
|
| 49 |
+\fB\-\-cluster\fP="" |
|
| 50 |
+ The name of the kubeconfig cluster to use |
|
| 51 |
+ |
|
| 52 |
+.PP |
|
| 53 |
+\fB\-\-config\fP="" |
|
| 54 |
+ Path to the config file to use for CLI requests. |
|
| 55 |
+ |
|
| 56 |
+.PP |
|
| 57 |
+\fB\-\-context\fP="" |
|
| 58 |
+ The name of the kubeconfig context to use |
|
| 59 |
+ |
|
| 60 |
+.PP |
|
| 61 |
+\fB\-\-google\-json\-key\fP="" |
|
| 62 |
+ The Google Cloud Platform Service Account JSON Key to use for authentication. |
|
| 63 |
+ |
|
| 64 |
+.PP |
|
| 65 |
+\fB\-\-insecure\-skip\-tls\-verify\fP=false |
|
| 66 |
+ If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. |
|
| 67 |
+ |
|
| 68 |
+.PP |
|
| 69 |
+\fB\-\-log\-flush\-frequency\fP=0 |
|
| 70 |
+ Maximum number of seconds between log flushes |
|
| 71 |
+ |
|
| 72 |
+.PP |
|
| 73 |
+\fB\-\-match\-server\-version\fP=false |
|
| 74 |
+ Require server version to match client version |
|
| 75 |
+ |
|
| 76 |
+.PP |
|
| 77 |
+\fB\-n\fP, \fB\-\-namespace\fP="" |
|
| 78 |
+ If present, the namespace scope for this CLI request. |
|
| 79 |
+ |
|
| 80 |
+.PP |
|
| 81 |
+\fB\-\-server\fP="" |
|
| 82 |
+ The address and port of the Kubernetes API server |
|
| 83 |
+ |
|
| 84 |
+.PP |
|
| 85 |
+\fB\-\-token\fP="" |
|
| 86 |
+ Bearer token for authentication to the API server. |
|
| 87 |
+ |
|
| 88 |
+.PP |
|
| 89 |
+\fB\-\-user\fP="" |
|
| 90 |
+ The name of the kubeconfig user to use |
|
| 91 |
+ |
|
| 92 |
+ |
|
| 93 |
+.SH EXAMPLE |
|
| 94 |
+.PP |
|
| 95 |
+.RS |
|
| 96 |
+ |
|
| 97 |
+.nf |
|
| 98 |
+ # Add an image pull secret to a service account to automatically use it for pulling pod images: |
|
| 99 |
+ oc secrets link serviceaccount\-name pull\-secret \-\-for=pull |
|
| 100 |
+ |
|
| 101 |
+ # Add an image pull secret to a service account to automatically use it for both pulling and pushing build images: |
|
| 102 |
+ oc secrets link builder builder\-image\-secret \-\-for=pull,mount |
|
| 103 |
+ |
|
| 104 |
+ # If the cluster's serviceAccountConfig is operating with limitSecretReferences: True, secrets must be added to the pod's service account whitelist in order to be available to the pod: |
|
| 105 |
+ oc secrets link pod\-sa pod\-secret |
|
| 106 |
+ |
|
| 107 |
+.fi |
|
| 108 |
+.RE |
|
| 109 |
+ |
|
| 110 |
+ |
|
| 111 |
+.SH SEE ALSO |
|
| 112 |
+.PP |
|
| 113 |
+\fBoc\-secrets(1)\fP, |
|
| 114 |
+ |
|
| 115 |
+ |
|
| 116 |
+.SH HISTORY |
|
| 117 |
+.PP |
|
| 118 |
+June 2016, Ported from the Kubernetes man\-doc generator |
| 0 | 119 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,107 @@ |
| 0 |
+.TH "OC SECRETS" "1" " Openshift CLI User Manuals" "Openshift" "June 2016" "" |
|
| 1 |
+ |
|
| 2 |
+ |
|
| 3 |
+.SH NAME |
|
| 4 |
+.PP |
|
| 5 |
+oc secrets unlink \- Detach secrets from a ServiceAccount |
|
| 6 |
+ |
|
| 7 |
+ |
|
| 8 |
+.SH SYNOPSIS |
|
| 9 |
+.PP |
|
| 10 |
+\fBoc secrets unlink\fP [OPTIONS] |
|
| 11 |
+ |
|
| 12 |
+ |
|
| 13 |
+.SH DESCRIPTION |
|
| 14 |
+.PP |
|
| 15 |
+Unlink (detach) secrets from a service account |
|
| 16 |
+ |
|
| 17 |
+.PP |
|
| 18 |
+If a secret is no longer valid for a pod, build or image pull, you may unlink it from a service account. |
|
| 19 |
+ |
|
| 20 |
+ |
|
| 21 |
+.SH OPTIONS INHERITED FROM PARENT COMMANDS |
|
| 22 |
+.PP |
|
| 23 |
+\fB\-\-api\-version\fP="" |
|
| 24 |
+ DEPRECATED: The API version to use when talking to the server |
|
| 25 |
+ |
|
| 26 |
+.PP |
|
| 27 |
+\fB\-\-as\fP="" |
|
| 28 |
+ Username to impersonate for the operation. |
|
| 29 |
+ |
|
| 30 |
+.PP |
|
| 31 |
+\fB\-\-certificate\-authority\fP="" |
|
| 32 |
+ Path to a cert. file for the certificate authority. |
|
| 33 |
+ |
|
| 34 |
+.PP |
|
| 35 |
+\fB\-\-client\-certificate\fP="" |
|
| 36 |
+ Path to a client certificate file for TLS. |
|
| 37 |
+ |
|
| 38 |
+.PP |
|
| 39 |
+\fB\-\-client\-key\fP="" |
|
| 40 |
+ Path to a client key file for TLS. |
|
| 41 |
+ |
|
| 42 |
+.PP |
|
| 43 |
+\fB\-\-cluster\fP="" |
|
| 44 |
+ The name of the kubeconfig cluster to use |
|
| 45 |
+ |
|
| 46 |
+.PP |
|
| 47 |
+\fB\-\-config\fP="" |
|
| 48 |
+ Path to the config file to use for CLI requests. |
|
| 49 |
+ |
|
| 50 |
+.PP |
|
| 51 |
+\fB\-\-context\fP="" |
|
| 52 |
+ The name of the kubeconfig context to use |
|
| 53 |
+ |
|
| 54 |
+.PP |
|
| 55 |
+\fB\-\-google\-json\-key\fP="" |
|
| 56 |
+ The Google Cloud Platform Service Account JSON Key to use for authentication. |
|
| 57 |
+ |
|
| 58 |
+.PP |
|
| 59 |
+\fB\-\-insecure\-skip\-tls\-verify\fP=false |
|
| 60 |
+ If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. |
|
| 61 |
+ |
|
| 62 |
+.PP |
|
| 63 |
+\fB\-\-log\-flush\-frequency\fP=0 |
|
| 64 |
+ Maximum number of seconds between log flushes |
|
| 65 |
+ |
|
| 66 |
+.PP |
|
| 67 |
+\fB\-\-match\-server\-version\fP=false |
|
| 68 |
+ Require server version to match client version |
|
| 69 |
+ |
|
| 70 |
+.PP |
|
| 71 |
+\fB\-n\fP, \fB\-\-namespace\fP="" |
|
| 72 |
+ If present, the namespace scope for this CLI request. |
|
| 73 |
+ |
|
| 74 |
+.PP |
|
| 75 |
+\fB\-\-server\fP="" |
|
| 76 |
+ The address and port of the Kubernetes API server |
|
| 77 |
+ |
|
| 78 |
+.PP |
|
| 79 |
+\fB\-\-token\fP="" |
|
| 80 |
+ Bearer token for authentication to the API server. |
|
| 81 |
+ |
|
| 82 |
+.PP |
|
| 83 |
+\fB\-\-user\fP="" |
|
| 84 |
+ The name of the kubeconfig user to use |
|
| 85 |
+ |
|
| 86 |
+ |
|
| 87 |
+.SH EXAMPLE |
|
| 88 |
+.PP |
|
| 89 |
+.RS |
|
| 90 |
+ |
|
| 91 |
+.nf |
|
| 92 |
+ # Unlink a secret currently associated with a service account: |
|
| 93 |
+oc secrets unlink serviceaccount\-name secret\-name another\-secret\-name ... |
|
| 94 |
+ |
|
| 95 |
+.fi |
|
| 96 |
+.RE |
|
| 97 |
+ |
|
| 98 |
+ |
|
| 99 |
+.SH SEE ALSO |
|
| 100 |
+.PP |
|
| 101 |
+\fBoc\-secrets(1)\fP, |
|
| 102 |
+ |
|
| 103 |
+ |
|
| 104 |
+.SH HISTORY |
|
| 105 |
+.PP |
|
| 106 |
+June 2016, Ported from the Kubernetes man\-doc generator |
| ... | ... |
@@ -89,7 +89,7 @@ Docker registries. |
| 89 | 89 |
|
| 90 | 90 |
.SH SEE ALSO |
| 91 | 91 |
.PP |
| 92 |
-\fBoc(1)\fP, \fBoc\-secrets\-new(1)\fP, \fBoc\-secrets\-new\-dockercfg(1)\fP, \fBoc\-secrets\-new\-basicauth(1)\fP, \fBoc\-secrets\-new\-sshauth(1)\fP, \fBoc\-secrets\-add(1)\fP, |
|
| 92 |
+\fBoc(1)\fP, \fBoc\-secrets\-new(1)\fP, \fBoc\-secrets\-new\-dockercfg(1)\fP, \fBoc\-secrets\-new\-basicauth(1)\fP, \fBoc\-secrets\-new\-sshauth(1)\fP, \fBoc\-secrets\-link(1)\fP, \fBoc\-secrets\-unlink(1)\fP, \fBoc\-secrets\-add(1)\fP, |
|
| 93 | 93 |
|
| 94 | 94 |
|
| 95 | 95 |
.SH HISTORY |
| ... | ... |
@@ -3,7 +3,7 @@ |
| 3 | 3 |
|
| 4 | 4 |
.SH NAME |
| 5 | 5 |
.PP |
| 6 |
-openshift cli secrets add \- Add secrets to a ServiceAccount |
|
| 6 |
+openshift cli secrets add \- DEPRECATED: secrets link |
|
| 7 | 7 |
|
| 8 | 8 |
|
| 9 | 9 |
.SH SYNOPSIS |
| ... | ... |
@@ -13,16 +13,13 @@ openshift cli secrets add \- Add secrets to a ServiceAccount |
| 13 | 13 |
|
| 14 | 14 |
.SH DESCRIPTION |
| 15 | 15 |
.PP |
| 16 |
-Add secrets to a ServiceAccount |
|
| 17 |
- |
|
| 18 |
-.PP |
|
| 19 |
-After you have created a secret, you probably want to make use of that secret inside of a pod, for a build, or as an image pull secret. In order to do that, you must add your secret to a service account. |
|
| 16 |
+DEPRECATED: This command has been moved to "openshift cli secrets link" |
|
| 20 | 17 |
|
| 21 | 18 |
|
| 22 | 19 |
.SH OPTIONS |
| 23 | 20 |
.PP |
| 24 | 21 |
\fB\-\-for\fP=[mount] |
| 25 |
- type of secret to add: mount or pull |
|
| 22 |
+ type of secret to link: mount or pull |
|
| 26 | 23 |
|
| 27 | 24 |
|
| 28 | 25 |
.SH OPTIONS INHERITED FROM PARENT COMMANDS |
| ... | ... |
@@ -96,14 +93,14 @@ After you have created a secret, you probably want to make use of that secret in |
| 96 | 96 |
.RS |
| 97 | 97 |
|
| 98 | 98 |
.nf |
| 99 |
- // To use your secret inside of a pod or as a push, pull, or source secret for a build, you must add a 'mount' secret to your service account like this: |
|
| 100 |
- openshift cli secrets add serviceaccount/sa\-name secrets/secret\-name secrets/another\-secret\-name |
|
| 99 |
+ # Add an image pull secret to a service account to automatically use it for pulling pod images: |
|
| 100 |
+ openshift cli serviceaccount\-name pull\-secret \-\-for=pull |
|
| 101 | 101 |
|
| 102 |
- // To use your secret as an image pull secret, you must add a 'pull' secret to your service account like this: |
|
| 103 |
- openshift cli secrets add serviceaccount/sa\-name secrets/secret\-name \-\-for=pull |
|
| 102 |
+ # Add an image pull secret to a service account to automatically use it for both pulling and pushing build images: |
|
| 103 |
+ openshift cli builder builder\-image\-secret \-\-for=pull,mount |
|
| 104 | 104 |
|
| 105 |
- // To use your secret for image pulls or inside a pod: |
|
| 106 |
- openshift cli secrets add serviceaccount/sa\-name secrets/secret\-name \-\-for=pull,mount |
|
| 105 |
+ # If the cluster's serviceAccountConfig is operating with limitSecretReferences: True, secrets must be added to the pod's service account whitelist in order to be available to the pod: |
|
| 106 |
+ openshift cli pod\-sa pod\-secret |
|
| 107 | 107 |
|
| 108 | 108 |
.fi |
| 109 | 109 |
.RE |
| 110 | 110 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,119 @@ |
| 0 |
+.TH "OPENSHIFT CLI SECRETS" "1" " Openshift CLI User Manuals" "Openshift" "June 2016" "" |
|
| 1 |
+ |
|
| 2 |
+ |
|
| 3 |
+.SH NAME |
|
| 4 |
+.PP |
|
| 5 |
+openshift cli secrets link \- Link secrets to a ServiceAccount |
|
| 6 |
+ |
|
| 7 |
+ |
|
| 8 |
+.SH SYNOPSIS |
|
| 9 |
+.PP |
|
| 10 |
+\fBopenshift cli secrets link\fP [OPTIONS] |
|
| 11 |
+ |
|
| 12 |
+ |
|
| 13 |
+.SH DESCRIPTION |
|
| 14 |
+.PP |
|
| 15 |
+Link secrets to a service account |
|
| 16 |
+ |
|
| 17 |
+.PP |
|
| 18 |
+Linking a secret enables a service account to automatically use that secret for some forms of authentication |
|
| 19 |
+ |
|
| 20 |
+ |
|
| 21 |
+.SH OPTIONS |
|
| 22 |
+.PP |
|
| 23 |
+\fB\-\-for\fP=[mount] |
|
| 24 |
+ type of secret to link: mount or pull |
|
| 25 |
+ |
|
| 26 |
+ |
|
| 27 |
+.SH OPTIONS INHERITED FROM PARENT COMMANDS |
|
| 28 |
+.PP |
|
| 29 |
+\fB\-\-api\-version\fP="" |
|
| 30 |
+ DEPRECATED: The API version to use when talking to the server |
|
| 31 |
+ |
|
| 32 |
+.PP |
|
| 33 |
+\fB\-\-as\fP="" |
|
| 34 |
+ Username to impersonate for the operation. |
|
| 35 |
+ |
|
| 36 |
+.PP |
|
| 37 |
+\fB\-\-certificate\-authority\fP="" |
|
| 38 |
+ Path to a cert. file for the certificate authority. |
|
| 39 |
+ |
|
| 40 |
+.PP |
|
| 41 |
+\fB\-\-client\-certificate\fP="" |
|
| 42 |
+ Path to a client certificate file for TLS. |
|
| 43 |
+ |
|
| 44 |
+.PP |
|
| 45 |
+\fB\-\-client\-key\fP="" |
|
| 46 |
+ Path to a client key file for TLS. |
|
| 47 |
+ |
|
| 48 |
+.PP |
|
| 49 |
+\fB\-\-cluster\fP="" |
|
| 50 |
+ The name of the kubeconfig cluster to use |
|
| 51 |
+ |
|
| 52 |
+.PP |
|
| 53 |
+\fB\-\-config\fP="" |
|
| 54 |
+ Path to the config file to use for CLI requests. |
|
| 55 |
+ |
|
| 56 |
+.PP |
|
| 57 |
+\fB\-\-context\fP="" |
|
| 58 |
+ The name of the kubeconfig context to use |
|
| 59 |
+ |
|
| 60 |
+.PP |
|
| 61 |
+\fB\-\-google\-json\-key\fP="" |
|
| 62 |
+ The Google Cloud Platform Service Account JSON Key to use for authentication. |
|
| 63 |
+ |
|
| 64 |
+.PP |
|
| 65 |
+\fB\-\-insecure\-skip\-tls\-verify\fP=false |
|
| 66 |
+ If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. |
|
| 67 |
+ |
|
| 68 |
+.PP |
|
| 69 |
+\fB\-\-log\-flush\-frequency\fP=0 |
|
| 70 |
+ Maximum number of seconds between log flushes |
|
| 71 |
+ |
|
| 72 |
+.PP |
|
| 73 |
+\fB\-\-match\-server\-version\fP=false |
|
| 74 |
+ Require server version to match client version |
|
| 75 |
+ |
|
| 76 |
+.PP |
|
| 77 |
+\fB\-n\fP, \fB\-\-namespace\fP="" |
|
| 78 |
+ If present, the namespace scope for this CLI request. |
|
| 79 |
+ |
|
| 80 |
+.PP |
|
| 81 |
+\fB\-\-server\fP="" |
|
| 82 |
+ The address and port of the Kubernetes API server |
|
| 83 |
+ |
|
| 84 |
+.PP |
|
| 85 |
+\fB\-\-token\fP="" |
|
| 86 |
+ Bearer token for authentication to the API server. |
|
| 87 |
+ |
|
| 88 |
+.PP |
|
| 89 |
+\fB\-\-user\fP="" |
|
| 90 |
+ The name of the kubeconfig user to use |
|
| 91 |
+ |
|
| 92 |
+ |
|
| 93 |
+.SH EXAMPLE |
|
| 94 |
+.PP |
|
| 95 |
+.RS |
|
| 96 |
+ |
|
| 97 |
+.nf |
|
| 98 |
+ # Add an image pull secret to a service account to automatically use it for pulling pod images: |
|
| 99 |
+ openshift cli secrets link serviceaccount\-name pull\-secret \-\-for=pull |
|
| 100 |
+ |
|
| 101 |
+ # Add an image pull secret to a service account to automatically use it for both pulling and pushing build images: |
|
| 102 |
+ openshift cli secrets link builder builder\-image\-secret \-\-for=pull,mount |
|
| 103 |
+ |
|
| 104 |
+ # If the cluster's serviceAccountConfig is operating with limitSecretReferences: True, secrets must be added to the pod's service account whitelist in order to be available to the pod: |
|
| 105 |
+ openshift cli secrets link pod\-sa pod\-secret |
|
| 106 |
+ |
|
| 107 |
+.fi |
|
| 108 |
+.RE |
|
| 109 |
+ |
|
| 110 |
+ |
|
| 111 |
+.SH SEE ALSO |
|
| 112 |
+.PP |
|
| 113 |
+\fBopenshift\-cli\-secrets(1)\fP, |
|
| 114 |
+ |
|
| 115 |
+ |
|
| 116 |
+.SH HISTORY |
|
| 117 |
+.PP |
|
| 118 |
+June 2016, Ported from the Kubernetes man\-doc generator |
| 0 | 119 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,107 @@ |
| 0 |
+.TH "OPENSHIFT CLI SECRETS" "1" " Openshift CLI User Manuals" "Openshift" "June 2016" "" |
|
| 1 |
+ |
|
| 2 |
+ |
|
| 3 |
+.SH NAME |
|
| 4 |
+.PP |
|
| 5 |
+openshift cli secrets unlink \- Detach secrets from a ServiceAccount |
|
| 6 |
+ |
|
| 7 |
+ |
|
| 8 |
+.SH SYNOPSIS |
|
| 9 |
+.PP |
|
| 10 |
+\fBopenshift cli secrets unlink\fP [OPTIONS] |
|
| 11 |
+ |
|
| 12 |
+ |
|
| 13 |
+.SH DESCRIPTION |
|
| 14 |
+.PP |
|
| 15 |
+Unlink (detach) secrets from a service account |
|
| 16 |
+ |
|
| 17 |
+.PP |
|
| 18 |
+If a secret is no longer valid for a pod, build or image pull, you may unlink it from a service account. |
|
| 19 |
+ |
|
| 20 |
+ |
|
| 21 |
+.SH OPTIONS INHERITED FROM PARENT COMMANDS |
|
| 22 |
+.PP |
|
| 23 |
+\fB\-\-api\-version\fP="" |
|
| 24 |
+ DEPRECATED: The API version to use when talking to the server |
|
| 25 |
+ |
|
| 26 |
+.PP |
|
| 27 |
+\fB\-\-as\fP="" |
|
| 28 |
+ Username to impersonate for the operation. |
|
| 29 |
+ |
|
| 30 |
+.PP |
|
| 31 |
+\fB\-\-certificate\-authority\fP="" |
|
| 32 |
+ Path to a cert. file for the certificate authority. |
|
| 33 |
+ |
|
| 34 |
+.PP |
|
| 35 |
+\fB\-\-client\-certificate\fP="" |
|
| 36 |
+ Path to a client certificate file for TLS. |
|
| 37 |
+ |
|
| 38 |
+.PP |
|
| 39 |
+\fB\-\-client\-key\fP="" |
|
| 40 |
+ Path to a client key file for TLS. |
|
| 41 |
+ |
|
| 42 |
+.PP |
|
| 43 |
+\fB\-\-cluster\fP="" |
|
| 44 |
+ The name of the kubeconfig cluster to use |
|
| 45 |
+ |
|
| 46 |
+.PP |
|
| 47 |
+\fB\-\-config\fP="" |
|
| 48 |
+ Path to the config file to use for CLI requests. |
|
| 49 |
+ |
|
| 50 |
+.PP |
|
| 51 |
+\fB\-\-context\fP="" |
|
| 52 |
+ The name of the kubeconfig context to use |
|
| 53 |
+ |
|
| 54 |
+.PP |
|
| 55 |
+\fB\-\-google\-json\-key\fP="" |
|
| 56 |
+ The Google Cloud Platform Service Account JSON Key to use for authentication. |
|
| 57 |
+ |
|
| 58 |
+.PP |
|
| 59 |
+\fB\-\-insecure\-skip\-tls\-verify\fP=false |
|
| 60 |
+ If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. |
|
| 61 |
+ |
|
| 62 |
+.PP |
|
| 63 |
+\fB\-\-log\-flush\-frequency\fP=0 |
|
| 64 |
+ Maximum number of seconds between log flushes |
|
| 65 |
+ |
|
| 66 |
+.PP |
|
| 67 |
+\fB\-\-match\-server\-version\fP=false |
|
| 68 |
+ Require server version to match client version |
|
| 69 |
+ |
|
| 70 |
+.PP |
|
| 71 |
+\fB\-n\fP, \fB\-\-namespace\fP="" |
|
| 72 |
+ If present, the namespace scope for this CLI request. |
|
| 73 |
+ |
|
| 74 |
+.PP |
|
| 75 |
+\fB\-\-server\fP="" |
|
| 76 |
+ The address and port of the Kubernetes API server |
|
| 77 |
+ |
|
| 78 |
+.PP |
|
| 79 |
+\fB\-\-token\fP="" |
|
| 80 |
+ Bearer token for authentication to the API server. |
|
| 81 |
+ |
|
| 82 |
+.PP |
|
| 83 |
+\fB\-\-user\fP="" |
|
| 84 |
+ The name of the kubeconfig user to use |
|
| 85 |
+ |
|
| 86 |
+ |
|
| 87 |
+.SH EXAMPLE |
|
| 88 |
+.PP |
|
| 89 |
+.RS |
|
| 90 |
+ |
|
| 91 |
+.nf |
|
| 92 |
+ # Unlink a secret currently associated with a service account: |
|
| 93 |
+openshift cli secrets unlink serviceaccount\-name secret\-name another\-secret\-name ... |
|
| 94 |
+ |
|
| 95 |
+.fi |
|
| 96 |
+.RE |
|
| 97 |
+ |
|
| 98 |
+ |
|
| 99 |
+.SH SEE ALSO |
|
| 100 |
+.PP |
|
| 101 |
+\fBopenshift\-cli\-secrets(1)\fP, |
|
| 102 |
+ |
|
| 103 |
+ |
|
| 104 |
+.SH HISTORY |
|
| 105 |
+.PP |
|
| 106 |
+June 2016, Ported from the Kubernetes man\-doc generator |
| ... | ... |
@@ -89,7 +89,7 @@ Docker registries. |
| 89 | 89 |
|
| 90 | 90 |
.SH SEE ALSO |
| 91 | 91 |
.PP |
| 92 |
-\fBopenshift\-cli(1)\fP, \fBopenshift\-cli\-secrets\-new(1)\fP, \fBopenshift\-cli\-secrets\-new\-dockercfg(1)\fP, \fBopenshift\-cli\-secrets\-new\-basicauth(1)\fP, \fBopenshift\-cli\-secrets\-new\-sshauth(1)\fP, \fBopenshift\-cli\-secrets\-add(1)\fP, |
|
| 92 |
+\fBopenshift\-cli(1)\fP, \fBopenshift\-cli\-secrets\-new(1)\fP, \fBopenshift\-cli\-secrets\-new\-dockercfg(1)\fP, \fBopenshift\-cli\-secrets\-new\-basicauth(1)\fP, \fBopenshift\-cli\-secrets\-new\-sshauth(1)\fP, \fBopenshift\-cli\-secrets\-link(1)\fP, \fBopenshift\-cli\-secrets\-unlink(1)\fP, \fBopenshift\-cli\-secrets\-add(1)\fP, |
|
| 93 | 93 |
|
| 94 | 94 |
|
| 95 | 95 |
.SH HISTORY |
| ... | ... |
@@ -87,6 +87,8 @@ func NewCommandCLI(name, fullName string, in io.Reader, out, errout io.Writer) * |
| 87 | 87 |
f := clientcmd.New(cmds.PersistentFlags()) |
| 88 | 88 |
|
| 89 | 89 |
loginCmd := cmd.NewCmdLogin(fullName, f, in, out) |
| 90 |
+ secretcmds := secrets.NewCmdSecrets(secrets.SecretsRecommendedName, fullName+" "+secrets.SecretsRecommendedName, f, in, out, fullName+" edit") |
|
| 91 |
+ |
|
| 90 | 92 |
groups := templates.CommandGroups{
|
| 91 | 93 |
{
|
| 92 | 94 |
Message: "Basic Commands:", |
| ... | ... |
@@ -128,7 +130,7 @@ func NewCommandCLI(name, fullName string, in io.Reader, out, errout io.Writer) * |
| 128 | 128 |
cmd.NewCmdDelete(fullName, f, out), |
| 129 | 129 |
cmd.NewCmdScale(fullName, f, out), |
| 130 | 130 |
cmd.NewCmdAutoscale(fullName, f, out), |
| 131 |
- secrets.NewCmdSecrets(secrets.SecretsRecommendedName, fullName+" "+secrets.SecretsRecommendedName, f, in, out, fullName+" edit"), |
|
| 131 |
+ secretcmds, |
|
| 132 | 132 |
sa.NewCmdServiceAccounts(sa.ServiceAccountsRecommendedName, fullName+" "+sa.ServiceAccountsRecommendedName, f, out), |
| 133 | 133 |
}, |
| 134 | 134 |
}, |
| ... | ... |
@@ -180,6 +182,7 @@ func NewCommandCLI(name, fullName string, in io.Reader, out, errout io.Writer) * |
| 180 | 180 |
moved(fullName, "set env", cmds, set.NewCmdEnv(fullName, f, in, out)), |
| 181 | 181 |
moved(fullName, "set volume", cmds, set.NewCmdVolume(fullName, f, out, errout)), |
| 182 | 182 |
moved(fullName, "logs", cmds, cmd.NewCmdBuildLogs(fullName, f, out)), |
| 183 |
+ moved(fullName, "secrets link", secretcmds, secrets.NewCmdLinkSecret("add", fullName, f.Factory, out)),
|
|
| 183 | 184 |
} |
| 184 | 185 |
|
| 185 | 186 |
changeSharedFlagDefaults(cmds) |
| 186 | 187 |
deleted file mode 100644 |
| ... | ... |
@@ -1,274 +0,0 @@ |
| 1 |
-package secrets |
|
| 2 |
- |
|
| 3 |
-import ( |
|
| 4 |
- "errors" |
|
| 5 |
- "fmt" |
|
| 6 |
- "io" |
|
| 7 |
- "io/ioutil" |
|
| 8 |
- "strings" |
|
| 9 |
- |
|
| 10 |
- kapi "k8s.io/kubernetes/pkg/api" |
|
| 11 |
- "k8s.io/kubernetes/pkg/api/meta" |
|
| 12 |
- client "k8s.io/kubernetes/pkg/client/unversioned" |
|
| 13 |
- kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" |
|
| 14 |
- "k8s.io/kubernetes/pkg/kubectl/resource" |
|
| 15 |
- "k8s.io/kubernetes/pkg/runtime" |
|
| 16 |
- "k8s.io/kubernetes/pkg/util/sets" |
|
| 17 |
- |
|
| 18 |
- "github.com/spf13/cobra" |
|
| 19 |
-) |
|
| 20 |
- |
|
| 21 |
-const ( |
|
| 22 |
- AddSecretRecommendedName = "add" |
|
| 23 |
- |
|
| 24 |
- // TODO: move to examples |
|
| 25 |
- addSecretLong = ` |
|
| 26 |
-Add secrets to a ServiceAccount |
|
| 27 |
- |
|
| 28 |
-After you have created a secret, you probably want to make use of that secret inside of a pod, for a build, or as an image pull secret. In order to do that, you must add your secret to a service account.` |
|
| 29 |
- |
|
| 30 |
- addSecretExample = ` // To use your secret inside of a pod or as a push, pull, or source secret for a build, you must add a 'mount' secret to your service account like this: |
|
| 31 |
- %[1]s serviceaccount/sa-name secrets/secret-name secrets/another-secret-name |
|
| 32 |
- |
|
| 33 |
- // To use your secret as an image pull secret, you must add a 'pull' secret to your service account like this: |
|
| 34 |
- %[1]s serviceaccount/sa-name secrets/secret-name --for=pull |
|
| 35 |
- |
|
| 36 |
- // To use your secret for image pulls or inside a pod: |
|
| 37 |
- %[1]s serviceaccount/sa-name secrets/secret-name --for=pull,mount` |
|
| 38 |
-) |
|
| 39 |
- |
|
| 40 |
-type AddSecretOptions struct {
|
|
| 41 |
- TargetName string |
|
| 42 |
- SecretNames []string |
|
| 43 |
- |
|
| 44 |
- ForMount bool |
|
| 45 |
- ForPull bool |
|
| 46 |
- |
|
| 47 |
- Namespace string |
|
| 48 |
- |
|
| 49 |
- Mapper meta.RESTMapper |
|
| 50 |
- Typer runtime.ObjectTyper |
|
| 51 |
- ClientMapper resource.ClientMapper |
|
| 52 |
- ClientInterface client.Interface |
|
| 53 |
- |
|
| 54 |
- Out io.Writer |
|
| 55 |
-} |
|
| 56 |
- |
|
| 57 |
-// NewCmdAddSecret creates a command object for adding a secret reference to a service account |
|
| 58 |
-func NewCmdAddSecret(name, fullName string, f *kcmdutil.Factory, out io.Writer) *cobra.Command {
|
|
| 59 |
- o := &AddSecretOptions{Out: out}
|
|
| 60 |
- var typeFlags []string |
|
| 61 |
- |
|
| 62 |
- cmd := &cobra.Command{
|
|
| 63 |
- Use: fmt.Sprintf("%s serviceaccounts/sa-name secrets/secret-name [secrets/another-secret-name]...", name),
|
|
| 64 |
- Short: "Add secrets to a ServiceAccount", |
|
| 65 |
- Long: addSecretLong, |
|
| 66 |
- Example: fmt.Sprintf(addSecretExample, fullName), |
|
| 67 |
- Run: func(c *cobra.Command, args []string) {
|
|
| 68 |
- if err := o.Complete(f, args, typeFlags); err != nil {
|
|
| 69 |
- kcmdutil.CheckErr(kcmdutil.UsageError(c, err.Error())) |
|
| 70 |
- } |
|
| 71 |
- |
|
| 72 |
- if err := o.Validate(); err != nil {
|
|
| 73 |
- kcmdutil.CheckErr(kcmdutil.UsageError(c, err.Error())) |
|
| 74 |
- } |
|
| 75 |
- |
|
| 76 |
- if err := o.AddSecrets(); err != nil {
|
|
| 77 |
- kcmdutil.CheckErr(err) |
|
| 78 |
- } |
|
| 79 |
- |
|
| 80 |
- }, |
|
| 81 |
- } |
|
| 82 |
- |
|
| 83 |
- cmd.Flags().StringSliceVar(&typeFlags, "for", []string{"mount"}, "type of secret to add: mount or pull")
|
|
| 84 |
- |
|
| 85 |
- return cmd |
|
| 86 |
-} |
|
| 87 |
- |
|
| 88 |
-func (o *AddSecretOptions) Complete(f *kcmdutil.Factory, args []string, typeFlags []string) error {
|
|
| 89 |
- if len(args) < 2 {
|
|
| 90 |
- return errors.New("must have service account name and at least one secret name")
|
|
| 91 |
- } |
|
| 92 |
- o.TargetName = args[0] |
|
| 93 |
- o.SecretNames = args[1:] |
|
| 94 |
- |
|
| 95 |
- if len(typeFlags) == 0 {
|
|
| 96 |
- o.ForMount = true |
|
| 97 |
- } else {
|
|
| 98 |
- for _, flag := range typeFlags {
|
|
| 99 |
- loweredValue := strings.ToLower(flag) |
|
| 100 |
- switch loweredValue {
|
|
| 101 |
- case "pull": |
|
| 102 |
- o.ForPull = true |
|
| 103 |
- case "mount": |
|
| 104 |
- o.ForMount = true |
|
| 105 |
- default: |
|
| 106 |
- return fmt.Errorf("unknown for: %v", flag)
|
|
| 107 |
- } |
|
| 108 |
- } |
|
| 109 |
- } |
|
| 110 |
- |
|
| 111 |
- var err error |
|
| 112 |
- o.ClientInterface, err = f.Client() |
|
| 113 |
- if err != nil {
|
|
| 114 |
- return err |
|
| 115 |
- } |
|
| 116 |
- |
|
| 117 |
- o.Namespace, _, err = f.DefaultNamespace() |
|
| 118 |
- if err != nil {
|
|
| 119 |
- return err |
|
| 120 |
- } |
|
| 121 |
- |
|
| 122 |
- o.Mapper, o.Typer = f.Object(false) |
|
| 123 |
- o.ClientMapper = resource.ClientMapperFunc(f.ClientForMapping) |
|
| 124 |
- |
|
| 125 |
- return nil |
|
| 126 |
-} |
|
| 127 |
- |
|
| 128 |
-func (o AddSecretOptions) Validate() error {
|
|
| 129 |
- if len(o.TargetName) == 0 {
|
|
| 130 |
- return errors.New("service account name must be present")
|
|
| 131 |
- } |
|
| 132 |
- if len(o.SecretNames) == 0 {
|
|
| 133 |
- return errors.New("secret name must be present")
|
|
| 134 |
- } |
|
| 135 |
- if !o.ForPull && !o.ForMount {
|
|
| 136 |
- return errors.New("for must be present")
|
|
| 137 |
- } |
|
| 138 |
- if o.Mapper == nil {
|
|
| 139 |
- return errors.New("Mapper must be present")
|
|
| 140 |
- } |
|
| 141 |
- if o.Typer == nil {
|
|
| 142 |
- return errors.New("Typer must be present")
|
|
| 143 |
- } |
|
| 144 |
- if o.ClientMapper == nil {
|
|
| 145 |
- return errors.New("ClientMapper must be present")
|
|
| 146 |
- } |
|
| 147 |
- if o.ClientInterface == nil {
|
|
| 148 |
- return errors.New("ClientInterface must be present")
|
|
| 149 |
- } |
|
| 150 |
- |
|
| 151 |
- return nil |
|
| 152 |
-} |
|
| 153 |
- |
|
| 154 |
-func (o AddSecretOptions) AddSecrets() error {
|
|
| 155 |
- r := resource.NewBuilder(o.Mapper, o.Typer, o.ClientMapper, kapi.Codecs.UniversalDecoder()). |
|
| 156 |
- NamespaceParam(o.Namespace). |
|
| 157 |
- ResourceNames("serviceaccounts", o.TargetName).
|
|
| 158 |
- SingleResourceType(). |
|
| 159 |
- Do() |
|
| 160 |
- if r.Err() != nil {
|
|
| 161 |
- return r.Err() |
|
| 162 |
- } |
|
| 163 |
- obj, err := r.Object() |
|
| 164 |
- if err != nil {
|
|
| 165 |
- return err |
|
| 166 |
- } |
|
| 167 |
- |
|
| 168 |
- switch t := obj.(type) {
|
|
| 169 |
- case *kapi.ServiceAccount: |
|
| 170 |
- err = o.addSecretsToServiceAccount(t) |
|
| 171 |
- if err != nil {
|
|
| 172 |
- return err |
|
| 173 |
- } |
|
| 174 |
- default: |
|
| 175 |
- return fmt.Errorf("unhandled object: %#v", t)
|
|
| 176 |
- } |
|
| 177 |
- |
|
| 178 |
- return nil |
|
| 179 |
-} |
|
| 180 |
- |
|
| 181 |
-// TODO: when Secrets in kapi.ServiceAccount get changed to MountSecrets and represented by LocalObjectReferences, this can be |
|
| 182 |
-// refactored to reuse the addition code better |
|
| 183 |
-// addSecretsToServiceAccount adds secrets to the service account, either as pull secrets, mount secrets, or both. |
|
| 184 |
-func (o AddSecretOptions) addSecretsToServiceAccount(serviceaccount *kapi.ServiceAccount) error {
|
|
| 185 |
- updated := false |
|
| 186 |
- newSecrets, err := o.getSecrets() |
|
| 187 |
- if err != nil {
|
|
| 188 |
- return err |
|
| 189 |
- } |
|
| 190 |
- newSecretNames := getSecretNames(newSecrets) |
|
| 191 |
- |
|
| 192 |
- if o.ForMount {
|
|
| 193 |
- currentSecrets := getMountSecretNames(serviceaccount) |
|
| 194 |
- secretsToAdd := newSecretNames.Difference(currentSecrets) |
|
| 195 |
- for _, secretName := range secretsToAdd.List() {
|
|
| 196 |
- serviceaccount.Secrets = append(serviceaccount.Secrets, kapi.ObjectReference{Name: secretName})
|
|
| 197 |
- updated = true |
|
| 198 |
- } |
|
| 199 |
- } |
|
| 200 |
- if o.ForPull {
|
|
| 201 |
- currentSecrets := getPullSecretNames(serviceaccount) |
|
| 202 |
- secretsToAdd := newSecretNames.Difference(currentSecrets) |
|
| 203 |
- for _, secretName := range secretsToAdd.List() {
|
|
| 204 |
- serviceaccount.ImagePullSecrets = append(serviceaccount.ImagePullSecrets, kapi.LocalObjectReference{Name: secretName})
|
|
| 205 |
- updated = true |
|
| 206 |
- } |
|
| 207 |
- } |
|
| 208 |
- if updated {
|
|
| 209 |
- _, err = o.ClientInterface.ServiceAccounts(o.Namespace).Update(serviceaccount) |
|
| 210 |
- return err |
|
| 211 |
- } |
|
| 212 |
- return nil |
|
| 213 |
-} |
|
| 214 |
- |
|
| 215 |
-func (o AddSecretOptions) getSecrets() ([]*kapi.Secret, error) {
|
|
| 216 |
- r := resource.NewBuilder(o.Mapper, o.Typer, o.ClientMapper, kapi.Codecs.UniversalDecoder()). |
|
| 217 |
- NamespaceParam(o.Namespace). |
|
| 218 |
- ResourceNames("secrets", o.SecretNames...).
|
|
| 219 |
- SingleResourceType(). |
|
| 220 |
- Do() |
|
| 221 |
- if r.Err() != nil {
|
|
| 222 |
- return nil, r.Err() |
|
| 223 |
- } |
|
| 224 |
- infos, err := r.Infos() |
|
| 225 |
- if err != nil {
|
|
| 226 |
- return nil, err |
|
| 227 |
- } |
|
| 228 |
- |
|
| 229 |
- secrets := []*kapi.Secret{}
|
|
| 230 |
- for i := range infos {
|
|
| 231 |
- info := infos[i] |
|
| 232 |
- |
|
| 233 |
- switch t := info.Object.(type) {
|
|
| 234 |
- case *kapi.Secret: |
|
| 235 |
- secrets = append(secrets, t) |
|
| 236 |
- default: |
|
| 237 |
- return nil, fmt.Errorf("unhandled object: %#v", t)
|
|
| 238 |
- } |
|
| 239 |
- } |
|
| 240 |
- |
|
| 241 |
- return secrets, nil |
|
| 242 |
-} |
|
| 243 |
- |
|
| 244 |
-func getSecretNames(secrets []*kapi.Secret) sets.String {
|
|
| 245 |
- names := sets.String{}
|
|
| 246 |
- for _, secret := range secrets {
|
|
| 247 |
- names.Insert(secret.Name) |
|
| 248 |
- } |
|
| 249 |
- return names |
|
| 250 |
-} |
|
| 251 |
- |
|
| 252 |
-func getMountSecretNames(serviceaccount *kapi.ServiceAccount) sets.String {
|
|
| 253 |
- names := sets.String{}
|
|
| 254 |
- for _, secret := range serviceaccount.Secrets {
|
|
| 255 |
- names.Insert(secret.Name) |
|
| 256 |
- } |
|
| 257 |
- return names |
|
| 258 |
-} |
|
| 259 |
- |
|
| 260 |
-func getPullSecretNames(serviceaccount *kapi.ServiceAccount) sets.String {
|
|
| 261 |
- names := sets.String{}
|
|
| 262 |
- for _, secret := range serviceaccount.ImagePullSecrets {
|
|
| 263 |
- names.Insert(secret.Name) |
|
| 264 |
- } |
|
| 265 |
- return names |
|
| 266 |
-} |
|
| 267 |
- |
|
| 268 |
-func (o AddSecretOptions) GetOut() io.Writer {
|
|
| 269 |
- if o.Out == nil {
|
|
| 270 |
- return ioutil.Discard |
|
| 271 |
- } |
|
| 272 |
- |
|
| 273 |
- return o.Out |
|
| 274 |
-} |
| 275 | 1 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,161 @@ |
| 0 |
+package secrets |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "errors" |
|
| 4 |
+ "fmt" |
|
| 5 |
+ "io" |
|
| 6 |
+ "strings" |
|
| 7 |
+ |
|
| 8 |
+ kapi "k8s.io/kubernetes/pkg/api" |
|
| 9 |
+ kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" |
|
| 10 |
+ |
|
| 11 |
+ "github.com/spf13/cobra" |
|
| 12 |
+) |
|
| 13 |
+ |
|
| 14 |
+const ( |
|
| 15 |
+ // LinkSecretRecommendedName `oc secrets link` |
|
| 16 |
+ LinkSecretRecommendedName = "link" |
|
| 17 |
+ |
|
| 18 |
+ // TODO: move to examples |
|
| 19 |
+ linkSecretLong = ` |
|
| 20 |
+Link secrets to a service account |
|
| 21 |
+ |
|
| 22 |
+Linking a secret enables a service account to automatically use that secret for some forms of authentication` |
|
| 23 |
+ |
|
| 24 |
+ linkSecretExample = ` # Add an image pull secret to a service account to automatically use it for pulling pod images: |
|
| 25 |
+ %[1]s serviceaccount-name pull-secret --for=pull |
|
| 26 |
+ |
|
| 27 |
+ # Add an image pull secret to a service account to automatically use it for both pulling and pushing build images: |
|
| 28 |
+ %[1]s builder builder-image-secret --for=pull,mount |
|
| 29 |
+ |
|
| 30 |
+ # If the cluster's serviceAccountConfig is operating with limitSecretReferences: True, secrets must be added to the pod's service account whitelist in order to be available to the pod: |
|
| 31 |
+ %[1]s pod-sa pod-secret` |
|
| 32 |
+) |
|
| 33 |
+ |
|
| 34 |
+type LinkSecretOptions struct {
|
|
| 35 |
+ SecretOptions |
|
| 36 |
+ |
|
| 37 |
+ ForMount bool |
|
| 38 |
+ ForPull bool |
|
| 39 |
+ |
|
| 40 |
+ typeFlags []string |
|
| 41 |
+} |
|
| 42 |
+ |
|
| 43 |
+// NewCmdLinkSecret creates a command object for linking a secret reference to a service account |
|
| 44 |
+func NewCmdLinkSecret(name, fullName string, f *kcmdutil.Factory, out io.Writer) *cobra.Command {
|
|
| 45 |
+ o := &LinkSecretOptions{SecretOptions{Out: out}, false, false, nil}
|
|
| 46 |
+ |
|
| 47 |
+ cmd := &cobra.Command{
|
|
| 48 |
+ Use: fmt.Sprintf("%s serviceaccounts-name secret-name [another-secret-name]...", name),
|
|
| 49 |
+ Short: "Link secrets to a ServiceAccount", |
|
| 50 |
+ Long: linkSecretLong, |
|
| 51 |
+ Example: fmt.Sprintf(linkSecretExample, fullName), |
|
| 52 |
+ Run: func(c *cobra.Command, args []string) {
|
|
| 53 |
+ if err := o.Complete(f, args); err != nil {
|
|
| 54 |
+ kcmdutil.CheckErr(kcmdutil.UsageError(c, err.Error())) |
|
| 55 |
+ } |
|
| 56 |
+ |
|
| 57 |
+ if err := o.Validate(); err != nil {
|
|
| 58 |
+ kcmdutil.CheckErr(kcmdutil.UsageError(c, err.Error())) |
|
| 59 |
+ } |
|
| 60 |
+ |
|
| 61 |
+ if err := o.LinkSecrets(); err != nil {
|
|
| 62 |
+ kcmdutil.CheckErr(err) |
|
| 63 |
+ } |
|
| 64 |
+ |
|
| 65 |
+ }, |
|
| 66 |
+ } |
|
| 67 |
+ |
|
| 68 |
+ cmd.Flags().StringSliceVar(&o.typeFlags, "for", []string{"mount"}, "type of secret to link: mount or pull")
|
|
| 69 |
+ |
|
| 70 |
+ return cmd |
|
| 71 |
+} |
|
| 72 |
+ |
|
| 73 |
+func (o *LinkSecretOptions) Complete(f *kcmdutil.Factory, args []string) error {
|
|
| 74 |
+ if err := o.SecretOptions.Complete(f, args); err != nil {
|
|
| 75 |
+ return err |
|
| 76 |
+ } |
|
| 77 |
+ |
|
| 78 |
+ if len(o.typeFlags) == 0 {
|
|
| 79 |
+ o.ForMount = true |
|
| 80 |
+ } else {
|
|
| 81 |
+ for _, flag := range o.typeFlags {
|
|
| 82 |
+ loweredValue := strings.ToLower(flag) |
|
| 83 |
+ switch loweredValue {
|
|
| 84 |
+ case "pull": |
|
| 85 |
+ o.ForPull = true |
|
| 86 |
+ case "mount": |
|
| 87 |
+ o.ForMount = true |
|
| 88 |
+ default: |
|
| 89 |
+ return fmt.Errorf("unknown for: %v", flag)
|
|
| 90 |
+ } |
|
| 91 |
+ } |
|
| 92 |
+ } |
|
| 93 |
+ |
|
| 94 |
+ return nil |
|
| 95 |
+} |
|
| 96 |
+ |
|
| 97 |
+func (o LinkSecretOptions) Validate() error {
|
|
| 98 |
+ if err := o.SecretOptions.Validate(); err != nil {
|
|
| 99 |
+ return err |
|
| 100 |
+ } |
|
| 101 |
+ |
|
| 102 |
+ if !o.ForPull && !o.ForMount {
|
|
| 103 |
+ return errors.New("for must be present")
|
|
| 104 |
+ } |
|
| 105 |
+ |
|
| 106 |
+ return nil |
|
| 107 |
+} |
|
| 108 |
+ |
|
| 109 |
+func (o LinkSecretOptions) LinkSecrets() error {
|
|
| 110 |
+ serviceaccount, err := o.GetServiceAccount() |
|
| 111 |
+ if err != nil {
|
|
| 112 |
+ return err |
|
| 113 |
+ } |
|
| 114 |
+ |
|
| 115 |
+ err = o.linkSecretsToServiceAccount(serviceaccount) |
|
| 116 |
+ if err != nil {
|
|
| 117 |
+ return err |
|
| 118 |
+ } |
|
| 119 |
+ |
|
| 120 |
+ return nil |
|
| 121 |
+} |
|
| 122 |
+ |
|
| 123 |
+// TODO: when Secrets in kapi.ServiceAccount get changed to MountSecrets and represented by LocalObjectReferences, this can be |
|
| 124 |
+// refactored to reuse the addition code better |
|
| 125 |
+// linkSecretsToServiceAccount links secrets to the service account, either as pull secrets, mount secrets, or both. |
|
| 126 |
+func (o LinkSecretOptions) linkSecretsToServiceAccount(serviceaccount *kapi.ServiceAccount) error {
|
|
| 127 |
+ updated := false |
|
| 128 |
+ newSecrets, failLater, err := o.GetSecrets() |
|
| 129 |
+ if err != nil {
|
|
| 130 |
+ return err |
|
| 131 |
+ } |
|
| 132 |
+ newSecretNames := o.GetSecretNames(newSecrets) |
|
| 133 |
+ |
|
| 134 |
+ if o.ForMount {
|
|
| 135 |
+ currentSecrets := o.GetMountSecretNames(serviceaccount) |
|
| 136 |
+ secretsToLink := newSecretNames.Difference(currentSecrets) |
|
| 137 |
+ for _, secretName := range secretsToLink.List() {
|
|
| 138 |
+ serviceaccount.Secrets = append(serviceaccount.Secrets, kapi.ObjectReference{Name: secretName})
|
|
| 139 |
+ updated = true |
|
| 140 |
+ } |
|
| 141 |
+ } |
|
| 142 |
+ if o.ForPull {
|
|
| 143 |
+ currentSecrets := o.GetPullSecretNames(serviceaccount) |
|
| 144 |
+ secretsToLink := newSecretNames.Difference(currentSecrets) |
|
| 145 |
+ for _, secretName := range secretsToLink.List() {
|
|
| 146 |
+ serviceaccount.ImagePullSecrets = append(serviceaccount.ImagePullSecrets, kapi.LocalObjectReference{Name: secretName})
|
|
| 147 |
+ updated = true |
|
| 148 |
+ } |
|
| 149 |
+ } |
|
| 150 |
+ if updated {
|
|
| 151 |
+ _, err = o.ClientInterface.ServiceAccounts(o.Namespace).Update(serviceaccount) |
|
| 152 |
+ return err |
|
| 153 |
+ } |
|
| 154 |
+ |
|
| 155 |
+ if failLater {
|
|
| 156 |
+ return errors.New("Some secrets could not be linked")
|
|
| 157 |
+ } |
|
| 158 |
+ |
|
| 159 |
+ return nil |
|
| 160 |
+} |
| 0 | 161 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,181 @@ |
| 0 |
+package secrets |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "errors" |
|
| 4 |
+ "fmt" |
|
| 5 |
+ "io" |
|
| 6 |
+ "io/ioutil" |
|
| 7 |
+ "os" |
|
| 8 |
+ |
|
| 9 |
+ kapi "k8s.io/kubernetes/pkg/api" |
|
| 10 |
+ "k8s.io/kubernetes/pkg/api/meta" |
|
| 11 |
+ client "k8s.io/kubernetes/pkg/client/unversioned" |
|
| 12 |
+ kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" |
|
| 13 |
+ "k8s.io/kubernetes/pkg/kubectl/resource" |
|
| 14 |
+ "k8s.io/kubernetes/pkg/runtime" |
|
| 15 |
+ "k8s.io/kubernetes/pkg/util/sets" |
|
| 16 |
+) |
|
| 17 |
+ |
|
| 18 |
+// SecretOptions Structure holding state for processing secret linking and |
|
| 19 |
+// unlinking. |
|
| 20 |
+type SecretOptions struct {
|
|
| 21 |
+ TargetName string |
|
| 22 |
+ SecretNames []string |
|
| 23 |
+ typeFlags []string |
|
| 24 |
+ |
|
| 25 |
+ Namespace string |
|
| 26 |
+ |
|
| 27 |
+ Mapper meta.RESTMapper |
|
| 28 |
+ Typer runtime.ObjectTyper |
|
| 29 |
+ ClientMapper resource.ClientMapper |
|
| 30 |
+ ClientInterface client.Interface |
|
| 31 |
+ |
|
| 32 |
+ Out io.Writer |
|
| 33 |
+} |
|
| 34 |
+ |
|
| 35 |
+// Complete Parses the command line arguments and populates SecretOptions |
|
| 36 |
+func (o *SecretOptions) Complete(f *kcmdutil.Factory, args []string) error {
|
|
| 37 |
+ if len(args) < 2 {
|
|
| 38 |
+ return errors.New("must have service account name and at least one secret name")
|
|
| 39 |
+ } |
|
| 40 |
+ o.TargetName = args[0] |
|
| 41 |
+ o.SecretNames = args[1:] |
|
| 42 |
+ |
|
| 43 |
+ var err error |
|
| 44 |
+ o.ClientInterface, err = f.Client() |
|
| 45 |
+ if err != nil {
|
|
| 46 |
+ return err |
|
| 47 |
+ } |
|
| 48 |
+ |
|
| 49 |
+ o.Namespace, _, err = f.DefaultNamespace() |
|
| 50 |
+ if err != nil {
|
|
| 51 |
+ return err |
|
| 52 |
+ } |
|
| 53 |
+ |
|
| 54 |
+ o.Mapper, o.Typer = f.Object(false) |
|
| 55 |
+ o.ClientMapper = resource.ClientMapperFunc(f.ClientForMapping) |
|
| 56 |
+ |
|
| 57 |
+ return nil |
|
| 58 |
+} |
|
| 59 |
+ |
|
| 60 |
+// Validate Ensures that all arguments have appropriate values |
|
| 61 |
+func (o SecretOptions) Validate() error {
|
|
| 62 |
+ if len(o.TargetName) == 0 {
|
|
| 63 |
+ return errors.New("service account name must be present")
|
|
| 64 |
+ } |
|
| 65 |
+ if len(o.SecretNames) == 0 {
|
|
| 66 |
+ return errors.New("secret name must be present")
|
|
| 67 |
+ } |
|
| 68 |
+ if o.Mapper == nil {
|
|
| 69 |
+ return errors.New("Mapper must be present")
|
|
| 70 |
+ } |
|
| 71 |
+ if o.Typer == nil {
|
|
| 72 |
+ return errors.New("Typer must be present")
|
|
| 73 |
+ } |
|
| 74 |
+ if o.ClientMapper == nil {
|
|
| 75 |
+ return errors.New("ClientMapper must be present")
|
|
| 76 |
+ } |
|
| 77 |
+ if o.ClientInterface == nil {
|
|
| 78 |
+ return errors.New("ClientInterface must be present")
|
|
| 79 |
+ } |
|
| 80 |
+ |
|
| 81 |
+ return nil |
|
| 82 |
+} |
|
| 83 |
+ |
|
| 84 |
+// GetServiceAccount Retrieve the service account object specified by the command |
|
| 85 |
+func (o SecretOptions) GetServiceAccount() (*kapi.ServiceAccount, error) {
|
|
| 86 |
+ r := resource.NewBuilder(o.Mapper, o.Typer, o.ClientMapper, kapi.Codecs.UniversalDecoder()). |
|
| 87 |
+ NamespaceParam(o.Namespace). |
|
| 88 |
+ ResourceNames("serviceaccounts", o.TargetName).
|
|
| 89 |
+ SingleResourceType(). |
|
| 90 |
+ Do() |
|
| 91 |
+ if r.Err() != nil {
|
|
| 92 |
+ return nil, r.Err() |
|
| 93 |
+ } |
|
| 94 |
+ obj, err := r.Object() |
|
| 95 |
+ if err != nil {
|
|
| 96 |
+ return nil, err |
|
| 97 |
+ } |
|
| 98 |
+ |
|
| 99 |
+ switch t := obj.(type) {
|
|
| 100 |
+ case *kapi.ServiceAccount: |
|
| 101 |
+ return t, nil |
|
| 102 |
+ default: |
|
| 103 |
+ return nil, fmt.Errorf("unhandled object: %#v", t)
|
|
| 104 |
+ } |
|
| 105 |
+} |
|
| 106 |
+ |
|
| 107 |
+// GetSecretNames Get a list of the names of the secrets in a set of them |
|
| 108 |
+func (o SecretOptions) GetSecretNames(secrets []*kapi.Secret) sets.String {
|
|
| 109 |
+ names := sets.String{}
|
|
| 110 |
+ for _, secret := range secrets {
|
|
| 111 |
+ names.Insert(secret.Name) |
|
| 112 |
+ } |
|
| 113 |
+ return names |
|
| 114 |
+} |
|
| 115 |
+ |
|
| 116 |
+// GetMountSecretNames Get a list of the names of the mount secrets associated |
|
| 117 |
+// with a service account |
|
| 118 |
+func (o SecretOptions) GetMountSecretNames(serviceaccount *kapi.ServiceAccount) sets.String {
|
|
| 119 |
+ names := sets.String{}
|
|
| 120 |
+ for _, secret := range serviceaccount.Secrets {
|
|
| 121 |
+ names.Insert(secret.Name) |
|
| 122 |
+ } |
|
| 123 |
+ return names |
|
| 124 |
+} |
|
| 125 |
+ |
|
| 126 |
+// GetPullSecretNames Get a list of the names of the pull secrets associated |
|
| 127 |
+// with a service account. |
|
| 128 |
+func (o SecretOptions) GetPullSecretNames(serviceaccount *kapi.ServiceAccount) sets.String {
|
|
| 129 |
+ names := sets.String{}
|
|
| 130 |
+ for _, secret := range serviceaccount.ImagePullSecrets {
|
|
| 131 |
+ names.Insert(secret.Name) |
|
| 132 |
+ } |
|
| 133 |
+ return names |
|
| 134 |
+} |
|
| 135 |
+ |
|
| 136 |
+// GetOut Retrieve the output writer |
|
| 137 |
+func (o SecretOptions) GetOut() io.Writer {
|
|
| 138 |
+ if o.Out == nil {
|
|
| 139 |
+ return ioutil.Discard |
|
| 140 |
+ } |
|
| 141 |
+ |
|
| 142 |
+ return o.Out |
|
| 143 |
+} |
|
| 144 |
+ |
|
| 145 |
+// GetSecrets Return a list of secret objects in the default namespace |
|
| 146 |
+func (o SecretOptions) GetSecrets() ([]*kapi.Secret, bool, error) {
|
|
| 147 |
+ secrets := []*kapi.Secret{}
|
|
| 148 |
+ failLater := false |
|
| 149 |
+ |
|
| 150 |
+ for _, secretName := range o.SecretNames {
|
|
| 151 |
+ r := resource.NewBuilder(o.Mapper, o.Typer, o.ClientMapper, kapi.Codecs.UniversalDecoder()). |
|
| 152 |
+ NamespaceParam(o.Namespace). |
|
| 153 |
+ ResourceNames("secrets", secretName).
|
|
| 154 |
+ SingleResourceType(). |
|
| 155 |
+ Do() |
|
| 156 |
+ if r.Err() != nil {
|
|
| 157 |
+ return nil, false, r.Err() |
|
| 158 |
+ } |
|
| 159 |
+ obj, err := r.Object() |
|
| 160 |
+ if err != nil {
|
|
| 161 |
+ fmt.Fprintf(os.Stderr, "secrets \"%s\" not found\n", secretName) |
|
| 162 |
+ // Missing secrets are non-fatal but the command should not return |
|
| 163 |
+ // success. |
|
| 164 |
+ failLater = true |
|
| 165 |
+ continue |
|
| 166 |
+ } |
|
| 167 |
+ switch t := obj.(type) {
|
|
| 168 |
+ case *kapi.Secret: |
|
| 169 |
+ secrets = append(secrets, t) |
|
| 170 |
+ default: |
|
| 171 |
+ return nil, false, fmt.Errorf("unhandled object: %#v", t)
|
|
| 172 |
+ } |
|
| 173 |
+ } |
|
| 174 |
+ |
|
| 175 |
+ if len(secrets) == 0 {
|
|
| 176 |
+ return nil, false, errors.New("No valid secrets found")
|
|
| 177 |
+ } |
|
| 178 |
+ |
|
| 179 |
+ return secrets, failLater, nil |
|
| 180 |
+} |
| ... | ... |
@@ -49,7 +49,8 @@ func NewCmdSecrets(name, fullName string, f *clientcmd.Factory, reader io.Reader |
| 49 | 49 |
cmds.AddCommand(NewCmdCreateDockerConfigSecret(CreateDockerConfigSecretRecommendedName, fullName+" "+CreateDockerConfigSecretRecommendedName, f.Factory, out, newSecretFullName, ocEditFullName)) |
| 50 | 50 |
cmds.AddCommand(NewCmdCreateBasicAuthSecret(CreateBasicAuthSecretRecommendedCommandName, fullName+" "+CreateBasicAuthSecretRecommendedCommandName, f.Factory, reader, out, newSecretFullName, ocEditFullName)) |
| 51 | 51 |
cmds.AddCommand(NewCmdCreateSSHAuthSecret(CreateSSHAuthSecretRecommendedCommandName, fullName+" "+CreateSSHAuthSecretRecommendedCommandName, f.Factory, out, newSecretFullName, ocEditFullName)) |
| 52 |
- cmds.AddCommand(NewCmdAddSecret(AddSecretRecommendedName, fullName+" "+AddSecretRecommendedName, f.Factory, out)) |
|
| 52 |
+ cmds.AddCommand(NewCmdLinkSecret(LinkSecretRecommendedName, fullName+" "+LinkSecretRecommendedName, f.Factory, out)) |
|
| 53 |
+ cmds.AddCommand(NewCmdUnlinkSecret(UnlinkSecretRecommendedName, fullName+" "+UnlinkSecretRecommendedName, f.Factory, out)) |
|
| 53 | 54 |
|
| 54 | 55 |
return cmds |
| 55 | 56 |
} |
| 56 | 57 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,128 @@ |
| 0 |
+package secrets |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "errors" |
|
| 4 |
+ "fmt" |
|
| 5 |
+ "io" |
|
| 6 |
+ |
|
| 7 |
+ kapi "k8s.io/kubernetes/pkg/api" |
|
| 8 |
+ kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" |
|
| 9 |
+ |
|
| 10 |
+ "github.com/spf13/cobra" |
|
| 11 |
+) |
|
| 12 |
+ |
|
| 13 |
+const ( |
|
| 14 |
+ UnlinkSecretRecommendedName = "unlink" |
|
| 15 |
+ |
|
| 16 |
+ // TODO: move to examples |
|
| 17 |
+ unlinkSecretLong = ` |
|
| 18 |
+Unlink (detach) secrets from a service account |
|
| 19 |
+ |
|
| 20 |
+If a secret is no longer valid for a pod, build or image pull, you may unlink it from a service account.` |
|
| 21 |
+ |
|
| 22 |
+ unlinkSecretExample = ` # Unlink a secret currently associated with a service account: |
|
| 23 |
+%[1]s serviceaccount-name secret-name another-secret-name ...` |
|
| 24 |
+) |
|
| 25 |
+ |
|
| 26 |
+type UnlinkSecretOptions struct {
|
|
| 27 |
+ SecretOptions |
|
| 28 |
+} |
|
| 29 |
+ |
|
| 30 |
+// NewCmdUnlinkSecret creates a command object for detaching one or more secret references from a service account |
|
| 31 |
+func NewCmdUnlinkSecret(name, fullName string, f *kcmdutil.Factory, out io.Writer) *cobra.Command {
|
|
| 32 |
+ o := &UnlinkSecretOptions{SecretOptions{Out: out}}
|
|
| 33 |
+ |
|
| 34 |
+ cmd := &cobra.Command{
|
|
| 35 |
+ Use: fmt.Sprintf("%s serviceaccount-name secret-name [another-secret-name] ...", name),
|
|
| 36 |
+ Short: "Detach secrets from a ServiceAccount", |
|
| 37 |
+ Long: unlinkSecretLong, |
|
| 38 |
+ Example: fmt.Sprintf(unlinkSecretExample, fullName), |
|
| 39 |
+ Run: func(c *cobra.Command, args []string) {
|
|
| 40 |
+ if err := o.Complete(f, args); err != nil {
|
|
| 41 |
+ kcmdutil.CheckErr(kcmdutil.UsageError(c, err.Error())) |
|
| 42 |
+ } |
|
| 43 |
+ if err := o.Validate(); err != nil {
|
|
| 44 |
+ kcmdutil.CheckErr(kcmdutil.UsageError(c, err.Error())) |
|
| 45 |
+ } |
|
| 46 |
+ |
|
| 47 |
+ if err := o.UnlinkSecrets(); err != nil {
|
|
| 48 |
+ kcmdutil.CheckErr(err) |
|
| 49 |
+ } |
|
| 50 |
+ |
|
| 51 |
+ }, |
|
| 52 |
+ } |
|
| 53 |
+ |
|
| 54 |
+ return cmd |
|
| 55 |
+} |
|
| 56 |
+ |
|
| 57 |
+func (o UnlinkSecretOptions) UnlinkSecrets() error {
|
|
| 58 |
+ serviceaccount, err := o.GetServiceAccount() |
|
| 59 |
+ if err != nil {
|
|
| 60 |
+ return err |
|
| 61 |
+ } |
|
| 62 |
+ |
|
| 63 |
+ if err = o.unlinkSecretsFromServiceAccount(serviceaccount); err != nil {
|
|
| 64 |
+ return err |
|
| 65 |
+ } |
|
| 66 |
+ |
|
| 67 |
+ return nil |
|
| 68 |
+} |
|
| 69 |
+ |
|
| 70 |
+// unlinkSecretsFromServiceAccount detaches pull and mount secrets from the service account. |
|
| 71 |
+func (o UnlinkSecretOptions) unlinkSecretsFromServiceAccount(serviceaccount *kapi.ServiceAccount) error {
|
|
| 72 |
+ // All of the requested secrets must be present in either the Mount or Pull secrets |
|
| 73 |
+ // If any of them are not present, we'll return an error and push no changes. |
|
| 74 |
+ rmSecrets, failLater, err := o.GetSecrets() |
|
| 75 |
+ if err != nil {
|
|
| 76 |
+ return err |
|
| 77 |
+ } |
|
| 78 |
+ rmSecretNames := o.GetSecretNames(rmSecrets) |
|
| 79 |
+ |
|
| 80 |
+ newMountSecrets := []kapi.ObjectReference{}
|
|
| 81 |
+ newPullSecrets := []kapi.LocalObjectReference{}
|
|
| 82 |
+ |
|
| 83 |
+ // Check the mount secrets |
|
| 84 |
+ for i := len(serviceaccount.Secrets) - 1; i >= 0; i-- {
|
|
| 85 |
+ found := false |
|
| 86 |
+ for _, secretname := range rmSecretNames.List() {
|
|
| 87 |
+ if secretname == serviceaccount.Secrets[i].Name {
|
|
| 88 |
+ found = true |
|
| 89 |
+ // Skip adding this to the updated list |
|
| 90 |
+ } |
|
| 91 |
+ } |
|
| 92 |
+ |
|
| 93 |
+ if !found {
|
|
| 94 |
+ // Copy this back in, since it doesn't match the ones we're removing |
|
| 95 |
+ newMountSecrets = append(newMountSecrets, serviceaccount.Secrets[i]) |
|
| 96 |
+ } |
|
| 97 |
+ } |
|
| 98 |
+ |
|
| 99 |
+ // Check the image pull secrets |
|
| 100 |
+ for i := len(serviceaccount.ImagePullSecrets) - 1; i >= 0; i-- {
|
|
| 101 |
+ found := false |
|
| 102 |
+ for _, secretname := range rmSecretNames.List() {
|
|
| 103 |
+ if secretname == serviceaccount.ImagePullSecrets[i].Name {
|
|
| 104 |
+ found = true |
|
| 105 |
+ // Skip adding this to the updated list |
|
| 106 |
+ } |
|
| 107 |
+ } |
|
| 108 |
+ if !found {
|
|
| 109 |
+ // Copy this back in, since it doesn't match the one we're removing |
|
| 110 |
+ newPullSecrets = append(newPullSecrets, serviceaccount.ImagePullSecrets[i]) |
|
| 111 |
+ } |
|
| 112 |
+ } |
|
| 113 |
+ |
|
| 114 |
+ // Save the updated Secret lists back to the server |
|
| 115 |
+ serviceaccount.Secrets = newMountSecrets |
|
| 116 |
+ serviceaccount.ImagePullSecrets = newPullSecrets |
|
| 117 |
+ _, err = o.ClientInterface.ServiceAccounts(o.Namespace).Update(serviceaccount) |
|
| 118 |
+ if err != nil {
|
|
| 119 |
+ return err |
|
| 120 |
+ } |
|
| 121 |
+ |
|
| 122 |
+ if failLater {
|
|
| 123 |
+ return errors.New("Some secrets could not be unlinked")
|
|
| 124 |
+ } |
|
| 125 |
+ |
|
| 126 |
+ return nil |
|
| 127 |
+} |
| ... | ... |
@@ -69,15 +69,56 @@ os::cmd::expect_success 'oc secrets new-sshauth sshauth --ssh-privatekey=$PRIVAT |
| 69 | 69 |
# check to make sure incorrect SSH private-key path fail as expected |
| 70 | 70 |
os::cmd::expect_failure_and_text 'oc secrets new-sshauth bad-file --ssh-privatekey=/bad/path' 'error: open /bad/path: no such file or directory' |
| 71 | 71 |
|
| 72 |
+# attach secrets to service account (deprecated) |
|
| 73 |
+# single secret with prefix |
|
| 74 |
+os::cmd::expect_success 'oc secrets add deployer basicauth' |
|
| 75 |
+# don't add the same secret twice |
|
| 76 |
+os::cmd::expect_success 'oc secrets add deployer basicauth sshauth' |
|
| 77 |
+# make sure we can add as as pull secret |
|
| 78 |
+os::cmd::expect_success 'oc secrets add deployer basicauth sshauth --for=pull' |
|
| 79 |
+# make sure we can add as as pull secret and mount secret at once |
|
| 80 |
+os::cmd::expect_success 'oc secrets add deployer basicauth sshauth --for=pull,mount' |
|
| 81 |
+ |
|
| 72 | 82 |
# attach secrets to service account |
| 73 | 83 |
# single secret with prefix |
| 74 |
-os::cmd::expect_success 'oc secrets add serviceaccounts/deployer secrets/basicauth' |
|
| 84 |
+os::cmd::expect_success 'oc secrets link deployer basicauth' |
|
| 75 | 85 |
# don't add the same secret twice |
| 76 |
-os::cmd::expect_success 'oc secrets add serviceaccounts/deployer secrets/basicauth secrets/sshauth' |
|
| 86 |
+os::cmd::expect_success 'oc secrets link deployer basicauth sshauth' |
|
| 77 | 87 |
# make sure we can add as as pull secret |
| 78 |
-os::cmd::expect_success 'oc secrets add serviceaccounts/deployer secrets/basicauth secrets/sshauth --for=pull' |
|
| 88 |
+os::cmd::expect_success 'oc secrets link deployer basicauth sshauth --for=pull' |
|
| 79 | 89 |
# make sure we can add as as pull secret and mount secret at once |
| 80 |
-os::cmd::expect_success 'oc secrets add serviceaccounts/deployer secrets/basicauth secrets/sshauth --for=pull,mount' |
|
| 90 |
+os::cmd::expect_success 'oc secrets link deployer basicauth sshauth --for=pull,mount' |
|
| 91 |
+ |
|
| 92 |
+# Confirm that all the linked secrets are present |
|
| 93 |
+os::cmd::expect_success 'oc get serviceaccounts/deployer -o yaml |grep -q basicauth' |
|
| 94 |
+os::cmd::expect_success 'oc get serviceaccounts/deployer -o yaml |grep -q sshauth' |
|
| 95 |
+ |
|
| 96 |
+# Remove secrets from service account |
|
| 97 |
+os::cmd::expect_success 'oc secrets unlink deployer basicauth' |
|
| 98 |
+# Confirm that the secret was removed |
|
| 99 |
+os::cmd::expect_failure 'oc get serviceaccounts/deployer -o yaml |grep -q basicauth' |
|
| 100 |
+ |
|
| 101 |
+# Re-link that secret |
|
| 102 |
+os::cmd::expect_success 'oc secrets link deployer basicauth' |
|
| 103 |
+ |
|
| 104 |
+# Removing a non-existent secret should warn but succeed and change nothing |
|
| 105 |
+os::cmd::expect_failure_and_text 'oc secrets unlink deployer foobar' 'secrets "foobar" not found' |
|
| 106 |
+ |
|
| 107 |
+# Make sure that removing an existent and non-existent secret succeeds but warns about the non-existent one |
|
| 108 |
+os::cmd::expect_failure_and_text 'oc secrets unlink deployer foobar basicauth' 'secrets "foobar" not found' |
|
| 109 |
+# Make sure that the existing secret is removed |
|
| 110 |
+os::cmd::expect_failure 'oc get serviceaccounts/deployer -o yaml |grep -q basicauth' |
|
| 111 |
+ |
|
| 112 |
+# Make sure that removing a real but unlinked secret succeeds |
|
| 113 |
+# https://github.com/openshift/origin/pull/9234#discussion_r70832486 |
|
| 114 |
+os::cmd::expect_success 'oc secrets unlink deployer basicauth' |
|
| 115 |
+ |
|
| 116 |
+# Make sure that it succeeds if *any* of the secrets are linked |
|
| 117 |
+# https://github.com/openshift/origin/pull/9234#discussion_r70832486 |
|
| 118 |
+os::cmd::expect_success 'oc secrets unlink deployer basicauth sshauth' |
|
| 119 |
+ |
|
| 120 |
+# Confirm that the linked one was removed |
|
| 121 |
+os::cmd::expect_failure 'oc get serviceaccounts/deployer -o yaml |grep -q sshauth' |
|
| 81 | 122 |
|
| 82 | 123 |
# command alias |
| 83 | 124 |
os::cmd::expect_success 'oc secret --help' |
| ... | ... |
@@ -86,6 +127,8 @@ os::cmd::expect_success 'oc secret new-dockercfg --help' |
| 86 | 86 |
os::cmd::expect_success 'oc secret new-basicauth --help' |
| 87 | 87 |
os::cmd::expect_success 'oc secret new-sshauth --help' |
| 88 | 88 |
os::cmd::expect_success 'oc secret add --help' |
| 89 |
+os::cmd::expect_success 'oc secret link --help' |
|
| 90 |
+os::cmd::expect_success 'oc secret unlink --help' |
|
| 89 | 91 |
|
| 90 | 92 |
echo "secrets: ok" |
| 91 | 93 |
os::test::junit::declare_suite_end |