diff --git a/contrib/completions/bash/oadm b/contrib/completions/bash/oadm index 36fd6b11865e..5b44561c684c 100644 --- a/contrib/completions/bash/oadm +++ b/contrib/completions/bash/oadm @@ -700,6 +700,169 @@ _oadm_ca() noun_aliases=() } +_oadm_certificate_approve() +{ + last_command="oadm_certificate_approve" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--filename=") + flags_with_completion+=("--filename") + flags_completion+=("__handle_filename_extension_flag json|yaml|yml") + two_word_flags+=("-f") + flags_with_completion+=("-f") + flags_completion+=("__handle_filename_extension_flag json|yaml|yml") + local_nonpersistent_flags+=("--filename=") + flags+=("--output=") + two_word_flags+=("-o") + local_nonpersistent_flags+=("--output=") + flags+=("--recursive") + flags+=("-R") + local_nonpersistent_flags+=("--recursive") + flags+=("--as=") + flags+=("--azure-container-registry-config=") + flags+=("--certificate-authority=") + flags_with_completion+=("--certificate-authority") + flags_completion+=("_filedir") + flags+=("--client-certificate=") + flags_with_completion+=("--client-certificate") + flags_completion+=("_filedir") + flags+=("--client-key=") + flags_with_completion+=("--client-key") + flags_completion+=("_filedir") + flags+=("--cluster=") + flags+=("--config=") + flags_with_completion+=("--config") + flags_completion+=("_filedir") + flags+=("--context=") + flags+=("--google-json-key=") + flags+=("--insecure-skip-tls-verify") + flags+=("--log-flush-frequency=") + flags+=("--loglevel=") + flags+=("--logspec=") + flags+=("--match-server-version") + flags+=("--namespace=") + two_word_flags+=("-n") + flags+=("--request-timeout=") + flags+=("--server=") + flags+=("--token=") + flags+=("--user=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_oadm_certificate_deny() +{ + last_command="oadm_certificate_deny" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--filename=") + flags_with_completion+=("--filename") + flags_completion+=("__handle_filename_extension_flag json|yaml|yml") + two_word_flags+=("-f") + flags_with_completion+=("-f") + flags_completion+=("__handle_filename_extension_flag json|yaml|yml") + local_nonpersistent_flags+=("--filename=") + flags+=("--output=") + two_word_flags+=("-o") + local_nonpersistent_flags+=("--output=") + flags+=("--recursive") + flags+=("-R") + local_nonpersistent_flags+=("--recursive") + flags+=("--as=") + flags+=("--azure-container-registry-config=") + flags+=("--certificate-authority=") + flags_with_completion+=("--certificate-authority") + flags_completion+=("_filedir") + flags+=("--client-certificate=") + flags_with_completion+=("--client-certificate") + flags_completion+=("_filedir") + flags+=("--client-key=") + flags_with_completion+=("--client-key") + flags_completion+=("_filedir") + flags+=("--cluster=") + flags+=("--config=") + flags_with_completion+=("--config") + flags_completion+=("_filedir") + flags+=("--context=") + flags+=("--google-json-key=") + flags+=("--insecure-skip-tls-verify") + flags+=("--log-flush-frequency=") + flags+=("--loglevel=") + flags+=("--logspec=") + flags+=("--match-server-version") + flags+=("--namespace=") + two_word_flags+=("-n") + flags+=("--request-timeout=") + flags+=("--server=") + flags+=("--token=") + flags+=("--user=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_oadm_certificate() +{ + last_command="oadm_certificate" + commands=() + commands+=("approve") + commands+=("deny") + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--as=") + flags+=("--azure-container-registry-config=") + flags+=("--certificate-authority=") + flags_with_completion+=("--certificate-authority") + flags_completion+=("_filedir") + flags+=("--client-certificate=") + flags_with_completion+=("--client-certificate") + flags_completion+=("_filedir") + flags+=("--client-key=") + flags_with_completion+=("--client-key") + flags_completion+=("_filedir") + flags+=("--cluster=") + flags+=("--config=") + flags_with_completion+=("--config") + flags_completion+=("_filedir") + flags+=("--context=") + flags+=("--google-json-key=") + flags+=("--insecure-skip-tls-verify") + flags+=("--log-flush-frequency=") + flags+=("--loglevel=") + flags+=("--logspec=") + flags+=("--match-server-version") + flags+=("--namespace=") + two_word_flags+=("-n") + flags+=("--request-timeout=") + flags+=("--server=") + flags+=("--token=") + flags+=("--user=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + _oadm_completion() { last_command="oadm_completion" @@ -4944,6 +5107,7 @@ _oadm() commands=() commands+=("build-chain") commands+=("ca") + commands+=("certificate") commands+=("completion") commands+=("config") commands+=("cordon") diff --git a/contrib/completions/bash/oc b/contrib/completions/bash/oc index 5f71335b0ca1..e356c96f2df5 100644 --- a/contrib/completions/bash/oc +++ b/contrib/completions/bash/oc @@ -810,6 +810,163 @@ _oc_adm_ca() noun_aliases=() } +_oc_adm_certificate_approve() +{ + last_command="oc_adm_certificate_approve" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--filename=") + flags_with_completion+=("--filename") + flags_completion+=("__handle_filename_extension_flag json|yaml|yml") + two_word_flags+=("-f") + flags_with_completion+=("-f") + flags_completion+=("__handle_filename_extension_flag json|yaml|yml") + local_nonpersistent_flags+=("--filename=") + flags+=("--output=") + two_word_flags+=("-o") + local_nonpersistent_flags+=("--output=") + flags+=("--recursive") + flags+=("-R") + local_nonpersistent_flags+=("--recursive") + flags+=("--as=") + flags+=("--certificate-authority=") + flags_with_completion+=("--certificate-authority") + flags_completion+=("_filedir") + flags+=("--client-certificate=") + flags_with_completion+=("--client-certificate") + flags_completion+=("_filedir") + flags+=("--client-key=") + flags_with_completion+=("--client-key") + flags_completion+=("_filedir") + flags+=("--cluster=") + flags+=("--config=") + flags_with_completion+=("--config") + flags_completion+=("_filedir") + flags+=("--context=") + flags+=("--insecure-skip-tls-verify") + flags+=("--log-flush-frequency=") + flags+=("--loglevel=") + flags+=("--logspec=") + flags+=("--match-server-version") + flags+=("--namespace=") + two_word_flags+=("-n") + flags+=("--request-timeout=") + flags+=("--server=") + flags+=("--token=") + flags+=("--user=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_oc_adm_certificate_deny() +{ + last_command="oc_adm_certificate_deny" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--filename=") + flags_with_completion+=("--filename") + flags_completion+=("__handle_filename_extension_flag json|yaml|yml") + two_word_flags+=("-f") + flags_with_completion+=("-f") + flags_completion+=("__handle_filename_extension_flag json|yaml|yml") + local_nonpersistent_flags+=("--filename=") + flags+=("--output=") + two_word_flags+=("-o") + local_nonpersistent_flags+=("--output=") + flags+=("--recursive") + flags+=("-R") + local_nonpersistent_flags+=("--recursive") + flags+=("--as=") + flags+=("--certificate-authority=") + flags_with_completion+=("--certificate-authority") + flags_completion+=("_filedir") + flags+=("--client-certificate=") + flags_with_completion+=("--client-certificate") + flags_completion+=("_filedir") + flags+=("--client-key=") + flags_with_completion+=("--client-key") + flags_completion+=("_filedir") + flags+=("--cluster=") + flags+=("--config=") + flags_with_completion+=("--config") + flags_completion+=("_filedir") + flags+=("--context=") + flags+=("--insecure-skip-tls-verify") + flags+=("--log-flush-frequency=") + flags+=("--loglevel=") + flags+=("--logspec=") + flags+=("--match-server-version") + flags+=("--namespace=") + two_word_flags+=("-n") + flags+=("--request-timeout=") + flags+=("--server=") + flags+=("--token=") + flags+=("--user=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_oc_adm_certificate() +{ + last_command="oc_adm_certificate" + commands=() + commands+=("approve") + commands+=("deny") + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--as=") + flags+=("--certificate-authority=") + flags_with_completion+=("--certificate-authority") + flags_completion+=("_filedir") + flags+=("--client-certificate=") + flags_with_completion+=("--client-certificate") + flags_completion+=("_filedir") + flags+=("--client-key=") + flags_with_completion+=("--client-key") + flags_completion+=("_filedir") + flags+=("--cluster=") + flags+=("--config=") + flags_with_completion+=("--config") + flags_completion+=("_filedir") + flags+=("--context=") + flags+=("--insecure-skip-tls-verify") + flags+=("--log-flush-frequency=") + flags+=("--loglevel=") + flags+=("--logspec=") + flags+=("--match-server-version") + flags+=("--namespace=") + two_word_flags+=("-n") + flags+=("--request-timeout=") + flags+=("--server=") + flags+=("--token=") + flags+=("--user=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + _oc_adm_completion() { last_command="oc_adm_completion" @@ -4857,6 +5014,7 @@ _oc_adm() commands=() commands+=("build-chain") commands+=("ca") + commands+=("certificate") commands+=("completion") commands+=("config") commands+=("cordon") @@ -5531,6 +5689,94 @@ _oc_cluster_down() noun_aliases=() } +_oc_cluster_join() +{ + last_command="oc_cluster_join" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--create-machine") + local_nonpersistent_flags+=("--create-machine") + flags+=("--docker-machine=") + local_nonpersistent_flags+=("--docker-machine=") + flags+=("--env=") + two_word_flags+=("-e") + local_nonpersistent_flags+=("--env=") + flags+=("--forward-ports") + local_nonpersistent_flags+=("--forward-ports") + flags+=("--host-config-dir=") + local_nonpersistent_flags+=("--host-config-dir=") + flags+=("--host-data-dir=") + local_nonpersistent_flags+=("--host-data-dir=") + flags+=("--host-pv-dir=") + local_nonpersistent_flags+=("--host-pv-dir=") + flags+=("--host-volumes-dir=") + local_nonpersistent_flags+=("--host-volumes-dir=") + flags+=("--http-proxy=") + local_nonpersistent_flags+=("--http-proxy=") + flags+=("--https-proxy=") + local_nonpersistent_flags+=("--https-proxy=") + flags+=("--image=") + local_nonpersistent_flags+=("--image=") + flags+=("--image-streams=") + local_nonpersistent_flags+=("--image-streams=") + flags+=("--logging") + local_nonpersistent_flags+=("--logging") + flags+=("--metrics") + local_nonpersistent_flags+=("--metrics") + flags+=("--no-proxy=") + local_nonpersistent_flags+=("--no-proxy=") + flags+=("--public-hostname=") + local_nonpersistent_flags+=("--public-hostname=") + flags+=("--routing-suffix=") + local_nonpersistent_flags+=("--routing-suffix=") + flags+=("--secret=") + local_nonpersistent_flags+=("--secret=") + flags+=("--server-loglevel=") + local_nonpersistent_flags+=("--server-loglevel=") + flags+=("--skip-registry-check") + local_nonpersistent_flags+=("--skip-registry-check") + flags+=("--use-existing-config") + local_nonpersistent_flags+=("--use-existing-config") + flags+=("--version=") + local_nonpersistent_flags+=("--version=") + flags+=("--as=") + flags+=("--certificate-authority=") + flags_with_completion+=("--certificate-authority") + flags_completion+=("_filedir") + flags+=("--client-certificate=") + flags_with_completion+=("--client-certificate") + flags_completion+=("_filedir") + flags+=("--client-key=") + flags_with_completion+=("--client-key") + flags_completion+=("_filedir") + flags+=("--cluster=") + flags+=("--config=") + flags_with_completion+=("--config") + flags_completion+=("_filedir") + flags+=("--context=") + flags+=("--insecure-skip-tls-verify") + flags+=("--log-flush-frequency=") + flags+=("--loglevel=") + flags+=("--logspec=") + flags+=("--match-server-version") + flags+=("--namespace=") + two_word_flags+=("-n") + flags+=("--request-timeout=") + flags+=("--server=") + flags+=("--token=") + flags+=("--user=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + _oc_cluster_status() { last_command="oc_cluster_status" @@ -5667,6 +5913,7 @@ _oc_cluster() last_command="oc_cluster" commands=() commands+=("down") + commands+=("join") commands+=("status") commands+=("up") diff --git a/contrib/completions/bash/openshift b/contrib/completions/bash/openshift index 4186cd164369..82b932f4e833 100644 --- a/contrib/completions/bash/openshift +++ b/contrib/completions/bash/openshift @@ -700,6 +700,169 @@ _openshift_admin_ca() noun_aliases=() } +_openshift_admin_certificate_approve() +{ + last_command="openshift_admin_certificate_approve" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--filename=") + flags_with_completion+=("--filename") + flags_completion+=("__handle_filename_extension_flag json|yaml|yml") + two_word_flags+=("-f") + flags_with_completion+=("-f") + flags_completion+=("__handle_filename_extension_flag json|yaml|yml") + local_nonpersistent_flags+=("--filename=") + flags+=("--output=") + two_word_flags+=("-o") + local_nonpersistent_flags+=("--output=") + flags+=("--recursive") + flags+=("-R") + local_nonpersistent_flags+=("--recursive") + flags+=("--as=") + flags+=("--azure-container-registry-config=") + flags+=("--certificate-authority=") + flags_with_completion+=("--certificate-authority") + flags_completion+=("_filedir") + flags+=("--client-certificate=") + flags_with_completion+=("--client-certificate") + flags_completion+=("_filedir") + flags+=("--client-key=") + flags_with_completion+=("--client-key") + flags_completion+=("_filedir") + flags+=("--cluster=") + flags+=("--config=") + flags_with_completion+=("--config") + flags_completion+=("_filedir") + flags+=("--context=") + flags+=("--google-json-key=") + flags+=("--insecure-skip-tls-verify") + flags+=("--log-flush-frequency=") + flags+=("--loglevel=") + flags+=("--logspec=") + flags+=("--match-server-version") + flags+=("--namespace=") + two_word_flags+=("-n") + flags+=("--request-timeout=") + flags+=("--server=") + flags+=("--token=") + flags+=("--user=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_openshift_admin_certificate_deny() +{ + last_command="openshift_admin_certificate_deny" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--filename=") + flags_with_completion+=("--filename") + flags_completion+=("__handle_filename_extension_flag json|yaml|yml") + two_word_flags+=("-f") + flags_with_completion+=("-f") + flags_completion+=("__handle_filename_extension_flag json|yaml|yml") + local_nonpersistent_flags+=("--filename=") + flags+=("--output=") + two_word_flags+=("-o") + local_nonpersistent_flags+=("--output=") + flags+=("--recursive") + flags+=("-R") + local_nonpersistent_flags+=("--recursive") + flags+=("--as=") + flags+=("--azure-container-registry-config=") + flags+=("--certificate-authority=") + flags_with_completion+=("--certificate-authority") + flags_completion+=("_filedir") + flags+=("--client-certificate=") + flags_with_completion+=("--client-certificate") + flags_completion+=("_filedir") + flags+=("--client-key=") + flags_with_completion+=("--client-key") + flags_completion+=("_filedir") + flags+=("--cluster=") + flags+=("--config=") + flags_with_completion+=("--config") + flags_completion+=("_filedir") + flags+=("--context=") + flags+=("--google-json-key=") + flags+=("--insecure-skip-tls-verify") + flags+=("--log-flush-frequency=") + flags+=("--loglevel=") + flags+=("--logspec=") + flags+=("--match-server-version") + flags+=("--namespace=") + two_word_flags+=("-n") + flags+=("--request-timeout=") + flags+=("--server=") + flags+=("--token=") + flags+=("--user=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_openshift_admin_certificate() +{ + last_command="openshift_admin_certificate" + commands=() + commands+=("approve") + commands+=("deny") + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--as=") + flags+=("--azure-container-registry-config=") + flags+=("--certificate-authority=") + flags_with_completion+=("--certificate-authority") + flags_completion+=("_filedir") + flags+=("--client-certificate=") + flags_with_completion+=("--client-certificate") + flags_completion+=("_filedir") + flags+=("--client-key=") + flags_with_completion+=("--client-key") + flags_completion+=("_filedir") + flags+=("--cluster=") + flags+=("--config=") + flags_with_completion+=("--config") + flags_completion+=("_filedir") + flags+=("--context=") + flags+=("--google-json-key=") + flags+=("--insecure-skip-tls-verify") + flags+=("--log-flush-frequency=") + flags+=("--loglevel=") + flags+=("--logspec=") + flags+=("--match-server-version") + flags+=("--namespace=") + two_word_flags+=("-n") + flags+=("--request-timeout=") + flags+=("--server=") + flags+=("--token=") + flags+=("--user=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + _openshift_admin_completion() { last_command="openshift_admin_completion" @@ -4899,6 +5062,7 @@ _openshift_admin() commands=() commands+=("build-chain") commands+=("ca") + commands+=("certificate") commands+=("completion") commands+=("config") commands+=("cordon") @@ -5444,6 +5608,169 @@ _openshift_cli_adm_ca() noun_aliases=() } +_openshift_cli_adm_certificate_approve() +{ + last_command="openshift_cli_adm_certificate_approve" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--filename=") + flags_with_completion+=("--filename") + flags_completion+=("__handle_filename_extension_flag json|yaml|yml") + two_word_flags+=("-f") + flags_with_completion+=("-f") + flags_completion+=("__handle_filename_extension_flag json|yaml|yml") + local_nonpersistent_flags+=("--filename=") + flags+=("--output=") + two_word_flags+=("-o") + local_nonpersistent_flags+=("--output=") + flags+=("--recursive") + flags+=("-R") + local_nonpersistent_flags+=("--recursive") + flags+=("--as=") + flags+=("--azure-container-registry-config=") + flags+=("--certificate-authority=") + flags_with_completion+=("--certificate-authority") + flags_completion+=("_filedir") + flags+=("--client-certificate=") + flags_with_completion+=("--client-certificate") + flags_completion+=("_filedir") + flags+=("--client-key=") + flags_with_completion+=("--client-key") + flags_completion+=("_filedir") + flags+=("--cluster=") + flags+=("--config=") + flags_with_completion+=("--config") + flags_completion+=("_filedir") + flags+=("--context=") + flags+=("--google-json-key=") + flags+=("--insecure-skip-tls-verify") + flags+=("--log-flush-frequency=") + flags+=("--loglevel=") + flags+=("--logspec=") + flags+=("--match-server-version") + flags+=("--namespace=") + two_word_flags+=("-n") + flags+=("--request-timeout=") + flags+=("--server=") + flags+=("--token=") + flags+=("--user=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_openshift_cli_adm_certificate_deny() +{ + last_command="openshift_cli_adm_certificate_deny" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--filename=") + flags_with_completion+=("--filename") + flags_completion+=("__handle_filename_extension_flag json|yaml|yml") + two_word_flags+=("-f") + flags_with_completion+=("-f") + flags_completion+=("__handle_filename_extension_flag json|yaml|yml") + local_nonpersistent_flags+=("--filename=") + flags+=("--output=") + two_word_flags+=("-o") + local_nonpersistent_flags+=("--output=") + flags+=("--recursive") + flags+=("-R") + local_nonpersistent_flags+=("--recursive") + flags+=("--as=") + flags+=("--azure-container-registry-config=") + flags+=("--certificate-authority=") + flags_with_completion+=("--certificate-authority") + flags_completion+=("_filedir") + flags+=("--client-certificate=") + flags_with_completion+=("--client-certificate") + flags_completion+=("_filedir") + flags+=("--client-key=") + flags_with_completion+=("--client-key") + flags_completion+=("_filedir") + flags+=("--cluster=") + flags+=("--config=") + flags_with_completion+=("--config") + flags_completion+=("_filedir") + flags+=("--context=") + flags+=("--google-json-key=") + flags+=("--insecure-skip-tls-verify") + flags+=("--log-flush-frequency=") + flags+=("--loglevel=") + flags+=("--logspec=") + flags+=("--match-server-version") + flags+=("--namespace=") + two_word_flags+=("-n") + flags+=("--request-timeout=") + flags+=("--server=") + flags+=("--token=") + flags+=("--user=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_openshift_cli_adm_certificate() +{ + last_command="openshift_cli_adm_certificate" + commands=() + commands+=("approve") + commands+=("deny") + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--as=") + flags+=("--azure-container-registry-config=") + flags+=("--certificate-authority=") + flags_with_completion+=("--certificate-authority") + flags_completion+=("_filedir") + flags+=("--client-certificate=") + flags_with_completion+=("--client-certificate") + flags_completion+=("_filedir") + flags+=("--client-key=") + flags_with_completion+=("--client-key") + flags_completion+=("_filedir") + flags+=("--cluster=") + flags+=("--config=") + flags_with_completion+=("--config") + flags_completion+=("_filedir") + flags+=("--context=") + flags+=("--google-json-key=") + flags+=("--insecure-skip-tls-verify") + flags+=("--log-flush-frequency=") + flags+=("--loglevel=") + flags+=("--logspec=") + flags+=("--match-server-version") + flags+=("--namespace=") + two_word_flags+=("-n") + flags+=("--request-timeout=") + flags+=("--server=") + flags+=("--token=") + flags+=("--user=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + _openshift_cli_adm_completion() { last_command="openshift_cli_adm_completion" @@ -9643,6 +9970,7 @@ _openshift_cli_adm() commands=() commands+=("build-chain") commands+=("ca") + commands+=("certificate") commands+=("completion") commands+=("config") commands+=("cordon") @@ -10331,6 +10659,96 @@ _openshift_cli_cluster_down() noun_aliases=() } +_openshift_cli_cluster_join() +{ + last_command="openshift_cli_cluster_join" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--create-machine") + local_nonpersistent_flags+=("--create-machine") + flags+=("--docker-machine=") + local_nonpersistent_flags+=("--docker-machine=") + flags+=("--env=") + two_word_flags+=("-e") + local_nonpersistent_flags+=("--env=") + flags+=("--forward-ports") + local_nonpersistent_flags+=("--forward-ports") + flags+=("--host-config-dir=") + local_nonpersistent_flags+=("--host-config-dir=") + flags+=("--host-data-dir=") + local_nonpersistent_flags+=("--host-data-dir=") + flags+=("--host-pv-dir=") + local_nonpersistent_flags+=("--host-pv-dir=") + flags+=("--host-volumes-dir=") + local_nonpersistent_flags+=("--host-volumes-dir=") + flags+=("--http-proxy=") + local_nonpersistent_flags+=("--http-proxy=") + flags+=("--https-proxy=") + local_nonpersistent_flags+=("--https-proxy=") + flags+=("--image=") + local_nonpersistent_flags+=("--image=") + flags+=("--image-streams=") + local_nonpersistent_flags+=("--image-streams=") + flags+=("--logging") + local_nonpersistent_flags+=("--logging") + flags+=("--metrics") + local_nonpersistent_flags+=("--metrics") + flags+=("--no-proxy=") + local_nonpersistent_flags+=("--no-proxy=") + flags+=("--public-hostname=") + local_nonpersistent_flags+=("--public-hostname=") + flags+=("--routing-suffix=") + local_nonpersistent_flags+=("--routing-suffix=") + flags+=("--secret=") + local_nonpersistent_flags+=("--secret=") + flags+=("--server-loglevel=") + local_nonpersistent_flags+=("--server-loglevel=") + flags+=("--skip-registry-check") + local_nonpersistent_flags+=("--skip-registry-check") + flags+=("--use-existing-config") + local_nonpersistent_flags+=("--use-existing-config") + flags+=("--version=") + local_nonpersistent_flags+=("--version=") + flags+=("--as=") + flags+=("--azure-container-registry-config=") + flags+=("--certificate-authority=") + flags_with_completion+=("--certificate-authority") + flags_completion+=("_filedir") + flags+=("--client-certificate=") + flags_with_completion+=("--client-certificate") + flags_completion+=("_filedir") + flags+=("--client-key=") + flags_with_completion+=("--client-key") + flags_completion+=("_filedir") + flags+=("--cluster=") + flags+=("--config=") + flags_with_completion+=("--config") + flags_completion+=("_filedir") + flags+=("--context=") + flags+=("--google-json-key=") + flags+=("--insecure-skip-tls-verify") + flags+=("--log-flush-frequency=") + flags+=("--loglevel=") + flags+=("--logspec=") + flags+=("--match-server-version") + flags+=("--namespace=") + two_word_flags+=("-n") + flags+=("--request-timeout=") + flags+=("--server=") + flags+=("--token=") + flags+=("--user=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + _openshift_cli_cluster_status() { last_command="openshift_cli_cluster_status" @@ -10471,6 +10889,7 @@ _openshift_cli_cluster() last_command="openshift_cli_cluster" commands=() commands+=("down") + commands+=("join") commands+=("status") commands+=("up") @@ -31591,6 +32010,8 @@ _openshift_start_node() flags_with_completion=() flags_completion=() + flags+=("--bootstrap") + local_nonpersistent_flags+=("--bootstrap") flags+=("--config=") flags_with_completion+=("--config") flags_completion+=("__handle_filename_extension_flag yaml|yml") diff --git a/contrib/completions/zsh/oadm b/contrib/completions/zsh/oadm index c167e0ed11e4..229848a348d9 100644 --- a/contrib/completions/zsh/oadm +++ b/contrib/completions/zsh/oadm @@ -848,6 +848,169 @@ _oadm_ca() noun_aliases=() } +_oadm_certificate_approve() +{ + last_command="oadm_certificate_approve" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--filename=") + flags_with_completion+=("--filename") + flags_completion+=("__handle_filename_extension_flag json|yaml|yml") + two_word_flags+=("-f") + flags_with_completion+=("-f") + flags_completion+=("__handle_filename_extension_flag json|yaml|yml") + local_nonpersistent_flags+=("--filename=") + flags+=("--output=") + two_word_flags+=("-o") + local_nonpersistent_flags+=("--output=") + flags+=("--recursive") + flags+=("-R") + local_nonpersistent_flags+=("--recursive") + flags+=("--as=") + flags+=("--azure-container-registry-config=") + flags+=("--certificate-authority=") + flags_with_completion+=("--certificate-authority") + flags_completion+=("_filedir") + flags+=("--client-certificate=") + flags_with_completion+=("--client-certificate") + flags_completion+=("_filedir") + flags+=("--client-key=") + flags_with_completion+=("--client-key") + flags_completion+=("_filedir") + flags+=("--cluster=") + flags+=("--config=") + flags_with_completion+=("--config") + flags_completion+=("_filedir") + flags+=("--context=") + flags+=("--google-json-key=") + flags+=("--insecure-skip-tls-verify") + flags+=("--log-flush-frequency=") + flags+=("--loglevel=") + flags+=("--logspec=") + flags+=("--match-server-version") + flags+=("--namespace=") + two_word_flags+=("-n") + flags+=("--request-timeout=") + flags+=("--server=") + flags+=("--token=") + flags+=("--user=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_oadm_certificate_deny() +{ + last_command="oadm_certificate_deny" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--filename=") + flags_with_completion+=("--filename") + flags_completion+=("__handle_filename_extension_flag json|yaml|yml") + two_word_flags+=("-f") + flags_with_completion+=("-f") + flags_completion+=("__handle_filename_extension_flag json|yaml|yml") + local_nonpersistent_flags+=("--filename=") + flags+=("--output=") + two_word_flags+=("-o") + local_nonpersistent_flags+=("--output=") + flags+=("--recursive") + flags+=("-R") + local_nonpersistent_flags+=("--recursive") + flags+=("--as=") + flags+=("--azure-container-registry-config=") + flags+=("--certificate-authority=") + flags_with_completion+=("--certificate-authority") + flags_completion+=("_filedir") + flags+=("--client-certificate=") + flags_with_completion+=("--client-certificate") + flags_completion+=("_filedir") + flags+=("--client-key=") + flags_with_completion+=("--client-key") + flags_completion+=("_filedir") + flags+=("--cluster=") + flags+=("--config=") + flags_with_completion+=("--config") + flags_completion+=("_filedir") + flags+=("--context=") + flags+=("--google-json-key=") + flags+=("--insecure-skip-tls-verify") + flags+=("--log-flush-frequency=") + flags+=("--loglevel=") + flags+=("--logspec=") + flags+=("--match-server-version") + flags+=("--namespace=") + two_word_flags+=("-n") + flags+=("--request-timeout=") + flags+=("--server=") + flags+=("--token=") + flags+=("--user=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_oadm_certificate() +{ + last_command="oadm_certificate" + commands=() + commands+=("approve") + commands+=("deny") + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--as=") + flags+=("--azure-container-registry-config=") + flags+=("--certificate-authority=") + flags_with_completion+=("--certificate-authority") + flags_completion+=("_filedir") + flags+=("--client-certificate=") + flags_with_completion+=("--client-certificate") + flags_completion+=("_filedir") + flags+=("--client-key=") + flags_with_completion+=("--client-key") + flags_completion+=("_filedir") + flags+=("--cluster=") + flags+=("--config=") + flags_with_completion+=("--config") + flags_completion+=("_filedir") + flags+=("--context=") + flags+=("--google-json-key=") + flags+=("--insecure-skip-tls-verify") + flags+=("--log-flush-frequency=") + flags+=("--loglevel=") + flags+=("--logspec=") + flags+=("--match-server-version") + flags+=("--namespace=") + two_word_flags+=("-n") + flags+=("--request-timeout=") + flags+=("--server=") + flags+=("--token=") + flags+=("--user=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + _oadm_completion() { last_command="oadm_completion" @@ -5092,6 +5255,7 @@ _oadm() commands=() commands+=("build-chain") commands+=("ca") + commands+=("certificate") commands+=("completion") commands+=("config") commands+=("cordon") diff --git a/contrib/completions/zsh/oc b/contrib/completions/zsh/oc index 2198a2119c14..6814a7809ea6 100644 --- a/contrib/completions/zsh/oc +++ b/contrib/completions/zsh/oc @@ -958,6 +958,163 @@ _oc_adm_ca() noun_aliases=() } +_oc_adm_certificate_approve() +{ + last_command="oc_adm_certificate_approve" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--filename=") + flags_with_completion+=("--filename") + flags_completion+=("__handle_filename_extension_flag json|yaml|yml") + two_word_flags+=("-f") + flags_with_completion+=("-f") + flags_completion+=("__handle_filename_extension_flag json|yaml|yml") + local_nonpersistent_flags+=("--filename=") + flags+=("--output=") + two_word_flags+=("-o") + local_nonpersistent_flags+=("--output=") + flags+=("--recursive") + flags+=("-R") + local_nonpersistent_flags+=("--recursive") + flags+=("--as=") + flags+=("--certificate-authority=") + flags_with_completion+=("--certificate-authority") + flags_completion+=("_filedir") + flags+=("--client-certificate=") + flags_with_completion+=("--client-certificate") + flags_completion+=("_filedir") + flags+=("--client-key=") + flags_with_completion+=("--client-key") + flags_completion+=("_filedir") + flags+=("--cluster=") + flags+=("--config=") + flags_with_completion+=("--config") + flags_completion+=("_filedir") + flags+=("--context=") + flags+=("--insecure-skip-tls-verify") + flags+=("--log-flush-frequency=") + flags+=("--loglevel=") + flags+=("--logspec=") + flags+=("--match-server-version") + flags+=("--namespace=") + two_word_flags+=("-n") + flags+=("--request-timeout=") + flags+=("--server=") + flags+=("--token=") + flags+=("--user=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_oc_adm_certificate_deny() +{ + last_command="oc_adm_certificate_deny" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--filename=") + flags_with_completion+=("--filename") + flags_completion+=("__handle_filename_extension_flag json|yaml|yml") + two_word_flags+=("-f") + flags_with_completion+=("-f") + flags_completion+=("__handle_filename_extension_flag json|yaml|yml") + local_nonpersistent_flags+=("--filename=") + flags+=("--output=") + two_word_flags+=("-o") + local_nonpersistent_flags+=("--output=") + flags+=("--recursive") + flags+=("-R") + local_nonpersistent_flags+=("--recursive") + flags+=("--as=") + flags+=("--certificate-authority=") + flags_with_completion+=("--certificate-authority") + flags_completion+=("_filedir") + flags+=("--client-certificate=") + flags_with_completion+=("--client-certificate") + flags_completion+=("_filedir") + flags+=("--client-key=") + flags_with_completion+=("--client-key") + flags_completion+=("_filedir") + flags+=("--cluster=") + flags+=("--config=") + flags_with_completion+=("--config") + flags_completion+=("_filedir") + flags+=("--context=") + flags+=("--insecure-skip-tls-verify") + flags+=("--log-flush-frequency=") + flags+=("--loglevel=") + flags+=("--logspec=") + flags+=("--match-server-version") + flags+=("--namespace=") + two_word_flags+=("-n") + flags+=("--request-timeout=") + flags+=("--server=") + flags+=("--token=") + flags+=("--user=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_oc_adm_certificate() +{ + last_command="oc_adm_certificate" + commands=() + commands+=("approve") + commands+=("deny") + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--as=") + flags+=("--certificate-authority=") + flags_with_completion+=("--certificate-authority") + flags_completion+=("_filedir") + flags+=("--client-certificate=") + flags_with_completion+=("--client-certificate") + flags_completion+=("_filedir") + flags+=("--client-key=") + flags_with_completion+=("--client-key") + flags_completion+=("_filedir") + flags+=("--cluster=") + flags+=("--config=") + flags_with_completion+=("--config") + flags_completion+=("_filedir") + flags+=("--context=") + flags+=("--insecure-skip-tls-verify") + flags+=("--log-flush-frequency=") + flags+=("--loglevel=") + flags+=("--logspec=") + flags+=("--match-server-version") + flags+=("--namespace=") + two_word_flags+=("-n") + flags+=("--request-timeout=") + flags+=("--server=") + flags+=("--token=") + flags+=("--user=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + _oc_adm_completion() { last_command="oc_adm_completion" @@ -5005,6 +5162,7 @@ _oc_adm() commands=() commands+=("build-chain") commands+=("ca") + commands+=("certificate") commands+=("completion") commands+=("config") commands+=("cordon") @@ -5679,6 +5837,94 @@ _oc_cluster_down() noun_aliases=() } +_oc_cluster_join() +{ + last_command="oc_cluster_join" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--create-machine") + local_nonpersistent_flags+=("--create-machine") + flags+=("--docker-machine=") + local_nonpersistent_flags+=("--docker-machine=") + flags+=("--env=") + two_word_flags+=("-e") + local_nonpersistent_flags+=("--env=") + flags+=("--forward-ports") + local_nonpersistent_flags+=("--forward-ports") + flags+=("--host-config-dir=") + local_nonpersistent_flags+=("--host-config-dir=") + flags+=("--host-data-dir=") + local_nonpersistent_flags+=("--host-data-dir=") + flags+=("--host-pv-dir=") + local_nonpersistent_flags+=("--host-pv-dir=") + flags+=("--host-volumes-dir=") + local_nonpersistent_flags+=("--host-volumes-dir=") + flags+=("--http-proxy=") + local_nonpersistent_flags+=("--http-proxy=") + flags+=("--https-proxy=") + local_nonpersistent_flags+=("--https-proxy=") + flags+=("--image=") + local_nonpersistent_flags+=("--image=") + flags+=("--image-streams=") + local_nonpersistent_flags+=("--image-streams=") + flags+=("--logging") + local_nonpersistent_flags+=("--logging") + flags+=("--metrics") + local_nonpersistent_flags+=("--metrics") + flags+=("--no-proxy=") + local_nonpersistent_flags+=("--no-proxy=") + flags+=("--public-hostname=") + local_nonpersistent_flags+=("--public-hostname=") + flags+=("--routing-suffix=") + local_nonpersistent_flags+=("--routing-suffix=") + flags+=("--secret=") + local_nonpersistent_flags+=("--secret=") + flags+=("--server-loglevel=") + local_nonpersistent_flags+=("--server-loglevel=") + flags+=("--skip-registry-check") + local_nonpersistent_flags+=("--skip-registry-check") + flags+=("--use-existing-config") + local_nonpersistent_flags+=("--use-existing-config") + flags+=("--version=") + local_nonpersistent_flags+=("--version=") + flags+=("--as=") + flags+=("--certificate-authority=") + flags_with_completion+=("--certificate-authority") + flags_completion+=("_filedir") + flags+=("--client-certificate=") + flags_with_completion+=("--client-certificate") + flags_completion+=("_filedir") + flags+=("--client-key=") + flags_with_completion+=("--client-key") + flags_completion+=("_filedir") + flags+=("--cluster=") + flags+=("--config=") + flags_with_completion+=("--config") + flags_completion+=("_filedir") + flags+=("--context=") + flags+=("--insecure-skip-tls-verify") + flags+=("--log-flush-frequency=") + flags+=("--loglevel=") + flags+=("--logspec=") + flags+=("--match-server-version") + flags+=("--namespace=") + two_word_flags+=("-n") + flags+=("--request-timeout=") + flags+=("--server=") + flags+=("--token=") + flags+=("--user=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + _oc_cluster_status() { last_command="oc_cluster_status" @@ -5815,6 +6061,7 @@ _oc_cluster() last_command="oc_cluster" commands=() commands+=("down") + commands+=("join") commands+=("status") commands+=("up") diff --git a/contrib/completions/zsh/openshift b/contrib/completions/zsh/openshift index 53c9910d192e..51852c865bee 100644 --- a/contrib/completions/zsh/openshift +++ b/contrib/completions/zsh/openshift @@ -848,6 +848,169 @@ _openshift_admin_ca() noun_aliases=() } +_openshift_admin_certificate_approve() +{ + last_command="openshift_admin_certificate_approve" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--filename=") + flags_with_completion+=("--filename") + flags_completion+=("__handle_filename_extension_flag json|yaml|yml") + two_word_flags+=("-f") + flags_with_completion+=("-f") + flags_completion+=("__handle_filename_extension_flag json|yaml|yml") + local_nonpersistent_flags+=("--filename=") + flags+=("--output=") + two_word_flags+=("-o") + local_nonpersistent_flags+=("--output=") + flags+=("--recursive") + flags+=("-R") + local_nonpersistent_flags+=("--recursive") + flags+=("--as=") + flags+=("--azure-container-registry-config=") + flags+=("--certificate-authority=") + flags_with_completion+=("--certificate-authority") + flags_completion+=("_filedir") + flags+=("--client-certificate=") + flags_with_completion+=("--client-certificate") + flags_completion+=("_filedir") + flags+=("--client-key=") + flags_with_completion+=("--client-key") + flags_completion+=("_filedir") + flags+=("--cluster=") + flags+=("--config=") + flags_with_completion+=("--config") + flags_completion+=("_filedir") + flags+=("--context=") + flags+=("--google-json-key=") + flags+=("--insecure-skip-tls-verify") + flags+=("--log-flush-frequency=") + flags+=("--loglevel=") + flags+=("--logspec=") + flags+=("--match-server-version") + flags+=("--namespace=") + two_word_flags+=("-n") + flags+=("--request-timeout=") + flags+=("--server=") + flags+=("--token=") + flags+=("--user=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_openshift_admin_certificate_deny() +{ + last_command="openshift_admin_certificate_deny" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--filename=") + flags_with_completion+=("--filename") + flags_completion+=("__handle_filename_extension_flag json|yaml|yml") + two_word_flags+=("-f") + flags_with_completion+=("-f") + flags_completion+=("__handle_filename_extension_flag json|yaml|yml") + local_nonpersistent_flags+=("--filename=") + flags+=("--output=") + two_word_flags+=("-o") + local_nonpersistent_flags+=("--output=") + flags+=("--recursive") + flags+=("-R") + local_nonpersistent_flags+=("--recursive") + flags+=("--as=") + flags+=("--azure-container-registry-config=") + flags+=("--certificate-authority=") + flags_with_completion+=("--certificate-authority") + flags_completion+=("_filedir") + flags+=("--client-certificate=") + flags_with_completion+=("--client-certificate") + flags_completion+=("_filedir") + flags+=("--client-key=") + flags_with_completion+=("--client-key") + flags_completion+=("_filedir") + flags+=("--cluster=") + flags+=("--config=") + flags_with_completion+=("--config") + flags_completion+=("_filedir") + flags+=("--context=") + flags+=("--google-json-key=") + flags+=("--insecure-skip-tls-verify") + flags+=("--log-flush-frequency=") + flags+=("--loglevel=") + flags+=("--logspec=") + flags+=("--match-server-version") + flags+=("--namespace=") + two_word_flags+=("-n") + flags+=("--request-timeout=") + flags+=("--server=") + flags+=("--token=") + flags+=("--user=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_openshift_admin_certificate() +{ + last_command="openshift_admin_certificate" + commands=() + commands+=("approve") + commands+=("deny") + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--as=") + flags+=("--azure-container-registry-config=") + flags+=("--certificate-authority=") + flags_with_completion+=("--certificate-authority") + flags_completion+=("_filedir") + flags+=("--client-certificate=") + flags_with_completion+=("--client-certificate") + flags_completion+=("_filedir") + flags+=("--client-key=") + flags_with_completion+=("--client-key") + flags_completion+=("_filedir") + flags+=("--cluster=") + flags+=("--config=") + flags_with_completion+=("--config") + flags_completion+=("_filedir") + flags+=("--context=") + flags+=("--google-json-key=") + flags+=("--insecure-skip-tls-verify") + flags+=("--log-flush-frequency=") + flags+=("--loglevel=") + flags+=("--logspec=") + flags+=("--match-server-version") + flags+=("--namespace=") + two_word_flags+=("-n") + flags+=("--request-timeout=") + flags+=("--server=") + flags+=("--token=") + flags+=("--user=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + _openshift_admin_completion() { last_command="openshift_admin_completion" @@ -5047,6 +5210,7 @@ _openshift_admin() commands=() commands+=("build-chain") commands+=("ca") + commands+=("certificate") commands+=("completion") commands+=("config") commands+=("cordon") @@ -5592,6 +5756,169 @@ _openshift_cli_adm_ca() noun_aliases=() } +_openshift_cli_adm_certificate_approve() +{ + last_command="openshift_cli_adm_certificate_approve" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--filename=") + flags_with_completion+=("--filename") + flags_completion+=("__handle_filename_extension_flag json|yaml|yml") + two_word_flags+=("-f") + flags_with_completion+=("-f") + flags_completion+=("__handle_filename_extension_flag json|yaml|yml") + local_nonpersistent_flags+=("--filename=") + flags+=("--output=") + two_word_flags+=("-o") + local_nonpersistent_flags+=("--output=") + flags+=("--recursive") + flags+=("-R") + local_nonpersistent_flags+=("--recursive") + flags+=("--as=") + flags+=("--azure-container-registry-config=") + flags+=("--certificate-authority=") + flags_with_completion+=("--certificate-authority") + flags_completion+=("_filedir") + flags+=("--client-certificate=") + flags_with_completion+=("--client-certificate") + flags_completion+=("_filedir") + flags+=("--client-key=") + flags_with_completion+=("--client-key") + flags_completion+=("_filedir") + flags+=("--cluster=") + flags+=("--config=") + flags_with_completion+=("--config") + flags_completion+=("_filedir") + flags+=("--context=") + flags+=("--google-json-key=") + flags+=("--insecure-skip-tls-verify") + flags+=("--log-flush-frequency=") + flags+=("--loglevel=") + flags+=("--logspec=") + flags+=("--match-server-version") + flags+=("--namespace=") + two_word_flags+=("-n") + flags+=("--request-timeout=") + flags+=("--server=") + flags+=("--token=") + flags+=("--user=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_openshift_cli_adm_certificate_deny() +{ + last_command="openshift_cli_adm_certificate_deny" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--filename=") + flags_with_completion+=("--filename") + flags_completion+=("__handle_filename_extension_flag json|yaml|yml") + two_word_flags+=("-f") + flags_with_completion+=("-f") + flags_completion+=("__handle_filename_extension_flag json|yaml|yml") + local_nonpersistent_flags+=("--filename=") + flags+=("--output=") + two_word_flags+=("-o") + local_nonpersistent_flags+=("--output=") + flags+=("--recursive") + flags+=("-R") + local_nonpersistent_flags+=("--recursive") + flags+=("--as=") + flags+=("--azure-container-registry-config=") + flags+=("--certificate-authority=") + flags_with_completion+=("--certificate-authority") + flags_completion+=("_filedir") + flags+=("--client-certificate=") + flags_with_completion+=("--client-certificate") + flags_completion+=("_filedir") + flags+=("--client-key=") + flags_with_completion+=("--client-key") + flags_completion+=("_filedir") + flags+=("--cluster=") + flags+=("--config=") + flags_with_completion+=("--config") + flags_completion+=("_filedir") + flags+=("--context=") + flags+=("--google-json-key=") + flags+=("--insecure-skip-tls-verify") + flags+=("--log-flush-frequency=") + flags+=("--loglevel=") + flags+=("--logspec=") + flags+=("--match-server-version") + flags+=("--namespace=") + two_word_flags+=("-n") + flags+=("--request-timeout=") + flags+=("--server=") + flags+=("--token=") + flags+=("--user=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_openshift_cli_adm_certificate() +{ + last_command="openshift_cli_adm_certificate" + commands=() + commands+=("approve") + commands+=("deny") + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--as=") + flags+=("--azure-container-registry-config=") + flags+=("--certificate-authority=") + flags_with_completion+=("--certificate-authority") + flags_completion+=("_filedir") + flags+=("--client-certificate=") + flags_with_completion+=("--client-certificate") + flags_completion+=("_filedir") + flags+=("--client-key=") + flags_with_completion+=("--client-key") + flags_completion+=("_filedir") + flags+=("--cluster=") + flags+=("--config=") + flags_with_completion+=("--config") + flags_completion+=("_filedir") + flags+=("--context=") + flags+=("--google-json-key=") + flags+=("--insecure-skip-tls-verify") + flags+=("--log-flush-frequency=") + flags+=("--loglevel=") + flags+=("--logspec=") + flags+=("--match-server-version") + flags+=("--namespace=") + two_word_flags+=("-n") + flags+=("--request-timeout=") + flags+=("--server=") + flags+=("--token=") + flags+=("--user=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + _openshift_cli_adm_completion() { last_command="openshift_cli_adm_completion" @@ -9791,6 +10118,7 @@ _openshift_cli_adm() commands=() commands+=("build-chain") commands+=("ca") + commands+=("certificate") commands+=("completion") commands+=("config") commands+=("cordon") @@ -10479,6 +10807,96 @@ _openshift_cli_cluster_down() noun_aliases=() } +_openshift_cli_cluster_join() +{ + last_command="openshift_cli_cluster_join" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--create-machine") + local_nonpersistent_flags+=("--create-machine") + flags+=("--docker-machine=") + local_nonpersistent_flags+=("--docker-machine=") + flags+=("--env=") + two_word_flags+=("-e") + local_nonpersistent_flags+=("--env=") + flags+=("--forward-ports") + local_nonpersistent_flags+=("--forward-ports") + flags+=("--host-config-dir=") + local_nonpersistent_flags+=("--host-config-dir=") + flags+=("--host-data-dir=") + local_nonpersistent_flags+=("--host-data-dir=") + flags+=("--host-pv-dir=") + local_nonpersistent_flags+=("--host-pv-dir=") + flags+=("--host-volumes-dir=") + local_nonpersistent_flags+=("--host-volumes-dir=") + flags+=("--http-proxy=") + local_nonpersistent_flags+=("--http-proxy=") + flags+=("--https-proxy=") + local_nonpersistent_flags+=("--https-proxy=") + flags+=("--image=") + local_nonpersistent_flags+=("--image=") + flags+=("--image-streams=") + local_nonpersistent_flags+=("--image-streams=") + flags+=("--logging") + local_nonpersistent_flags+=("--logging") + flags+=("--metrics") + local_nonpersistent_flags+=("--metrics") + flags+=("--no-proxy=") + local_nonpersistent_flags+=("--no-proxy=") + flags+=("--public-hostname=") + local_nonpersistent_flags+=("--public-hostname=") + flags+=("--routing-suffix=") + local_nonpersistent_flags+=("--routing-suffix=") + flags+=("--secret=") + local_nonpersistent_flags+=("--secret=") + flags+=("--server-loglevel=") + local_nonpersistent_flags+=("--server-loglevel=") + flags+=("--skip-registry-check") + local_nonpersistent_flags+=("--skip-registry-check") + flags+=("--use-existing-config") + local_nonpersistent_flags+=("--use-existing-config") + flags+=("--version=") + local_nonpersistent_flags+=("--version=") + flags+=("--as=") + flags+=("--azure-container-registry-config=") + flags+=("--certificate-authority=") + flags_with_completion+=("--certificate-authority") + flags_completion+=("_filedir") + flags+=("--client-certificate=") + flags_with_completion+=("--client-certificate") + flags_completion+=("_filedir") + flags+=("--client-key=") + flags_with_completion+=("--client-key") + flags_completion+=("_filedir") + flags+=("--cluster=") + flags+=("--config=") + flags_with_completion+=("--config") + flags_completion+=("_filedir") + flags+=("--context=") + flags+=("--google-json-key=") + flags+=("--insecure-skip-tls-verify") + flags+=("--log-flush-frequency=") + flags+=("--loglevel=") + flags+=("--logspec=") + flags+=("--match-server-version") + flags+=("--namespace=") + two_word_flags+=("-n") + flags+=("--request-timeout=") + flags+=("--server=") + flags+=("--token=") + flags+=("--user=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + _openshift_cli_cluster_status() { last_command="openshift_cli_cluster_status" @@ -10619,6 +11037,7 @@ _openshift_cli_cluster() last_command="openshift_cli_cluster" commands=() commands+=("down") + commands+=("join") commands+=("status") commands+=("up") @@ -31739,6 +32158,8 @@ _openshift_start_node() flags_with_completion=() flags_completion=() + flags+=("--bootstrap") + local_nonpersistent_flags+=("--bootstrap") flags+=("--config=") flags_with_completion+=("--config") flags_completion+=("__handle_filename_extension_flag yaml|yml") diff --git a/contrib/systemd/origin-node-bootstrap.sysconfig b/contrib/systemd/origin-node-bootstrap.sysconfig new file mode 100644 index 000000000000..1e334fcb0617 --- /dev/null +++ b/contrib/systemd/origin-node-bootstrap.sysconfig @@ -0,0 +1,14 @@ +OPTIONS="--loglevel=0 --bootstrap --kubeconfig=/etc/origin/node/node-bootstrap.kubeconfig" +# /etc/origin/node/ should contain a node-bootstrap.kubeconfig file that can request +# bootstrap certificates. +# +# If if your node is running on a separate host you can rsync the contents +# rsync -a root@atomic-openshift-master:/var/lib/origin/origin.local.certificates/node-`hostname`/ /etc/origin/node +CONFIG_FILE=/etc/origin/node/node-config.yaml + +# Proxy configuration +# Origin uses standard HTTP_PROXY environment variables. Be sure to set +# NO_PROXY for your master +#NO_PROXY=master.example.com +#HTTP_PROXY=http://USER:PASSWORD@IPADDR:PORT +#HTTPS_PROXY=https://USER:PASSWORD@IPADDR:PORT diff --git a/docs/generated/oc_by_example_content.adoc b/docs/generated/oc_by_example_content.adoc index 5806ffaa36fe..c2314f83e764 100644 --- a/docs/generated/oc_by_example_content.adoc +++ b/docs/generated/oc_by_example_content.adoc @@ -928,6 +928,25 @@ Stop OpenShift on Docker ==== +== oc cluster join +Join an existing OpenShift cluster + +==== + +[options="nowrap"] +---- + # Start a new OpenShift node on a new docker machine named 'node' + oc cluster join --create-machine + + # Start OpenShift node and preserve data and config between restarts + oc cluster join --host-data-dir=/mydata --use-existing-config + + # Use a different set of images + oc cluster join --image="registry.example.com/origin" --version="v1.1" +---- +==== + + == oc cluster status Show OpenShift on Docker status diff --git a/docs/man/man1/.files_generated_oadm b/docs/man/man1/.files_generated_oadm index bfcaadec3328..3458da37b822 100644 --- a/docs/man/man1/.files_generated_oadm +++ b/docs/man/man1/.files_generated_oadm @@ -6,6 +6,9 @@ oadm-ca-create-signer-cert.1 oadm-ca-decrypt.1 oadm-ca-encrypt.1 oadm-ca.1 +oadm-certificate-approve.1 +oadm-certificate-deny.1 +oadm-certificate.1 oadm-completion.1 oadm-config-current-context.1 oadm-config-delete-cluster.1 diff --git a/docs/man/man1/.files_generated_oc b/docs/man/man1/.files_generated_oc index 1aa815983203..d63dc88d87a5 100644 --- a/docs/man/man1/.files_generated_oc +++ b/docs/man/man1/.files_generated_oc @@ -6,6 +6,9 @@ oc-adm-ca-create-signer-cert.1 oc-adm-ca-decrypt.1 oc-adm-ca-encrypt.1 oc-adm-ca.1 +oc-adm-certificate-approve.1 +oc-adm-certificate-deny.1 +oc-adm-certificate.1 oc-adm-completion.1 oc-adm-config-current-context.1 oc-adm-config-delete-cluster.1 @@ -94,6 +97,7 @@ oc-autoscale.1 oc-build-logs.1 oc-cancel-build.1 oc-cluster-down.1 +oc-cluster-join.1 oc-cluster-status.1 oc-cluster-up.1 oc-cluster.1 diff --git a/docs/man/man1/.files_generated_openshift b/docs/man/man1/.files_generated_openshift index 253b79d70547..523c3ea58680 100644 --- a/docs/man/man1/.files_generated_openshift +++ b/docs/man/man1/.files_generated_openshift @@ -6,6 +6,9 @@ openshift-admin-ca-create-signer-cert.1 openshift-admin-ca-decrypt.1 openshift-admin-ca-encrypt.1 openshift-admin-ca.1 +openshift-admin-certificate-approve.1 +openshift-admin-certificate-deny.1 +openshift-admin-certificate.1 openshift-admin-completion.1 openshift-admin-config-current-context.1 openshift-admin-config-delete-cluster.1 @@ -95,6 +98,9 @@ openshift-cli-adm-ca-create-signer-cert.1 openshift-cli-adm-ca-decrypt.1 openshift-cli-adm-ca-encrypt.1 openshift-cli-adm-ca.1 +openshift-cli-adm-certificate-approve.1 +openshift-cli-adm-certificate-deny.1 +openshift-cli-adm-certificate.1 openshift-cli-adm-completion.1 openshift-cli-adm-config-current-context.1 openshift-cli-adm-config-delete-cluster.1 @@ -183,6 +189,7 @@ openshift-cli-autoscale.1 openshift-cli-build-logs.1 openshift-cli-cancel-build.1 openshift-cli-cluster-down.1 +openshift-cli-cluster-join.1 openshift-cli-cluster-status.1 openshift-cli-cluster-up.1 openshift-cli-cluster.1 diff --git a/docs/man/man1/oadm-certificate-approve.1 b/docs/man/man1/oadm-certificate-approve.1 new file mode 100644 index 000000000000..197a3ea84198 --- /dev/null +++ b/docs/man/man1/oadm-certificate-approve.1 @@ -0,0 +1,120 @@ +.TH "OADM CERTIFICATE" "1" " Openshift CLI User Manuals" "Openshift" "June 2016" "" + + +.SH NAME +.PP +oadm certificate approve \- Approve a certificate signing request + + +.SH SYNOPSIS +.PP +\fBoadm certificate approve\fP [OPTIONS] + + +.SH DESCRIPTION +.PP +Approve a certificate signing request. + +.PP +kubectl certificate approve allows a cluster admin to approve a certificate signing request (CSR). This action tells a certificate signing controller to issue a certificate to the requestor with the attributes requested in the CSR. + +.PP +SECURITY NOTICE: Depending on the requested attributes, the issued certificate can potentially grant a requester access to cluster resources or to authenticate as a requested identity. Before approving a CSR, ensure you understand what the signed certificate can do. + + +.SH OPTIONS +.PP +\fB\-f\fP, \fB\-\-filename\fP=[] + Filename, directory, or URL to files identifying the resource to update + +.PP +\fB\-o\fP, \fB\-\-output\fP="" + Output mode. Use "\-o name" for shorter output (resource/name). + +.PP +\fB\-R\fP, \fB\-\-recursive\fP=false + Process the directory used in \-f, \-\-filename recursively. Useful when you want to manage related manifests organized within the same directory. + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-api\-version\fP="" + DEPRECATED: The API version to use when talking to the server + +.PP +\fB\-\-as\fP="" + Username to impersonate for the operation + +.PP +\fB\-\-azure\-container\-registry\-config\fP="" + Path to the file container Azure container registry configuration information. + +.PP +\fB\-\-certificate\-authority\fP="" + Path to a cert. file for the certificate authority + +.PP +\fB\-\-client\-certificate\fP="" + Path to a client certificate file for TLS + +.PP +\fB\-\-client\-key\fP="" + Path to a client key file for TLS + +.PP +\fB\-\-cluster\fP="" + The name of the kubeconfig cluster to use + +.PP +\fB\-\-config\fP="" + Path to the config file to use for CLI requests. + +.PP +\fB\-\-context\fP="" + The name of the kubeconfig context to use + +.PP +\fB\-\-google\-json\-key\fP="" + The Google Cloud Platform Service Account JSON Key to use for authentication. + +.PP +\fB\-\-insecure\-skip\-tls\-verify\fP=false + If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure + +.PP +\fB\-\-log\-flush\-frequency\fP=0 + Maximum number of seconds between log flushes + +.PP +\fB\-\-match\-server\-version\fP=false + Require server version to match client version + +.PP +\fB\-n\fP, \fB\-\-namespace\fP="" + If present, the namespace scope for this CLI request + +.PP +\fB\-\-request\-timeout\fP="0" + The length of time to wait before giving up on a single server request. Non\-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. + +.PP +\fB\-\-server\fP="" + The address and port of the Kubernetes API server + +.PP +\fB\-\-token\fP="" + Bearer token for authentication to the API server + +.PP +\fB\-\-user\fP="" + The name of the kubeconfig user to use + + +.SH SEE ALSO +.PP +\fBoadm\-certificate(1)\fP, + + +.SH HISTORY +.PP +June 2016, Ported from the Kubernetes man\-doc generator diff --git a/docs/man/man1/oadm-certificate-deny.1 b/docs/man/man1/oadm-certificate-deny.1 new file mode 100644 index 000000000000..bc25b6ccaa61 --- /dev/null +++ b/docs/man/man1/oadm-certificate-deny.1 @@ -0,0 +1,117 @@ +.TH "OADM CERTIFICATE" "1" " Openshift CLI User Manuals" "Openshift" "June 2016" "" + + +.SH NAME +.PP +oadm certificate deny \- Deny a certificate signing request + + +.SH SYNOPSIS +.PP +\fBoadm certificate deny\fP [OPTIONS] + + +.SH DESCRIPTION +.PP +Deny a certificate signing request. + +.PP +kubectl certificate deny allows a cluster admin to deny a certificate signing request (CSR). This action tells a certificate signing controller to not to issue a certificate to the requestor. + + +.SH OPTIONS +.PP +\fB\-f\fP, \fB\-\-filename\fP=[] + Filename, directory, or URL to files identifying the resource to update + +.PP +\fB\-o\fP, \fB\-\-output\fP="" + Output mode. Use "\-o name" for shorter output (resource/name). + +.PP +\fB\-R\fP, \fB\-\-recursive\fP=false + Process the directory used in \-f, \-\-filename recursively. Useful when you want to manage related manifests organized within the same directory. + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-api\-version\fP="" + DEPRECATED: The API version to use when talking to the server + +.PP +\fB\-\-as\fP="" + Username to impersonate for the operation + +.PP +\fB\-\-azure\-container\-registry\-config\fP="" + Path to the file container Azure container registry configuration information. + +.PP +\fB\-\-certificate\-authority\fP="" + Path to a cert. file for the certificate authority + +.PP +\fB\-\-client\-certificate\fP="" + Path to a client certificate file for TLS + +.PP +\fB\-\-client\-key\fP="" + Path to a client key file for TLS + +.PP +\fB\-\-cluster\fP="" + The name of the kubeconfig cluster to use + +.PP +\fB\-\-config\fP="" + Path to the config file to use for CLI requests. + +.PP +\fB\-\-context\fP="" + The name of the kubeconfig context to use + +.PP +\fB\-\-google\-json\-key\fP="" + The Google Cloud Platform Service Account JSON Key to use for authentication. + +.PP +\fB\-\-insecure\-skip\-tls\-verify\fP=false + If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure + +.PP +\fB\-\-log\-flush\-frequency\fP=0 + Maximum number of seconds between log flushes + +.PP +\fB\-\-match\-server\-version\fP=false + Require server version to match client version + +.PP +\fB\-n\fP, \fB\-\-namespace\fP="" + If present, the namespace scope for this CLI request + +.PP +\fB\-\-request\-timeout\fP="0" + The length of time to wait before giving up on a single server request. Non\-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. + +.PP +\fB\-\-server\fP="" + The address and port of the Kubernetes API server + +.PP +\fB\-\-token\fP="" + Bearer token for authentication to the API server + +.PP +\fB\-\-user\fP="" + The name of the kubeconfig user to use + + +.SH SEE ALSO +.PP +\fBoadm\-certificate(1)\fP, + + +.SH HISTORY +.PP +June 2016, Ported from the Kubernetes man\-doc generator diff --git a/docs/man/man1/oadm-certificate.1 b/docs/man/man1/oadm-certificate.1 new file mode 100644 index 000000000000..dd60824b9758 --- /dev/null +++ b/docs/man/man1/oadm-certificate.1 @@ -0,0 +1,100 @@ +.TH "OADM" "1" " Openshift CLI User Manuals" "Openshift" "June 2016" "" + + +.SH NAME +.PP +oadm certificate \- Modify certificate resources. + + +.SH SYNOPSIS +.PP +\fBoadm certificate\fP [OPTIONS] + + +.SH DESCRIPTION +.PP +Modify certificate resources. + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-api\-version\fP="" + DEPRECATED: The API version to use when talking to the server + +.PP +\fB\-\-as\fP="" + Username to impersonate for the operation + +.PP +\fB\-\-azure\-container\-registry\-config\fP="" + Path to the file container Azure container registry configuration information. + +.PP +\fB\-\-certificate\-authority\fP="" + Path to a cert. file for the certificate authority + +.PP +\fB\-\-client\-certificate\fP="" + Path to a client certificate file for TLS + +.PP +\fB\-\-client\-key\fP="" + Path to a client key file for TLS + +.PP +\fB\-\-cluster\fP="" + The name of the kubeconfig cluster to use + +.PP +\fB\-\-config\fP="" + Path to the config file to use for CLI requests. + +.PP +\fB\-\-context\fP="" + The name of the kubeconfig context to use + +.PP +\fB\-\-google\-json\-key\fP="" + The Google Cloud Platform Service Account JSON Key to use for authentication. + +.PP +\fB\-\-insecure\-skip\-tls\-verify\fP=false + If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure + +.PP +\fB\-\-log\-flush\-frequency\fP=0 + Maximum number of seconds between log flushes + +.PP +\fB\-\-match\-server\-version\fP=false + Require server version to match client version + +.PP +\fB\-n\fP, \fB\-\-namespace\fP="" + If present, the namespace scope for this CLI request + +.PP +\fB\-\-request\-timeout\fP="0" + The length of time to wait before giving up on a single server request. Non\-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. + +.PP +\fB\-\-server\fP="" + The address and port of the Kubernetes API server + +.PP +\fB\-\-token\fP="" + Bearer token for authentication to the API server + +.PP +\fB\-\-user\fP="" + The name of the kubeconfig user to use + + +.SH SEE ALSO +.PP +\fBoadm(1)\fP, \fBoadm\-certificate\-approve(1)\fP, \fBoadm\-certificate\-deny(1)\fP, + + +.SH HISTORY +.PP +June 2016, Ported from the Kubernetes man\-doc generator diff --git a/docs/man/man1/oadm.1 b/docs/man/man1/oadm.1 index 03df21be8ea4..20a6036a9087 100644 --- a/docs/man/man1/oadm.1 +++ b/docs/man/man1/oadm.1 @@ -95,7 +95,7 @@ Commands for managing a cluster are exposed here. Many administrative actions in .SH SEE ALSO .PP -\fBoadm\-build\-chain(1)\fP, \fBoadm\-ca(1)\fP, \fBoadm\-completion(1)\fP, \fBoadm\-config(1)\fP, \fBoadm\-cordon(1)\fP, \fBoadm\-create\-api\-client\-config(1)\fP, \fBoadm\-create\-bootstrap\-policy\-file(1)\fP, \fBoadm\-create\-bootstrap\-project\-template(1)\fP, \fBoadm\-create\-error\-template(1)\fP, \fBoadm\-create\-key\-pair(1)\fP, \fBoadm\-create\-kubeconfig(1)\fP, \fBoadm\-create\-login\-template(1)\fP, \fBoadm\-create\-master\-certs(1)\fP, \fBoadm\-create\-node\-config(1)\fP, \fBoadm\-create\-provider\-selection\-template(1)\fP, \fBoadm\-create\-server\-cert(1)\fP, \fBoadm\-create\-signer\-cert(1)\fP, \fBoadm\-diagnostics(1)\fP, \fBoadm\-drain(1)\fP, \fBoadm\-groups(1)\fP, \fBoadm\-ipfailover(1)\fP, \fBoadm\-manage\-node(1)\fP, \fBoadm\-migrate(1)\fP, \fBoadm\-new\-project(1)\fP, \fBoadm\-options(1)\fP, \fBoadm\-overwrite\-policy(1)\fP, \fBoadm\-pod\-network(1)\fP, \fBoadm\-policy(1)\fP, \fBoadm\-prune(1)\fP, \fBoadm\-registry(1)\fP, \fBoadm\-router(1)\fP, \fBoadm\-taint(1)\fP, \fBoadm\-top(1)\fP, \fBoadm\-uncordon(1)\fP, \fBoadm\-version(1)\fP, +\fBoadm\-build\-chain(1)\fP, \fBoadm\-ca(1)\fP, \fBoadm\-certificate(1)\fP, \fBoadm\-completion(1)\fP, \fBoadm\-config(1)\fP, \fBoadm\-cordon(1)\fP, \fBoadm\-create\-api\-client\-config(1)\fP, \fBoadm\-create\-bootstrap\-policy\-file(1)\fP, \fBoadm\-create\-bootstrap\-project\-template(1)\fP, \fBoadm\-create\-error\-template(1)\fP, \fBoadm\-create\-key\-pair(1)\fP, \fBoadm\-create\-kubeconfig(1)\fP, \fBoadm\-create\-login\-template(1)\fP, \fBoadm\-create\-master\-certs(1)\fP, \fBoadm\-create\-node\-config(1)\fP, \fBoadm\-create\-provider\-selection\-template(1)\fP, \fBoadm\-create\-server\-cert(1)\fP, \fBoadm\-create\-signer\-cert(1)\fP, \fBoadm\-diagnostics(1)\fP, \fBoadm\-drain(1)\fP, \fBoadm\-groups(1)\fP, \fBoadm\-ipfailover(1)\fP, \fBoadm\-manage\-node(1)\fP, \fBoadm\-migrate(1)\fP, \fBoadm\-new\-project(1)\fP, \fBoadm\-options(1)\fP, \fBoadm\-overwrite\-policy(1)\fP, \fBoadm\-pod\-network(1)\fP, \fBoadm\-policy(1)\fP, \fBoadm\-prune(1)\fP, \fBoadm\-registry(1)\fP, \fBoadm\-router(1)\fP, \fBoadm\-taint(1)\fP, \fBoadm\-top(1)\fP, \fBoadm\-uncordon(1)\fP, \fBoadm\-version(1)\fP, .SH HISTORY diff --git a/docs/man/man1/oc-adm-certificate-approve.1 b/docs/man/man1/oc-adm-certificate-approve.1 new file mode 100644 index 000000000000..41399628a359 --- /dev/null +++ b/docs/man/man1/oc-adm-certificate-approve.1 @@ -0,0 +1,120 @@ +.TH "OC ADM CERTIFICATE" "1" " Openshift CLI User Manuals" "Openshift" "June 2016" "" + + +.SH NAME +.PP +oc adm certificate approve \- Approve a certificate signing request + + +.SH SYNOPSIS +.PP +\fBoc adm certificate approve\fP [OPTIONS] + + +.SH DESCRIPTION +.PP +Approve a certificate signing request. + +.PP +kubectl certificate approve allows a cluster admin to approve a certificate signing request (CSR). This action tells a certificate signing controller to issue a certificate to the requestor with the attributes requested in the CSR. + +.PP +SECURITY NOTICE: Depending on the requested attributes, the issued certificate can potentially grant a requester access to cluster resources or to authenticate as a requested identity. Before approving a CSR, ensure you understand what the signed certificate can do. + + +.SH OPTIONS +.PP +\fB\-f\fP, \fB\-\-filename\fP=[] + Filename, directory, or URL to files identifying the resource to update + +.PP +\fB\-o\fP, \fB\-\-output\fP="" + Output mode. Use "\-o name" for shorter output (resource/name). + +.PP +\fB\-R\fP, \fB\-\-recursive\fP=false + Process the directory used in \-f, \-\-filename recursively. Useful when you want to manage related manifests organized within the same directory. + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-api\-version\fP="" + DEPRECATED: The API version to use when talking to the server + +.PP +\fB\-\-as\fP="" + Username to impersonate for the operation + +.PP +\fB\-\-azure\-container\-registry\-config\fP="" + Path to the file container Azure container registry configuration information. + +.PP +\fB\-\-certificate\-authority\fP="" + Path to a cert. file for the certificate authority + +.PP +\fB\-\-client\-certificate\fP="" + Path to a client certificate file for TLS + +.PP +\fB\-\-client\-key\fP="" + Path to a client key file for TLS + +.PP +\fB\-\-cluster\fP="" + The name of the kubeconfig cluster to use + +.PP +\fB\-\-config\fP="" + Path to the config file to use for CLI requests. + +.PP +\fB\-\-context\fP="" + The name of the kubeconfig context to use + +.PP +\fB\-\-google\-json\-key\fP="" + The Google Cloud Platform Service Account JSON Key to use for authentication. + +.PP +\fB\-\-insecure\-skip\-tls\-verify\fP=false + If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure + +.PP +\fB\-\-log\-flush\-frequency\fP=0 + Maximum number of seconds between log flushes + +.PP +\fB\-\-match\-server\-version\fP=false + Require server version to match client version + +.PP +\fB\-n\fP, \fB\-\-namespace\fP="" + If present, the namespace scope for this CLI request + +.PP +\fB\-\-request\-timeout\fP="0" + The length of time to wait before giving up on a single server request. Non\-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. + +.PP +\fB\-\-server\fP="" + The address and port of the Kubernetes API server + +.PP +\fB\-\-token\fP="" + Bearer token for authentication to the API server + +.PP +\fB\-\-user\fP="" + The name of the kubeconfig user to use + + +.SH SEE ALSO +.PP +\fBoc\-adm\-certificate(1)\fP, + + +.SH HISTORY +.PP +June 2016, Ported from the Kubernetes man\-doc generator diff --git a/docs/man/man1/oc-adm-certificate-deny.1 b/docs/man/man1/oc-adm-certificate-deny.1 new file mode 100644 index 000000000000..1e28a6fa7926 --- /dev/null +++ b/docs/man/man1/oc-adm-certificate-deny.1 @@ -0,0 +1,117 @@ +.TH "OC ADM CERTIFICATE" "1" " Openshift CLI User Manuals" "Openshift" "June 2016" "" + + +.SH NAME +.PP +oc adm certificate deny \- Deny a certificate signing request + + +.SH SYNOPSIS +.PP +\fBoc adm certificate deny\fP [OPTIONS] + + +.SH DESCRIPTION +.PP +Deny a certificate signing request. + +.PP +kubectl certificate deny allows a cluster admin to deny a certificate signing request (CSR). This action tells a certificate signing controller to not to issue a certificate to the requestor. + + +.SH OPTIONS +.PP +\fB\-f\fP, \fB\-\-filename\fP=[] + Filename, directory, or URL to files identifying the resource to update + +.PP +\fB\-o\fP, \fB\-\-output\fP="" + Output mode. Use "\-o name" for shorter output (resource/name). + +.PP +\fB\-R\fP, \fB\-\-recursive\fP=false + Process the directory used in \-f, \-\-filename recursively. Useful when you want to manage related manifests organized within the same directory. + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-api\-version\fP="" + DEPRECATED: The API version to use when talking to the server + +.PP +\fB\-\-as\fP="" + Username to impersonate for the operation + +.PP +\fB\-\-azure\-container\-registry\-config\fP="" + Path to the file container Azure container registry configuration information. + +.PP +\fB\-\-certificate\-authority\fP="" + Path to a cert. file for the certificate authority + +.PP +\fB\-\-client\-certificate\fP="" + Path to a client certificate file for TLS + +.PP +\fB\-\-client\-key\fP="" + Path to a client key file for TLS + +.PP +\fB\-\-cluster\fP="" + The name of the kubeconfig cluster to use + +.PP +\fB\-\-config\fP="" + Path to the config file to use for CLI requests. + +.PP +\fB\-\-context\fP="" + The name of the kubeconfig context to use + +.PP +\fB\-\-google\-json\-key\fP="" + The Google Cloud Platform Service Account JSON Key to use for authentication. + +.PP +\fB\-\-insecure\-skip\-tls\-verify\fP=false + If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure + +.PP +\fB\-\-log\-flush\-frequency\fP=0 + Maximum number of seconds between log flushes + +.PP +\fB\-\-match\-server\-version\fP=false + Require server version to match client version + +.PP +\fB\-n\fP, \fB\-\-namespace\fP="" + If present, the namespace scope for this CLI request + +.PP +\fB\-\-request\-timeout\fP="0" + The length of time to wait before giving up on a single server request. Non\-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. + +.PP +\fB\-\-server\fP="" + The address and port of the Kubernetes API server + +.PP +\fB\-\-token\fP="" + Bearer token for authentication to the API server + +.PP +\fB\-\-user\fP="" + The name of the kubeconfig user to use + + +.SH SEE ALSO +.PP +\fBoc\-adm\-certificate(1)\fP, + + +.SH HISTORY +.PP +June 2016, Ported from the Kubernetes man\-doc generator diff --git a/docs/man/man1/oc-adm-certificate.1 b/docs/man/man1/oc-adm-certificate.1 new file mode 100644 index 000000000000..0587f275679e --- /dev/null +++ b/docs/man/man1/oc-adm-certificate.1 @@ -0,0 +1,100 @@ +.TH "OC ADM" "1" " Openshift CLI User Manuals" "Openshift" "June 2016" "" + + +.SH NAME +.PP +oc adm certificate \- Modify certificate resources. + + +.SH SYNOPSIS +.PP +\fBoc adm certificate\fP [OPTIONS] + + +.SH DESCRIPTION +.PP +Modify certificate resources. + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-api\-version\fP="" + DEPRECATED: The API version to use when talking to the server + +.PP +\fB\-\-as\fP="" + Username to impersonate for the operation + +.PP +\fB\-\-azure\-container\-registry\-config\fP="" + Path to the file container Azure container registry configuration information. + +.PP +\fB\-\-certificate\-authority\fP="" + Path to a cert. file for the certificate authority + +.PP +\fB\-\-client\-certificate\fP="" + Path to a client certificate file for TLS + +.PP +\fB\-\-client\-key\fP="" + Path to a client key file for TLS + +.PP +\fB\-\-cluster\fP="" + The name of the kubeconfig cluster to use + +.PP +\fB\-\-config\fP="" + Path to the config file to use for CLI requests. + +.PP +\fB\-\-context\fP="" + The name of the kubeconfig context to use + +.PP +\fB\-\-google\-json\-key\fP="" + The Google Cloud Platform Service Account JSON Key to use for authentication. + +.PP +\fB\-\-insecure\-skip\-tls\-verify\fP=false + If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure + +.PP +\fB\-\-log\-flush\-frequency\fP=0 + Maximum number of seconds between log flushes + +.PP +\fB\-\-match\-server\-version\fP=false + Require server version to match client version + +.PP +\fB\-n\fP, \fB\-\-namespace\fP="" + If present, the namespace scope for this CLI request + +.PP +\fB\-\-request\-timeout\fP="0" + The length of time to wait before giving up on a single server request. Non\-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. + +.PP +\fB\-\-server\fP="" + The address and port of the Kubernetes API server + +.PP +\fB\-\-token\fP="" + Bearer token for authentication to the API server + +.PP +\fB\-\-user\fP="" + The name of the kubeconfig user to use + + +.SH SEE ALSO +.PP +\fBoc\-adm(1)\fP, \fBoc\-adm\-certificate\-approve(1)\fP, \fBoc\-adm\-certificate\-deny(1)\fP, + + +.SH HISTORY +.PP +June 2016, Ported from the Kubernetes man\-doc generator diff --git a/docs/man/man1/oc-adm.1 b/docs/man/man1/oc-adm.1 index dcd1468bfa03..34a06ce54993 100644 --- a/docs/man/man1/oc-adm.1 +++ b/docs/man/man1/oc-adm.1 @@ -97,7 +97,7 @@ Commands for managing a cluster are exposed here. Many administrative actions in .SH SEE ALSO .PP -\fBoc(1)\fP, \fBoc\-adm\-build\-chain(1)\fP, \fBoc\-adm\-ca(1)\fP, \fBoc\-adm\-completion(1)\fP, \fBoc\-adm\-config(1)\fP, \fBoc\-adm\-cordon(1)\fP, \fBoc\-adm\-create\-api\-client\-config(1)\fP, \fBoc\-adm\-create\-bootstrap\-policy\-file(1)\fP, \fBoc\-adm\-create\-bootstrap\-project\-template(1)\fP, \fBoc\-adm\-create\-error\-template(1)\fP, \fBoc\-adm\-create\-key\-pair(1)\fP, \fBoc\-adm\-create\-kubeconfig(1)\fP, \fBoc\-adm\-create\-login\-template(1)\fP, \fBoc\-adm\-create\-master\-certs(1)\fP, \fBoc\-adm\-create\-node\-config(1)\fP, \fBoc\-adm\-create\-provider\-selection\-template(1)\fP, \fBoc\-adm\-create\-server\-cert(1)\fP, \fBoc\-adm\-create\-signer\-cert(1)\fP, \fBoc\-adm\-diagnostics(1)\fP, \fBoc\-adm\-drain(1)\fP, \fBoc\-adm\-groups(1)\fP, \fBoc\-adm\-ipfailover(1)\fP, \fBoc\-adm\-manage\-node(1)\fP, \fBoc\-adm\-migrate(1)\fP, \fBoc\-adm\-new\-project(1)\fP, \fBoc\-adm\-options(1)\fP, \fBoc\-adm\-overwrite\-policy(1)\fP, \fBoc\-adm\-pod\-network(1)\fP, \fBoc\-adm\-policy(1)\fP, \fBoc\-adm\-prune(1)\fP, \fBoc\-adm\-registry(1)\fP, \fBoc\-adm\-router(1)\fP, \fBoc\-adm\-taint(1)\fP, \fBoc\-adm\-top(1)\fP, \fBoc\-adm\-uncordon(1)\fP, +\fBoc(1)\fP, \fBoc\-adm\-build\-chain(1)\fP, \fBoc\-adm\-ca(1)\fP, \fBoc\-adm\-certificate(1)\fP, \fBoc\-adm\-completion(1)\fP, \fBoc\-adm\-config(1)\fP, \fBoc\-adm\-cordon(1)\fP, \fBoc\-adm\-create\-api\-client\-config(1)\fP, \fBoc\-adm\-create\-bootstrap\-policy\-file(1)\fP, \fBoc\-adm\-create\-bootstrap\-project\-template(1)\fP, \fBoc\-adm\-create\-error\-template(1)\fP, \fBoc\-adm\-create\-key\-pair(1)\fP, \fBoc\-adm\-create\-kubeconfig(1)\fP, \fBoc\-adm\-create\-login\-template(1)\fP, \fBoc\-adm\-create\-master\-certs(1)\fP, \fBoc\-adm\-create\-node\-config(1)\fP, \fBoc\-adm\-create\-provider\-selection\-template(1)\fP, \fBoc\-adm\-create\-server\-cert(1)\fP, \fBoc\-adm\-create\-signer\-cert(1)\fP, \fBoc\-adm\-diagnostics(1)\fP, \fBoc\-adm\-drain(1)\fP, \fBoc\-adm\-groups(1)\fP, \fBoc\-adm\-ipfailover(1)\fP, \fBoc\-adm\-manage\-node(1)\fP, \fBoc\-adm\-migrate(1)\fP, \fBoc\-adm\-new\-project(1)\fP, \fBoc\-adm\-options(1)\fP, \fBoc\-adm\-overwrite\-policy(1)\fP, \fBoc\-adm\-pod\-network(1)\fP, \fBoc\-adm\-policy(1)\fP, \fBoc\-adm\-prune(1)\fP, \fBoc\-adm\-registry(1)\fP, \fBoc\-adm\-router(1)\fP, \fBoc\-adm\-taint(1)\fP, \fBoc\-adm\-top(1)\fP, \fBoc\-adm\-uncordon(1)\fP, .SH HISTORY diff --git a/docs/man/man1/oc-cluster-join.1 b/docs/man/man1/oc-cluster-join.1 new file mode 100644 index 000000000000..7fe1e0f72e75 --- /dev/null +++ b/docs/man/man1/oc-cluster-join.1 @@ -0,0 +1,214 @@ +.TH "OC CLUSTER" "1" " Openshift CLI User Manuals" "Openshift" "June 2016" "" + + +.SH NAME +.PP +oc cluster join \- Join an existing OpenShift cluster + + +.SH SYNOPSIS +.PP +\fBoc cluster join\fP [OPTIONS] + + +.SH DESCRIPTION +.PP +Add a new node to an existing OpenShift cluster + +.PP +Uses an existing connection to a Docker daemon to start an OpenShift node. You must provide a secret to connect to the master. Before running command, ensure that you can execute docker commands successfully (ie. 'docker ps'). + +.PP +Optionally, the command can create a new Docker machine for your OpenShift node using the VirtualBox driver when the \-\-create\-machine argument is specified. The machine will be named 'node' by default. To name the machine differently, use the \-\-docker\-machine=NAME argument. If the \-\-docker\-machine=NAME argument is specified, but \-\-create\-machine is not, the command will attempt to find an existing docker machine with that name and start it if it's not running. + + +.SH OPTIONS +.PP +\fB\-\-create\-machine\fP=false + Create a Docker machine if one doesn't exist + +.PP +\fB\-\-docker\-machine\fP="" + Specify the Docker machine to use + +.PP +\fB\-e\fP, \fB\-\-env\fP=[] + Specify a key\-value pair for an environment variable to set on OpenShift container + +.PP +\fB\-\-forward\-ports\fP=false + Use Docker port\-forwarding to communicate with origin container. Requires 'socat' locally. + +.PP +\fB\-\-host\-config\-dir\fP="/var/lib/origin/openshift.local.config" + Directory on Docker host for OpenShift configuration + +.PP +\fB\-\-host\-data\-dir\fP="" + Directory on Docker host for OpenShift data. If not specified, etcd data will not be persisted on the host. + +.PP +\fB\-\-host\-pv\-dir\fP="/var/lib/origin/openshift.local.pv" + Directory on host for OpenShift persistent volumes + +.PP +\fB\-\-host\-volumes\-dir\fP="/var/lib/origin/openshift.local.volumes" + Directory on Docker host for OpenShift volumes + +.PP +\fB\-\-http\-proxy\fP="" + HTTP proxy to use for master and builds + +.PP +\fB\-\-https\-proxy\fP="" + HTTPS proxy to use for master and builds + +.PP +\fB\-\-image\fP="openshift/origin" + Specify the images to use for OpenShift + +.PP +\fB\-\-image\-streams\fP="centos7" + Specify which image streams to use, centos7|rhel7 + +.PP +\fB\-\-logging\fP=false + Install logging (experimental) + +.PP +\fB\-\-metrics\fP=false + Install metrics (experimental) + +.PP +\fB\-\-no\-proxy\fP=[] + List of hosts or subnets for which a proxy should not be used + +.PP +\fB\-\-public\-hostname\fP="" + Public hostname for OpenShift cluster + +.PP +\fB\-\-routing\-suffix\fP="" + Default suffix for server routes + +.PP +\fB\-\-secret\fP="" + Pass the secret to use to connect to the cluster + +.PP +\fB\-\-server\-loglevel\fP=0 + Log level for OpenShift server + +.PP +\fB\-\-skip\-registry\-check\fP=false + Skip Docker daemon registry check + +.PP +\fB\-\-use\-existing\-config\fP=false + Use existing configuration if present + +.PP +\fB\-\-version\fP="" + Specify the tag for OpenShift images + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-api\-version\fP="" + DEPRECATED: The API version to use when talking to the server + +.PP +\fB\-\-as\fP="" + Username to impersonate for the operation + +.PP +\fB\-\-azure\-container\-registry\-config\fP="" + Path to the file container Azure container registry configuration information. + +.PP +\fB\-\-certificate\-authority\fP="" + Path to a cert. file for the certificate authority + +.PP +\fB\-\-client\-certificate\fP="" + Path to a client certificate file for TLS + +.PP +\fB\-\-client\-key\fP="" + Path to a client key file for TLS + +.PP +\fB\-\-cluster\fP="" + The name of the kubeconfig cluster to use + +.PP +\fB\-\-config\fP="" + Path to the config file to use for CLI requests. + +.PP +\fB\-\-context\fP="" + The name of the kubeconfig context to use + +.PP +\fB\-\-google\-json\-key\fP="" + The Google Cloud Platform Service Account JSON Key to use for authentication. + +.PP +\fB\-\-insecure\-skip\-tls\-verify\fP=false + If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure + +.PP +\fB\-\-log\-flush\-frequency\fP=0 + Maximum number of seconds between log flushes + +.PP +\fB\-\-match\-server\-version\fP=false + Require server version to match client version + +.PP +\fB\-n\fP, \fB\-\-namespace\fP="" + If present, the namespace scope for this CLI request + +.PP +\fB\-\-request\-timeout\fP="0" + The length of time to wait before giving up on a single server request. Non\-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. + +.PP +\fB\-\-server\fP="" + The address and port of the Kubernetes API server + +.PP +\fB\-\-token\fP="" + Bearer token for authentication to the API server + +.PP +\fB\-\-user\fP="" + The name of the kubeconfig user to use + + +.SH EXAMPLE +.PP +.RS + +.nf + # Start a new OpenShift node on a new docker machine named 'node' + oc cluster join \-\-create\-machine + + # Start OpenShift node and preserve data and config between restarts + oc cluster join \-\-host\-data\-dir=/mydata \-\-use\-existing\-config + + # Use a different set of images + oc cluster join \-\-image="registry.example.com/origin" \-\-version="v1.1" + +.fi +.RE + + +.SH SEE ALSO +.PP +\fBoc\-cluster(1)\fP, + + +.SH HISTORY +.PP +June 2016, Ported from the Kubernetes man\-doc generator diff --git a/docs/man/man1/oc-cluster-up.1 b/docs/man/man1/oc-cluster-up.1 index b57fa442758a..4f280a319998 100644 --- a/docs/man/man1/oc-cluster-up.1 +++ b/docs/man/man1/oc-cluster-up.1 @@ -31,7 +31,7 @@ A public hostname can also be specified for the server with the \-\-public\-host .SH OPTIONS .PP \fB\-\-create\-machine\fP=false - If true, create a Docker machine if one doesn't exist + Create a Docker machine if one doesn't exist .PP \fB\-\-docker\-machine\fP="" @@ -43,7 +43,7 @@ A public hostname can also be specified for the server with the \-\-public\-host .PP \fB\-\-forward\-ports\fP=false - If true, use Docker port\-forwarding to communicate with origin container. Requires 'socat' locally. + Use Docker port\-forwarding to communicate with origin container. Requires 'socat' locally. .PP \fB\-\-host\-config\-dir\fP="/var/lib/origin/openshift.local.config" @@ -79,11 +79,11 @@ A public hostname can also be specified for the server with the \-\-public\-host .PP \fB\-\-logging\fP=false - If true, install logging (experimental) + Install logging (experimental) .PP \fB\-\-metrics\fP=false - If true, install metrics (experimental) + Install metrics (experimental) .PP \fB\-\-no\-proxy\fP=[] @@ -103,11 +103,11 @@ A public hostname can also be specified for the server with the \-\-public\-host .PP \fB\-\-skip\-registry\-check\fP=false - If true, skip Docker daemon registry check + Skip Docker daemon registry check .PP \fB\-\-use\-existing\-config\fP=false - If true, use existing configuration if present + Use existing configuration if present .PP \fB\-\-version\fP="" diff --git a/docs/man/man1/oc-cluster.1 b/docs/man/man1/oc-cluster.1 index 72cebc327cad..57330d954e6d 100644 --- a/docs/man/man1/oc-cluster.1 +++ b/docs/man/man1/oc-cluster.1 @@ -18,6 +18,9 @@ Manage a local OpenShift cluster .PP The OpenShift cluster will run as an all\-in\-one container on a Docker host. The Docker host may be a local VM (ie. using docker\-machine on OS X and Windows clients), remote machine, or the local Unix host. +.PP +Use the 'up' command to start a new cluster (master and node) on a single machine. Use the 'join' command on another machine to connect to the first cluster. + .PP To use an existing Docker connection, ensure that Docker commands are working and that you can create new containers. For OS X and Windows clients, a docker\-machine with the VirtualBox driver can be created for you using the \-\-create\-machine option. @@ -104,7 +107,7 @@ Default routes are setup using xip.io and the host ip of your cluster. To use a .SH SEE ALSO .PP -\fBoc(1)\fP, \fBoc\-cluster\-down(1)\fP, \fBoc\-cluster\-status(1)\fP, \fBoc\-cluster\-up(1)\fP, +\fBoc(1)\fP, \fBoc\-cluster\-down(1)\fP, \fBoc\-cluster\-join(1)\fP, \fBoc\-cluster\-status(1)\fP, \fBoc\-cluster\-up(1)\fP, .SH HISTORY diff --git a/docs/man/man1/openshift-admin-certificate-approve.1 b/docs/man/man1/openshift-admin-certificate-approve.1 new file mode 100644 index 000000000000..6dd031584357 --- /dev/null +++ b/docs/man/man1/openshift-admin-certificate-approve.1 @@ -0,0 +1,120 @@ +.TH "OPENSHIFT ADMIN CERTIFICATE" "1" " Openshift CLI User Manuals" "Openshift" "June 2016" "" + + +.SH NAME +.PP +openshift admin certificate approve \- Approve a certificate signing request + + +.SH SYNOPSIS +.PP +\fBopenshift admin certificate approve\fP [OPTIONS] + + +.SH DESCRIPTION +.PP +Approve a certificate signing request. + +.PP +kubectl certificate approve allows a cluster admin to approve a certificate signing request (CSR). This action tells a certificate signing controller to issue a certificate to the requestor with the attributes requested in the CSR. + +.PP +SECURITY NOTICE: Depending on the requested attributes, the issued certificate can potentially grant a requester access to cluster resources or to authenticate as a requested identity. Before approving a CSR, ensure you understand what the signed certificate can do. + + +.SH OPTIONS +.PP +\fB\-f\fP, \fB\-\-filename\fP=[] + Filename, directory, or URL to files identifying the resource to update + +.PP +\fB\-o\fP, \fB\-\-output\fP="" + Output mode. Use "\-o name" for shorter output (resource/name). + +.PP +\fB\-R\fP, \fB\-\-recursive\fP=false + Process the directory used in \-f, \-\-filename recursively. Useful when you want to manage related manifests organized within the same directory. + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-api\-version\fP="" + DEPRECATED: The API version to use when talking to the server + +.PP +\fB\-\-as\fP="" + Username to impersonate for the operation + +.PP +\fB\-\-azure\-container\-registry\-config\fP="" + Path to the file container Azure container registry configuration information. + +.PP +\fB\-\-certificate\-authority\fP="" + Path to a cert. file for the certificate authority + +.PP +\fB\-\-client\-certificate\fP="" + Path to a client certificate file for TLS + +.PP +\fB\-\-client\-key\fP="" + Path to a client key file for TLS + +.PP +\fB\-\-cluster\fP="" + The name of the kubeconfig cluster to use + +.PP +\fB\-\-config\fP="" + Path to the config file to use for CLI requests. + +.PP +\fB\-\-context\fP="" + The name of the kubeconfig context to use + +.PP +\fB\-\-google\-json\-key\fP="" + The Google Cloud Platform Service Account JSON Key to use for authentication. + +.PP +\fB\-\-insecure\-skip\-tls\-verify\fP=false + If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure + +.PP +\fB\-\-log\-flush\-frequency\fP=0 + Maximum number of seconds between log flushes + +.PP +\fB\-\-match\-server\-version\fP=false + Require server version to match client version + +.PP +\fB\-n\fP, \fB\-\-namespace\fP="" + If present, the namespace scope for this CLI request + +.PP +\fB\-\-request\-timeout\fP="0" + The length of time to wait before giving up on a single server request. Non\-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. + +.PP +\fB\-\-server\fP="" + The address and port of the Kubernetes API server + +.PP +\fB\-\-token\fP="" + Bearer token for authentication to the API server + +.PP +\fB\-\-user\fP="" + The name of the kubeconfig user to use + + +.SH SEE ALSO +.PP +\fBopenshift\-admin\-certificate(1)\fP, + + +.SH HISTORY +.PP +June 2016, Ported from the Kubernetes man\-doc generator diff --git a/docs/man/man1/openshift-admin-certificate-deny.1 b/docs/man/man1/openshift-admin-certificate-deny.1 new file mode 100644 index 000000000000..e8bbb9aa502d --- /dev/null +++ b/docs/man/man1/openshift-admin-certificate-deny.1 @@ -0,0 +1,117 @@ +.TH "OPENSHIFT ADMIN CERTIFICATE" "1" " Openshift CLI User Manuals" "Openshift" "June 2016" "" + + +.SH NAME +.PP +openshift admin certificate deny \- Deny a certificate signing request + + +.SH SYNOPSIS +.PP +\fBopenshift admin certificate deny\fP [OPTIONS] + + +.SH DESCRIPTION +.PP +Deny a certificate signing request. + +.PP +kubectl certificate deny allows a cluster admin to deny a certificate signing request (CSR). This action tells a certificate signing controller to not to issue a certificate to the requestor. + + +.SH OPTIONS +.PP +\fB\-f\fP, \fB\-\-filename\fP=[] + Filename, directory, or URL to files identifying the resource to update + +.PP +\fB\-o\fP, \fB\-\-output\fP="" + Output mode. Use "\-o name" for shorter output (resource/name). + +.PP +\fB\-R\fP, \fB\-\-recursive\fP=false + Process the directory used in \-f, \-\-filename recursively. Useful when you want to manage related manifests organized within the same directory. + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-api\-version\fP="" + DEPRECATED: The API version to use when talking to the server + +.PP +\fB\-\-as\fP="" + Username to impersonate for the operation + +.PP +\fB\-\-azure\-container\-registry\-config\fP="" + Path to the file container Azure container registry configuration information. + +.PP +\fB\-\-certificate\-authority\fP="" + Path to a cert. file for the certificate authority + +.PP +\fB\-\-client\-certificate\fP="" + Path to a client certificate file for TLS + +.PP +\fB\-\-client\-key\fP="" + Path to a client key file for TLS + +.PP +\fB\-\-cluster\fP="" + The name of the kubeconfig cluster to use + +.PP +\fB\-\-config\fP="" + Path to the config file to use for CLI requests. + +.PP +\fB\-\-context\fP="" + The name of the kubeconfig context to use + +.PP +\fB\-\-google\-json\-key\fP="" + The Google Cloud Platform Service Account JSON Key to use for authentication. + +.PP +\fB\-\-insecure\-skip\-tls\-verify\fP=false + If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure + +.PP +\fB\-\-log\-flush\-frequency\fP=0 + Maximum number of seconds between log flushes + +.PP +\fB\-\-match\-server\-version\fP=false + Require server version to match client version + +.PP +\fB\-n\fP, \fB\-\-namespace\fP="" + If present, the namespace scope for this CLI request + +.PP +\fB\-\-request\-timeout\fP="0" + The length of time to wait before giving up on a single server request. Non\-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. + +.PP +\fB\-\-server\fP="" + The address and port of the Kubernetes API server + +.PP +\fB\-\-token\fP="" + Bearer token for authentication to the API server + +.PP +\fB\-\-user\fP="" + The name of the kubeconfig user to use + + +.SH SEE ALSO +.PP +\fBopenshift\-admin\-certificate(1)\fP, + + +.SH HISTORY +.PP +June 2016, Ported from the Kubernetes man\-doc generator diff --git a/docs/man/man1/openshift-admin-certificate.1 b/docs/man/man1/openshift-admin-certificate.1 new file mode 100644 index 000000000000..c8801ba5a16b --- /dev/null +++ b/docs/man/man1/openshift-admin-certificate.1 @@ -0,0 +1,100 @@ +.TH "OPENSHIFT ADMIN" "1" " Openshift CLI User Manuals" "Openshift" "June 2016" "" + + +.SH NAME +.PP +openshift admin certificate \- Modify certificate resources. + + +.SH SYNOPSIS +.PP +\fBopenshift admin certificate\fP [OPTIONS] + + +.SH DESCRIPTION +.PP +Modify certificate resources. + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-api\-version\fP="" + DEPRECATED: The API version to use when talking to the server + +.PP +\fB\-\-as\fP="" + Username to impersonate for the operation + +.PP +\fB\-\-azure\-container\-registry\-config\fP="" + Path to the file container Azure container registry configuration information. + +.PP +\fB\-\-certificate\-authority\fP="" + Path to a cert. file for the certificate authority + +.PP +\fB\-\-client\-certificate\fP="" + Path to a client certificate file for TLS + +.PP +\fB\-\-client\-key\fP="" + Path to a client key file for TLS + +.PP +\fB\-\-cluster\fP="" + The name of the kubeconfig cluster to use + +.PP +\fB\-\-config\fP="" + Path to the config file to use for CLI requests. + +.PP +\fB\-\-context\fP="" + The name of the kubeconfig context to use + +.PP +\fB\-\-google\-json\-key\fP="" + The Google Cloud Platform Service Account JSON Key to use for authentication. + +.PP +\fB\-\-insecure\-skip\-tls\-verify\fP=false + If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure + +.PP +\fB\-\-log\-flush\-frequency\fP=0 + Maximum number of seconds between log flushes + +.PP +\fB\-\-match\-server\-version\fP=false + Require server version to match client version + +.PP +\fB\-n\fP, \fB\-\-namespace\fP="" + If present, the namespace scope for this CLI request + +.PP +\fB\-\-request\-timeout\fP="0" + The length of time to wait before giving up on a single server request. Non\-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. + +.PP +\fB\-\-server\fP="" + The address and port of the Kubernetes API server + +.PP +\fB\-\-token\fP="" + Bearer token for authentication to the API server + +.PP +\fB\-\-user\fP="" + The name of the kubeconfig user to use + + +.SH SEE ALSO +.PP +\fBopenshift\-admin(1)\fP, \fBopenshift\-admin\-certificate\-approve(1)\fP, \fBopenshift\-admin\-certificate\-deny(1)\fP, + + +.SH HISTORY +.PP +June 2016, Ported from the Kubernetes man\-doc generator diff --git a/docs/man/man1/openshift-admin.1 b/docs/man/man1/openshift-admin.1 index f4a4df244186..68979bfc9d49 100644 --- a/docs/man/man1/openshift-admin.1 +++ b/docs/man/man1/openshift-admin.1 @@ -97,7 +97,7 @@ Commands for managing a cluster are exposed here. Many administrative actions in .SH SEE ALSO .PP -\fBopenshift(1)\fP, \fBopenshift\-admin\-build\-chain(1)\fP, \fBopenshift\-admin\-ca(1)\fP, \fBopenshift\-admin\-completion(1)\fP, \fBopenshift\-admin\-config(1)\fP, \fBopenshift\-admin\-cordon(1)\fP, \fBopenshift\-admin\-create\-api\-client\-config(1)\fP, \fBopenshift\-admin\-create\-bootstrap\-policy\-file(1)\fP, \fBopenshift\-admin\-create\-bootstrap\-project\-template(1)\fP, \fBopenshift\-admin\-create\-error\-template(1)\fP, \fBopenshift\-admin\-create\-key\-pair(1)\fP, \fBopenshift\-admin\-create\-kubeconfig(1)\fP, \fBopenshift\-admin\-create\-login\-template(1)\fP, \fBopenshift\-admin\-create\-master\-certs(1)\fP, \fBopenshift\-admin\-create\-node\-config(1)\fP, \fBopenshift\-admin\-create\-provider\-selection\-template(1)\fP, \fBopenshift\-admin\-create\-server\-cert(1)\fP, \fBopenshift\-admin\-create\-signer\-cert(1)\fP, \fBopenshift\-admin\-diagnostics(1)\fP, \fBopenshift\-admin\-drain(1)\fP, \fBopenshift\-admin\-groups(1)\fP, \fBopenshift\-admin\-ipfailover(1)\fP, \fBopenshift\-admin\-manage\-node(1)\fP, \fBopenshift\-admin\-migrate(1)\fP, \fBopenshift\-admin\-new\-project(1)\fP, \fBopenshift\-admin\-options(1)\fP, \fBopenshift\-admin\-overwrite\-policy(1)\fP, \fBopenshift\-admin\-pod\-network(1)\fP, \fBopenshift\-admin\-policy(1)\fP, \fBopenshift\-admin\-prune(1)\fP, \fBopenshift\-admin\-registry(1)\fP, \fBopenshift\-admin\-router(1)\fP, \fBopenshift\-admin\-taint(1)\fP, \fBopenshift\-admin\-top(1)\fP, \fBopenshift\-admin\-uncordon(1)\fP, +\fBopenshift(1)\fP, \fBopenshift\-admin\-build\-chain(1)\fP, \fBopenshift\-admin\-ca(1)\fP, \fBopenshift\-admin\-certificate(1)\fP, \fBopenshift\-admin\-completion(1)\fP, \fBopenshift\-admin\-config(1)\fP, \fBopenshift\-admin\-cordon(1)\fP, \fBopenshift\-admin\-create\-api\-client\-config(1)\fP, \fBopenshift\-admin\-create\-bootstrap\-policy\-file(1)\fP, \fBopenshift\-admin\-create\-bootstrap\-project\-template(1)\fP, \fBopenshift\-admin\-create\-error\-template(1)\fP, \fBopenshift\-admin\-create\-key\-pair(1)\fP, \fBopenshift\-admin\-create\-kubeconfig(1)\fP, \fBopenshift\-admin\-create\-login\-template(1)\fP, \fBopenshift\-admin\-create\-master\-certs(1)\fP, \fBopenshift\-admin\-create\-node\-config(1)\fP, \fBopenshift\-admin\-create\-provider\-selection\-template(1)\fP, \fBopenshift\-admin\-create\-server\-cert(1)\fP, \fBopenshift\-admin\-create\-signer\-cert(1)\fP, \fBopenshift\-admin\-diagnostics(1)\fP, \fBopenshift\-admin\-drain(1)\fP, \fBopenshift\-admin\-groups(1)\fP, \fBopenshift\-admin\-ipfailover(1)\fP, \fBopenshift\-admin\-manage\-node(1)\fP, \fBopenshift\-admin\-migrate(1)\fP, \fBopenshift\-admin\-new\-project(1)\fP, \fBopenshift\-admin\-options(1)\fP, \fBopenshift\-admin\-overwrite\-policy(1)\fP, \fBopenshift\-admin\-pod\-network(1)\fP, \fBopenshift\-admin\-policy(1)\fP, \fBopenshift\-admin\-prune(1)\fP, \fBopenshift\-admin\-registry(1)\fP, \fBopenshift\-admin\-router(1)\fP, \fBopenshift\-admin\-taint(1)\fP, \fBopenshift\-admin\-top(1)\fP, \fBopenshift\-admin\-uncordon(1)\fP, .SH HISTORY diff --git a/docs/man/man1/openshift-cli-adm-certificate-approve.1 b/docs/man/man1/openshift-cli-adm-certificate-approve.1 new file mode 100644 index 000000000000..077c99b4ab2b --- /dev/null +++ b/docs/man/man1/openshift-cli-adm-certificate-approve.1 @@ -0,0 +1,120 @@ +.TH "OPENSHIFT CLI ADM CERTIFICATE" "1" " Openshift CLI User Manuals" "Openshift" "June 2016" "" + + +.SH NAME +.PP +openshift cli adm certificate approve \- Approve a certificate signing request + + +.SH SYNOPSIS +.PP +\fBopenshift cli adm certificate approve\fP [OPTIONS] + + +.SH DESCRIPTION +.PP +Approve a certificate signing request. + +.PP +kubectl certificate approve allows a cluster admin to approve a certificate signing request (CSR). This action tells a certificate signing controller to issue a certificate to the requestor with the attributes requested in the CSR. + +.PP +SECURITY NOTICE: Depending on the requested attributes, the issued certificate can potentially grant a requester access to cluster resources or to authenticate as a requested identity. Before approving a CSR, ensure you understand what the signed certificate can do. + + +.SH OPTIONS +.PP +\fB\-f\fP, \fB\-\-filename\fP=[] + Filename, directory, or URL to files identifying the resource to update + +.PP +\fB\-o\fP, \fB\-\-output\fP="" + Output mode. Use "\-o name" for shorter output (resource/name). + +.PP +\fB\-R\fP, \fB\-\-recursive\fP=false + Process the directory used in \-f, \-\-filename recursively. Useful when you want to manage related manifests organized within the same directory. + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-api\-version\fP="" + DEPRECATED: The API version to use when talking to the server + +.PP +\fB\-\-as\fP="" + Username to impersonate for the operation + +.PP +\fB\-\-azure\-container\-registry\-config\fP="" + Path to the file container Azure container registry configuration information. + +.PP +\fB\-\-certificate\-authority\fP="" + Path to a cert. file for the certificate authority + +.PP +\fB\-\-client\-certificate\fP="" + Path to a client certificate file for TLS + +.PP +\fB\-\-client\-key\fP="" + Path to a client key file for TLS + +.PP +\fB\-\-cluster\fP="" + The name of the kubeconfig cluster to use + +.PP +\fB\-\-config\fP="" + Path to the config file to use for CLI requests. + +.PP +\fB\-\-context\fP="" + The name of the kubeconfig context to use + +.PP +\fB\-\-google\-json\-key\fP="" + The Google Cloud Platform Service Account JSON Key to use for authentication. + +.PP +\fB\-\-insecure\-skip\-tls\-verify\fP=false + If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure + +.PP +\fB\-\-log\-flush\-frequency\fP=0 + Maximum number of seconds between log flushes + +.PP +\fB\-\-match\-server\-version\fP=false + Require server version to match client version + +.PP +\fB\-n\fP, \fB\-\-namespace\fP="" + If present, the namespace scope for this CLI request + +.PP +\fB\-\-request\-timeout\fP="0" + The length of time to wait before giving up on a single server request. Non\-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. + +.PP +\fB\-\-server\fP="" + The address and port of the Kubernetes API server + +.PP +\fB\-\-token\fP="" + Bearer token for authentication to the API server + +.PP +\fB\-\-user\fP="" + The name of the kubeconfig user to use + + +.SH SEE ALSO +.PP +\fBopenshift\-cli\-adm\-certificate(1)\fP, + + +.SH HISTORY +.PP +June 2016, Ported from the Kubernetes man\-doc generator diff --git a/docs/man/man1/openshift-cli-adm-certificate-deny.1 b/docs/man/man1/openshift-cli-adm-certificate-deny.1 new file mode 100644 index 000000000000..4f8293e2541e --- /dev/null +++ b/docs/man/man1/openshift-cli-adm-certificate-deny.1 @@ -0,0 +1,117 @@ +.TH "OPENSHIFT CLI ADM CERTIFICATE" "1" " Openshift CLI User Manuals" "Openshift" "June 2016" "" + + +.SH NAME +.PP +openshift cli adm certificate deny \- Deny a certificate signing request + + +.SH SYNOPSIS +.PP +\fBopenshift cli adm certificate deny\fP [OPTIONS] + + +.SH DESCRIPTION +.PP +Deny a certificate signing request. + +.PP +kubectl certificate deny allows a cluster admin to deny a certificate signing request (CSR). This action tells a certificate signing controller to not to issue a certificate to the requestor. + + +.SH OPTIONS +.PP +\fB\-f\fP, \fB\-\-filename\fP=[] + Filename, directory, or URL to files identifying the resource to update + +.PP +\fB\-o\fP, \fB\-\-output\fP="" + Output mode. Use "\-o name" for shorter output (resource/name). + +.PP +\fB\-R\fP, \fB\-\-recursive\fP=false + Process the directory used in \-f, \-\-filename recursively. Useful when you want to manage related manifests organized within the same directory. + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-api\-version\fP="" + DEPRECATED: The API version to use when talking to the server + +.PP +\fB\-\-as\fP="" + Username to impersonate for the operation + +.PP +\fB\-\-azure\-container\-registry\-config\fP="" + Path to the file container Azure container registry configuration information. + +.PP +\fB\-\-certificate\-authority\fP="" + Path to a cert. file for the certificate authority + +.PP +\fB\-\-client\-certificate\fP="" + Path to a client certificate file for TLS + +.PP +\fB\-\-client\-key\fP="" + Path to a client key file for TLS + +.PP +\fB\-\-cluster\fP="" + The name of the kubeconfig cluster to use + +.PP +\fB\-\-config\fP="" + Path to the config file to use for CLI requests. + +.PP +\fB\-\-context\fP="" + The name of the kubeconfig context to use + +.PP +\fB\-\-google\-json\-key\fP="" + The Google Cloud Platform Service Account JSON Key to use for authentication. + +.PP +\fB\-\-insecure\-skip\-tls\-verify\fP=false + If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure + +.PP +\fB\-\-log\-flush\-frequency\fP=0 + Maximum number of seconds between log flushes + +.PP +\fB\-\-match\-server\-version\fP=false + Require server version to match client version + +.PP +\fB\-n\fP, \fB\-\-namespace\fP="" + If present, the namespace scope for this CLI request + +.PP +\fB\-\-request\-timeout\fP="0" + The length of time to wait before giving up on a single server request. Non\-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. + +.PP +\fB\-\-server\fP="" + The address and port of the Kubernetes API server + +.PP +\fB\-\-token\fP="" + Bearer token for authentication to the API server + +.PP +\fB\-\-user\fP="" + The name of the kubeconfig user to use + + +.SH SEE ALSO +.PP +\fBopenshift\-cli\-adm\-certificate(1)\fP, + + +.SH HISTORY +.PP +June 2016, Ported from the Kubernetes man\-doc generator diff --git a/docs/man/man1/openshift-cli-adm-certificate.1 b/docs/man/man1/openshift-cli-adm-certificate.1 new file mode 100644 index 000000000000..b8e1a6fcc8f2 --- /dev/null +++ b/docs/man/man1/openshift-cli-adm-certificate.1 @@ -0,0 +1,100 @@ +.TH "OPENSHIFT CLI ADM" "1" " Openshift CLI User Manuals" "Openshift" "June 2016" "" + + +.SH NAME +.PP +openshift cli adm certificate \- Modify certificate resources. + + +.SH SYNOPSIS +.PP +\fBopenshift cli adm certificate\fP [OPTIONS] + + +.SH DESCRIPTION +.PP +Modify certificate resources. + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-api\-version\fP="" + DEPRECATED: The API version to use when talking to the server + +.PP +\fB\-\-as\fP="" + Username to impersonate for the operation + +.PP +\fB\-\-azure\-container\-registry\-config\fP="" + Path to the file container Azure container registry configuration information. + +.PP +\fB\-\-certificate\-authority\fP="" + Path to a cert. file for the certificate authority + +.PP +\fB\-\-client\-certificate\fP="" + Path to a client certificate file for TLS + +.PP +\fB\-\-client\-key\fP="" + Path to a client key file for TLS + +.PP +\fB\-\-cluster\fP="" + The name of the kubeconfig cluster to use + +.PP +\fB\-\-config\fP="" + Path to the config file to use for CLI requests. + +.PP +\fB\-\-context\fP="" + The name of the kubeconfig context to use + +.PP +\fB\-\-google\-json\-key\fP="" + The Google Cloud Platform Service Account JSON Key to use for authentication. + +.PP +\fB\-\-insecure\-skip\-tls\-verify\fP=false + If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure + +.PP +\fB\-\-log\-flush\-frequency\fP=0 + Maximum number of seconds between log flushes + +.PP +\fB\-\-match\-server\-version\fP=false + Require server version to match client version + +.PP +\fB\-n\fP, \fB\-\-namespace\fP="" + If present, the namespace scope for this CLI request + +.PP +\fB\-\-request\-timeout\fP="0" + The length of time to wait before giving up on a single server request. Non\-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. + +.PP +\fB\-\-server\fP="" + The address and port of the Kubernetes API server + +.PP +\fB\-\-token\fP="" + Bearer token for authentication to the API server + +.PP +\fB\-\-user\fP="" + The name of the kubeconfig user to use + + +.SH SEE ALSO +.PP +\fBopenshift\-cli\-adm(1)\fP, \fBopenshift\-cli\-adm\-certificate\-approve(1)\fP, \fBopenshift\-cli\-adm\-certificate\-deny(1)\fP, + + +.SH HISTORY +.PP +June 2016, Ported from the Kubernetes man\-doc generator diff --git a/docs/man/man1/openshift-cli-adm.1 b/docs/man/man1/openshift-cli-adm.1 index ef067c1ae8c1..2b49fcf11bfa 100644 --- a/docs/man/man1/openshift-cli-adm.1 +++ b/docs/man/man1/openshift-cli-adm.1 @@ -97,7 +97,7 @@ Commands for managing a cluster are exposed here. Many administrative actions in .SH SEE ALSO .PP -\fBopenshift\-cli(1)\fP, \fBopenshift\-cli\-adm\-build\-chain(1)\fP, \fBopenshift\-cli\-adm\-ca(1)\fP, \fBopenshift\-cli\-adm\-completion(1)\fP, \fBopenshift\-cli\-adm\-config(1)\fP, \fBopenshift\-cli\-adm\-cordon(1)\fP, \fBopenshift\-cli\-adm\-create\-api\-client\-config(1)\fP, \fBopenshift\-cli\-adm\-create\-bootstrap\-policy\-file(1)\fP, \fBopenshift\-cli\-adm\-create\-bootstrap\-project\-template(1)\fP, \fBopenshift\-cli\-adm\-create\-error\-template(1)\fP, \fBopenshift\-cli\-adm\-create\-key\-pair(1)\fP, \fBopenshift\-cli\-adm\-create\-kubeconfig(1)\fP, \fBopenshift\-cli\-adm\-create\-login\-template(1)\fP, \fBopenshift\-cli\-adm\-create\-master\-certs(1)\fP, \fBopenshift\-cli\-adm\-create\-node\-config(1)\fP, \fBopenshift\-cli\-adm\-create\-provider\-selection\-template(1)\fP, \fBopenshift\-cli\-adm\-create\-server\-cert(1)\fP, \fBopenshift\-cli\-adm\-create\-signer\-cert(1)\fP, \fBopenshift\-cli\-adm\-diagnostics(1)\fP, \fBopenshift\-cli\-adm\-drain(1)\fP, \fBopenshift\-cli\-adm\-groups(1)\fP, \fBopenshift\-cli\-adm\-ipfailover(1)\fP, \fBopenshift\-cli\-adm\-manage\-node(1)\fP, \fBopenshift\-cli\-adm\-migrate(1)\fP, \fBopenshift\-cli\-adm\-new\-project(1)\fP, \fBopenshift\-cli\-adm\-options(1)\fP, \fBopenshift\-cli\-adm\-overwrite\-policy(1)\fP, \fBopenshift\-cli\-adm\-pod\-network(1)\fP, \fBopenshift\-cli\-adm\-policy(1)\fP, \fBopenshift\-cli\-adm\-prune(1)\fP, \fBopenshift\-cli\-adm\-registry(1)\fP, \fBopenshift\-cli\-adm\-router(1)\fP, \fBopenshift\-cli\-adm\-taint(1)\fP, \fBopenshift\-cli\-adm\-top(1)\fP, \fBopenshift\-cli\-adm\-uncordon(1)\fP, +\fBopenshift\-cli(1)\fP, \fBopenshift\-cli\-adm\-build\-chain(1)\fP, \fBopenshift\-cli\-adm\-ca(1)\fP, \fBopenshift\-cli\-adm\-certificate(1)\fP, \fBopenshift\-cli\-adm\-completion(1)\fP, \fBopenshift\-cli\-adm\-config(1)\fP, \fBopenshift\-cli\-adm\-cordon(1)\fP, \fBopenshift\-cli\-adm\-create\-api\-client\-config(1)\fP, \fBopenshift\-cli\-adm\-create\-bootstrap\-policy\-file(1)\fP, \fBopenshift\-cli\-adm\-create\-bootstrap\-project\-template(1)\fP, \fBopenshift\-cli\-adm\-create\-error\-template(1)\fP, \fBopenshift\-cli\-adm\-create\-key\-pair(1)\fP, \fBopenshift\-cli\-adm\-create\-kubeconfig(1)\fP, \fBopenshift\-cli\-adm\-create\-login\-template(1)\fP, \fBopenshift\-cli\-adm\-create\-master\-certs(1)\fP, \fBopenshift\-cli\-adm\-create\-node\-config(1)\fP, \fBopenshift\-cli\-adm\-create\-provider\-selection\-template(1)\fP, \fBopenshift\-cli\-adm\-create\-server\-cert(1)\fP, \fBopenshift\-cli\-adm\-create\-signer\-cert(1)\fP, \fBopenshift\-cli\-adm\-diagnostics(1)\fP, \fBopenshift\-cli\-adm\-drain(1)\fP, \fBopenshift\-cli\-adm\-groups(1)\fP, \fBopenshift\-cli\-adm\-ipfailover(1)\fP, \fBopenshift\-cli\-adm\-manage\-node(1)\fP, \fBopenshift\-cli\-adm\-migrate(1)\fP, \fBopenshift\-cli\-adm\-new\-project(1)\fP, \fBopenshift\-cli\-adm\-options(1)\fP, \fBopenshift\-cli\-adm\-overwrite\-policy(1)\fP, \fBopenshift\-cli\-adm\-pod\-network(1)\fP, \fBopenshift\-cli\-adm\-policy(1)\fP, \fBopenshift\-cli\-adm\-prune(1)\fP, \fBopenshift\-cli\-adm\-registry(1)\fP, \fBopenshift\-cli\-adm\-router(1)\fP, \fBopenshift\-cli\-adm\-taint(1)\fP, \fBopenshift\-cli\-adm\-top(1)\fP, \fBopenshift\-cli\-adm\-uncordon(1)\fP, .SH HISTORY diff --git a/docs/man/man1/openshift-cli-cluster-join.1 b/docs/man/man1/openshift-cli-cluster-join.1 new file mode 100644 index 000000000000..31f9628672c6 --- /dev/null +++ b/docs/man/man1/openshift-cli-cluster-join.1 @@ -0,0 +1,214 @@ +.TH "OPENSHIFT CLI CLUSTER" "1" " Openshift CLI User Manuals" "Openshift" "June 2016" "" + + +.SH NAME +.PP +openshift cli cluster join \- Join an existing OpenShift cluster + + +.SH SYNOPSIS +.PP +\fBopenshift cli cluster join\fP [OPTIONS] + + +.SH DESCRIPTION +.PP +Add a new node to an existing OpenShift cluster + +.PP +Uses an existing connection to a Docker daemon to start an OpenShift node. You must provide a secret to connect to the master. Before running command, ensure that you can execute docker commands successfully (ie. 'docker ps'). + +.PP +Optionally, the command can create a new Docker machine for your OpenShift node using the VirtualBox driver when the \-\-create\-machine argument is specified. The machine will be named 'node' by default. To name the machine differently, use the \-\-docker\-machine=NAME argument. If the \-\-docker\-machine=NAME argument is specified, but \-\-create\-machine is not, the command will attempt to find an existing docker machine with that name and start it if it's not running. + + +.SH OPTIONS +.PP +\fB\-\-create\-machine\fP=false + Create a Docker machine if one doesn't exist + +.PP +\fB\-\-docker\-machine\fP="" + Specify the Docker machine to use + +.PP +\fB\-e\fP, \fB\-\-env\fP=[] + Specify a key\-value pair for an environment variable to set on OpenShift container + +.PP +\fB\-\-forward\-ports\fP=false + Use Docker port\-forwarding to communicate with origin container. Requires 'socat' locally. + +.PP +\fB\-\-host\-config\-dir\fP="/var/lib/origin/openshift.local.config" + Directory on Docker host for OpenShift configuration + +.PP +\fB\-\-host\-data\-dir\fP="" + Directory on Docker host for OpenShift data. If not specified, etcd data will not be persisted on the host. + +.PP +\fB\-\-host\-pv\-dir\fP="/var/lib/origin/openshift.local.pv" + Directory on host for OpenShift persistent volumes + +.PP +\fB\-\-host\-volumes\-dir\fP="/var/lib/origin/openshift.local.volumes" + Directory on Docker host for OpenShift volumes + +.PP +\fB\-\-http\-proxy\fP="" + HTTP proxy to use for master and builds + +.PP +\fB\-\-https\-proxy\fP="" + HTTPS proxy to use for master and builds + +.PP +\fB\-\-image\fP="openshift/origin" + Specify the images to use for OpenShift + +.PP +\fB\-\-image\-streams\fP="centos7" + Specify which image streams to use, centos7|rhel7 + +.PP +\fB\-\-logging\fP=false + Install logging (experimental) + +.PP +\fB\-\-metrics\fP=false + Install metrics (experimental) + +.PP +\fB\-\-no\-proxy\fP=[] + List of hosts or subnets for which a proxy should not be used + +.PP +\fB\-\-public\-hostname\fP="" + Public hostname for OpenShift cluster + +.PP +\fB\-\-routing\-suffix\fP="" + Default suffix for server routes + +.PP +\fB\-\-secret\fP="" + Pass the secret to use to connect to the cluster + +.PP +\fB\-\-server\-loglevel\fP=0 + Log level for OpenShift server + +.PP +\fB\-\-skip\-registry\-check\fP=false + Skip Docker daemon registry check + +.PP +\fB\-\-use\-existing\-config\fP=false + Use existing configuration if present + +.PP +\fB\-\-version\fP="" + Specify the tag for OpenShift images + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-api\-version\fP="" + DEPRECATED: The API version to use when talking to the server + +.PP +\fB\-\-as\fP="" + Username to impersonate for the operation + +.PP +\fB\-\-azure\-container\-registry\-config\fP="" + Path to the file container Azure container registry configuration information. + +.PP +\fB\-\-certificate\-authority\fP="" + Path to a cert. file for the certificate authority + +.PP +\fB\-\-client\-certificate\fP="" + Path to a client certificate file for TLS + +.PP +\fB\-\-client\-key\fP="" + Path to a client key file for TLS + +.PP +\fB\-\-cluster\fP="" + The name of the kubeconfig cluster to use + +.PP +\fB\-\-config\fP="" + Path to the config file to use for CLI requests. + +.PP +\fB\-\-context\fP="" + The name of the kubeconfig context to use + +.PP +\fB\-\-google\-json\-key\fP="" + The Google Cloud Platform Service Account JSON Key to use for authentication. + +.PP +\fB\-\-insecure\-skip\-tls\-verify\fP=false + If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure + +.PP +\fB\-\-log\-flush\-frequency\fP=0 + Maximum number of seconds between log flushes + +.PP +\fB\-\-match\-server\-version\fP=false + Require server version to match client version + +.PP +\fB\-n\fP, \fB\-\-namespace\fP="" + If present, the namespace scope for this CLI request + +.PP +\fB\-\-request\-timeout\fP="0" + The length of time to wait before giving up on a single server request. Non\-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. + +.PP +\fB\-\-server\fP="" + The address and port of the Kubernetes API server + +.PP +\fB\-\-token\fP="" + Bearer token for authentication to the API server + +.PP +\fB\-\-user\fP="" + The name of the kubeconfig user to use + + +.SH EXAMPLE +.PP +.RS + +.nf + # Start a new OpenShift node on a new docker machine named 'node' + openshift cli cluster join \-\-create\-machine + + # Start OpenShift node and preserve data and config between restarts + openshift cli cluster join \-\-host\-data\-dir=/mydata \-\-use\-existing\-config + + # Use a different set of images + openshift cli cluster join \-\-image="registry.example.com/origin" \-\-version="v1.1" + +.fi +.RE + + +.SH SEE ALSO +.PP +\fBopenshift\-cli\-cluster(1)\fP, + + +.SH HISTORY +.PP +June 2016, Ported from the Kubernetes man\-doc generator diff --git a/docs/man/man1/openshift-cli-cluster-up.1 b/docs/man/man1/openshift-cli-cluster-up.1 index 0ee31ecd6c19..e451dc9f5564 100644 --- a/docs/man/man1/openshift-cli-cluster-up.1 +++ b/docs/man/man1/openshift-cli-cluster-up.1 @@ -31,7 +31,7 @@ A public hostname can also be specified for the server with the \-\-public\-host .SH OPTIONS .PP \fB\-\-create\-machine\fP=false - If true, create a Docker machine if one doesn't exist + Create a Docker machine if one doesn't exist .PP \fB\-\-docker\-machine\fP="" @@ -43,7 +43,7 @@ A public hostname can also be specified for the server with the \-\-public\-host .PP \fB\-\-forward\-ports\fP=false - If true, use Docker port\-forwarding to communicate with origin container. Requires 'socat' locally. + Use Docker port\-forwarding to communicate with origin container. Requires 'socat' locally. .PP \fB\-\-host\-config\-dir\fP="/var/lib/origin/openshift.local.config" @@ -79,11 +79,11 @@ A public hostname can also be specified for the server with the \-\-public\-host .PP \fB\-\-logging\fP=false - If true, install logging (experimental) + Install logging (experimental) .PP \fB\-\-metrics\fP=false - If true, install metrics (experimental) + Install metrics (experimental) .PP \fB\-\-no\-proxy\fP=[] @@ -103,11 +103,11 @@ A public hostname can also be specified for the server with the \-\-public\-host .PP \fB\-\-skip\-registry\-check\fP=false - If true, skip Docker daemon registry check + Skip Docker daemon registry check .PP \fB\-\-use\-existing\-config\fP=false - If true, use existing configuration if present + Use existing configuration if present .PP \fB\-\-version\fP="" diff --git a/docs/man/man1/openshift-cli-cluster.1 b/docs/man/man1/openshift-cli-cluster.1 index 6646f22a75e6..a8e7259f3b53 100644 --- a/docs/man/man1/openshift-cli-cluster.1 +++ b/docs/man/man1/openshift-cli-cluster.1 @@ -18,6 +18,9 @@ Manage a local OpenShift cluster .PP The OpenShift cluster will run as an all\-in\-one container on a Docker host. The Docker host may be a local VM (ie. using docker\-machine on OS X and Windows clients), remote machine, or the local Unix host. +.PP +Use the 'up' command to start a new cluster (master and node) on a single machine. Use the 'join' command on another machine to connect to the first cluster. + .PP To use an existing Docker connection, ensure that Docker commands are working and that you can create new containers. For OS X and Windows clients, a docker\-machine with the VirtualBox driver can be created for you using the \-\-create\-machine option. @@ -104,7 +107,7 @@ Default routes are setup using xip.io and the host ip of your cluster. To use a .SH SEE ALSO .PP -\fBopenshift\-cli(1)\fP, \fBopenshift\-cli\-cluster\-down(1)\fP, \fBopenshift\-cli\-cluster\-status(1)\fP, \fBopenshift\-cli\-cluster\-up(1)\fP, +\fBopenshift\-cli(1)\fP, \fBopenshift\-cli\-cluster\-down(1)\fP, \fBopenshift\-cli\-cluster\-join(1)\fP, \fBopenshift\-cli\-cluster\-status(1)\fP, \fBopenshift\-cli\-cluster\-up(1)\fP, .SH HISTORY diff --git a/docs/man/man1/openshift-start-node.1 b/docs/man/man1/openshift-start-node.1 index 922ab54b7ea2..453e81e9ca3e 100644 --- a/docs/man/man1/openshift-start-node.1 +++ b/docs/man/man1/openshift-start-node.1 @@ -26,6 +26,10 @@ will start a node with given configuration file. The node will run in the foregr .SH OPTIONS +.PP +\fB\-\-bootstrap\fP=false + Use the provided .kubeconfig file to perform initial node setup (experimental). + .PP \fB\-\-config\fP="" Location of the node configuration file to run from. When running from a configuration file, all other command\-line arguments are ignored. diff --git a/hack/verify-govet.sh b/hack/verify-govet.sh index bc3177d1d033..a5deda30a0b5 100755 --- a/hack/verify-govet.sh +++ b/hack/verify-govet.sh @@ -44,6 +44,7 @@ ALL_DIRS=$(find_files | grep -Eo "\./([^/]+|pkg/[^/]+)" | sort -u) DIR_BLACKLIST='./hack ./pkg/api ./pkg/authorization +./pkg/bootstrap/run ./pkg/build ./pkg/client ./pkg/cmd diff --git a/pkg/bootstrap/docker/join.go b/pkg/bootstrap/docker/join.go new file mode 100644 index 000000000000..7b0d5f2b0788 --- /dev/null +++ b/pkg/bootstrap/docker/join.go @@ -0,0 +1,126 @@ +package docker + +import ( + "fmt" + "io" + "io/ioutil" + "os" + + "github.com/spf13/cobra" + "github.com/spf13/pflag" + + kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" + + "github.com/openshift/origin/pkg/bootstrap/docker/openshift" + "github.com/openshift/origin/pkg/cmd/templates" + osclientcmd "github.com/openshift/origin/pkg/cmd/util/clientcmd" +) + +// CmdJoinRecommendedName is the recommended command name +const CmdJoinRecommendedName = "join" + +var ( + cmdJoinLong = templates.LongDesc(` + Add a new node to an existing OpenShift cluster + + Uses an existing connection to a Docker daemon to start an OpenShift node. You must provide + a secret to connect to the master. Before running command, ensure that you can execute docker + commands successfully (ie. 'docker ps'). + + Optionally, the command can create a new Docker machine for your OpenShift node using the VirtualBox + driver when the --create-machine argument is specified. The machine will be named 'node' + by default. To name the machine differently, use the --docker-machine=NAME argument. If the + --docker-machine=NAME argument is specified, but --create-machine is not, the command will attempt + to find an existing docker machine with that name and start it if it's not running.`) + + cmdJoinExample = templates.Examples(` + # Start a new OpenShift node on a new docker machine named 'node' + %[1]s --create-machine + + # Start OpenShift node and preserve data and config between restarts + %[1]s --host-data-dir=/mydata --use-existing-config + + # Use a different set of images + %[1]s --image="registry.example.com/origin" --version="v1.1" +`) +) + +// NewCmdJoin creates a command that joins an existing OpenShift cluster. +func NewCmdJoin(name, fullName string, f *osclientcmd.Factory, in io.Reader, out io.Writer) *cobra.Command { + config := &ClientJoinConfig{ + CommonStartConfig: CommonStartConfig{ + Out: out, + UsePorts: []int{openshift.DefaultDNSPort, 10250}, + DNSPort: openshift.DefaultDNSPort, + }, + In: in, + } + cmd := &cobra.Command{ + Use: name, + Short: "Join an existing OpenShift cluster", + Long: cmdJoinLong, + Example: fmt.Sprintf(cmdJoinExample, fullName), + Run: func(c *cobra.Command, args []string) { + kcmdutil.CheckErr(config.Complete(f, c)) + kcmdutil.CheckErr(config.Validate(out)) + if err := config.Start(out); err != nil { + os.Exit(1) + } + }, + } + config.Bind(cmd.Flags()) + return cmd +} + +// ClientJoinConfig is the configuration for the client join command +type ClientJoinConfig struct { + CommonStartConfig + + In io.Reader + Secret string +} + +func (config *ClientJoinConfig) Bind(flags *pflag.FlagSet) { + config.CommonStartConfig.Bind(flags) + flags.StringVar(&config.Secret, "secret", "", "Pass the secret to use to connect to the cluster") +} + +// Complete initializes fields based on command parameters and execution environment +func (c *ClientJoinConfig) Complete(f *osclientcmd.Factory, cmd *cobra.Command) error { + if len(c.Secret) == 0 && c.In != nil { + fmt.Fprintf(c.Out, "Please paste the contents of your secret here and hit ENTER:\n") + data, err := ioutil.ReadAll(c.In) + if err != nil { + return err + } + c.Secret = string(data) + } + + if err := c.CommonStartConfig.Complete(f, cmd); err != nil { + return err + } + + // Create an OpenShift configuration and start a container that uses it. + c.addTask("Joining OpenShift cluster", c.StartOpenShiftNode) + + return nil +} + +// StartOpenShiftNode starts the OpenShift container as a node +func (c *ClientJoinConfig) StartOpenShiftNode(out io.Writer) error { + opt := &openshift.StartOptions{ + ServerIP: c.ServerIP, + UseSharedVolume: !c.UseNsenterMount, + SetPropagationMode: c.SetPropagationMode, + Images: c.imageFormat(), + HostVolumesDir: c.HostVolumesDir, + HostConfigDir: c.HostConfigDir, + HostDataDir: c.HostDataDir, + UseExistingConfig: c.UseExistingConfig, + Environment: c.Environment, + LogLevel: c.ServerLogLevel, + DNSPort: c.DNSPort, + KubeconfigContents: c.Secret, + } + return c.OpenShiftHelper().StartNode(opt, out) +} diff --git a/pkg/bootstrap/docker/openshift/helper.go b/pkg/bootstrap/docker/openshift/helper.go index 12d5316c8c4c..f4f416d457db 100644 --- a/pkg/bootstrap/docker/openshift/helper.go +++ b/pkg/bootstrap/docker/openshift/helper.go @@ -75,6 +75,7 @@ type Helper struct { type StartOptions struct { ServerIP string RouterIP string + RoutingSuffix string DNSPort int UseSharedVolume bool SetPropagationMode bool @@ -92,6 +93,7 @@ type StartOptions struct { HTTPProxy string HTTPSProxy string NoProxy []string + KubeconfigContents string } // NewHelper creates a new OpenShift helper @@ -326,8 +328,7 @@ func (h *Helper) Start(opt *StartOptions, out io.Writer) (string, error) { if err != nil { return "", errors.NewError("could not copy OpenShift configuration").WithCause(err) } - err = h.updateConfig(configDir, opt) - if err != nil { + if err := h.updateConfig(configDir, opt); err != nil { cleanupConfig() return "", errors.NewError("could not update OpenShift configuration").WithCause(err) } @@ -439,6 +440,73 @@ func (h *Helper) Start(opt *StartOptions, out io.Writer) (string, error) { return configDir, nil } +// StartNode starts the OpenShift node as a Docker container +// and returns a directory in the local file system where +// the OpenShift configuration has been copied +func (h *Helper) StartNode(opt *StartOptions, out io.Writer) error { + binds := openShiftContainerBinds + env := []string{} + if opt.UseSharedVolume { + binds = append(binds, fmt.Sprintf("%[1]s:%[1]s:shared", opt.HostVolumesDir)) + env = append(env, "OPENSHIFT_CONTAINERIZED=false") + } else { + binds = append(binds, "/:/rootfs:ro") + propagationMode := "" + if opt.SetPropagationMode { + propagationMode = ":rslave" + } + binds = append(binds, fmt.Sprintf("%[1]s:%[1]s%[2]s", opt.HostVolumesDir, propagationMode)) + } + env = append(env, opt.Environment...) + + kubeconfig := "/var/lib/origin/openshift.local.config/node/node-bootstrap.kubeconfig" + + fmt.Fprintf(out, "Starting OpenShift Node using container '%s'\n", h.containerName) + startCmd := []string{ + "start", "node", "--bootstrap", + fmt.Sprintf("--kubeconfig=%s", kubeconfig), + } + if opt.LogLevel > 0 { + startCmd = append(startCmd, fmt.Sprintf("--loglevel=%d", opt.LogLevel)) + } + + _, err := h.runHelper.New().Image(h.image). + Name(h.containerName). + Privileged(). + HostNetwork(). + HostPid(). + Bind(binds...). + Env(env...). + Command(startCmd...). + Copy(map[string][]byte{ + kubeconfig: []byte(opt.KubeconfigContents), + }). + Start() + if err != nil { + return errors.NewError("cannot start OpenShift Node daemon").WithCause(err) + } + + // Wait a minimum amount of time and check whether we're still running. If not, we know the daemon didn't start + time.Sleep(initialStatusCheckWait) + _, running, err := h.dockerHelper.GetContainerState(h.containerName) + if err != nil { + return errors.NewError("cannot get state of OpenShift container %s", h.containerName).WithCause(err) + } + if !running { + return ErrOpenShiftFailedToStart(h.containerName).WithDetails(h.OriginLog()) + } + + // Wait until the API server is listening + fmt.Fprintf(out, "Waiting for server to start listening\n") + masterHost := fmt.Sprintf("%s:10250", opt.ServerIP) + if err = cmdutil.WaitForSuccessfulDial(true, "tcp", masterHost, 200*time.Millisecond, 1*time.Second, serverUpTimeout); err != nil { + return ErrTimedOutWaitingForStart(h.containerName).WithDetails(h.OriginLog()) + } + + fmt.Fprintf(out, "OpenShift server started\n") + return nil +} + func (h *Helper) OriginLog() string { log := h.dockerHelper.ContainerLog(h.containerName, 10) if len(log) > 0 { @@ -521,8 +589,8 @@ func (h *Helper) updateConfig(configDir string, opt *StartOptions) error { return err } - if len(h.routingSuffix) > 0 { - cfg.RoutingConfig.Subdomain = h.routingSuffix + if len(opt.RoutingSuffix) > 0 { + cfg.RoutingConfig.Subdomain = opt.RoutingSuffix } else { cfg.RoutingConfig.Subdomain = fmt.Sprintf("%s.xip.io", opt.RouterIP) } diff --git a/pkg/bootstrap/docker/run/run.go b/pkg/bootstrap/docker/run/run.go index a29136961492..6a01dc9be024 100644 --- a/pkg/bootstrap/docker/run/run.go +++ b/pkg/bootstrap/docker/run/run.go @@ -1,8 +1,10 @@ package run import ( + "archive/tar" "bytes" "fmt" + "io" docker "github.com/fsouza/go-dockerclient" "github.com/golang/glog" @@ -35,6 +37,7 @@ type Runner struct { config *docker.Config hostConfig *docker.HostConfig removeContainer bool + copies map[string][]byte } // Name sets the name of the container to create @@ -78,6 +81,11 @@ func (h *Runner) Command(cmd ...string) *Runner { return h } +func (h *Runner) Copy(contents map[string][]byte) *Runner { + h.copies = contents + return h +} + // HostPid tells Docker to run using the host's pid namespace func (h *Runner) HostPid() *Runner { h.hostConfig.PidMode = "host" @@ -126,6 +134,9 @@ func (h *Runner) Start() (string, error) { if err != nil { return "", err } + if err := h.copy(id); err != nil { + return id, err + } return id, h.startContainer(id) } @@ -155,6 +166,46 @@ func (h *Runner) Create() (string, error) { return container.ID, nil } +func (h *Runner) copy(id string) error { + if len(h.copies) == 0 { + return nil + } + archive := streamingArchive(h.copies) + defer archive.Close() + err := h.client.UploadToContainer(id, docker.UploadToContainerOptions{ + InputStream: archive, + Path: "/", + NoOverwriteDirNonDir: true, + }) + return err +} + +// streamingArchive returns a ReadCloser containing a tar archive with contents serialized as files. +func streamingArchive(contents map[string][]byte) io.ReadCloser { + r, w := io.Pipe() + go func() { + archive := tar.NewWriter(w) + for k, v := range contents { + if err := archive.WriteHeader(&tar.Header{ + Name: k, + Mode: 0644, + Size: int64(len(v)), + Typeflag: tar.TypeReg, + }); err != nil { + w.CloseWithError(err) + return + } + if _, err := archive.Write(v); err != nil { + w.CloseWithError(err) + return + } + } + archive.Close() + w.Close() + }() + return r +} + func (h *Runner) startContainer(id string) error { err := h.client.StartContainer(id, nil) if err != nil { diff --git a/pkg/bootstrap/docker/up.go b/pkg/bootstrap/docker/up.go index f5a9660af0bb..40622469ed70 100644 --- a/pkg/bootstrap/docker/up.go +++ b/pkg/bootstrap/docker/up.go @@ -16,6 +16,7 @@ import ( docker "github.com/fsouza/go-dockerclient" "github.com/golang/glog" "github.com/spf13/cobra" + "github.com/spf13/pflag" kerrors "k8s.io/kubernetes/pkg/api/errors" kclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" @@ -42,7 +43,7 @@ const ( // CmdUpRecommendedName is the recommended command name CmdUpRecommendedName = "up" - openShiftNamespace = "openshift" + openshiftNamespace = "openshift" initialUser = "developer" initialPassword = "developer" @@ -118,8 +119,12 @@ var ( // NewCmdUp creates a command that starts openshift on Docker with reasonable defaults func NewCmdUp(name, fullName string, f *osclientcmd.Factory, out, errout io.Writer) *cobra.Command { config := &ClientStartConfig{ - Out: out, - PortForwarding: defaultPortForwarding(), + CommonStartConfig: CommonStartConfig{ + Out: out, + UsePorts: openshift.DefaultPorts, + PortForwarding: defaultPortForwarding(), + DNSPort: openshift.DefaultDNSPort, + }, } cmd := &cobra.Command{ Use: name, @@ -134,27 +139,7 @@ func NewCmdUp(name, fullName string, f *osclientcmd.Factory, out, errout io.Writ } }, } - cmd.Flags().BoolVar(&config.ShouldCreateDockerMachine, "create-machine", false, "If true, create a Docker machine if one doesn't exist") - cmd.Flags().StringVar(&config.DockerMachine, "docker-machine", "", "Specify the Docker machine to use") - cmd.Flags().StringVar(&config.ImageVersion, "version", "", "Specify the tag for OpenShift images") - cmd.Flags().StringVar(&config.Image, "image", "openshift/origin", "Specify the images to use for OpenShift") - cmd.Flags().StringVar(&config.ImageStreams, "image-streams", "centos7", "Specify which image streams to use, centos7|rhel7") - cmd.Flags().BoolVar(&config.SkipRegistryCheck, "skip-registry-check", false, "If true, skip Docker daemon registry check") - cmd.Flags().StringVar(&config.PublicHostname, "public-hostname", "", "Public hostname for OpenShift cluster") - cmd.Flags().StringVar(&config.RoutingSuffix, "routing-suffix", "", "Default suffix for server routes") - cmd.Flags().BoolVar(&config.UseExistingConfig, "use-existing-config", false, "If true, use existing configuration if present") - cmd.Flags().StringVar(&config.HostConfigDir, "host-config-dir", host.DefaultConfigDir, "Directory on Docker host for OpenShift configuration") - cmd.Flags().StringVar(&config.HostVolumesDir, "host-volumes-dir", host.DefaultVolumesDir, "Directory on Docker host for OpenShift volumes") - cmd.Flags().StringVar(&config.HostPersistentVolumesDir, "host-pv-dir", host.DefaultPersistentVolumesDir, "Directory on host for OpenShift persistent volumes") - cmd.Flags().StringVar(&config.HostDataDir, "host-data-dir", "", "Directory on Docker host for OpenShift data. If not specified, etcd data will not be persisted on the host.") - cmd.Flags().BoolVar(&config.PortForwarding, "forward-ports", config.PortForwarding, "If true, use Docker port-forwarding to communicate with origin container. Requires 'socat' locally.") - cmd.Flags().IntVar(&config.ServerLogLevel, "server-loglevel", 0, "Log level for OpenShift server") - cmd.Flags().StringArrayVarP(&config.Environment, "env", "e", config.Environment, "Specify a key-value pair for an environment variable to set on OpenShift container") - cmd.Flags().BoolVar(&config.ShouldInstallMetrics, "metrics", false, "If true, install metrics (experimental)") - cmd.Flags().BoolVar(&config.ShouldInstallLogging, "logging", false, "If true, install logging (experimental)") - cmd.Flags().StringVar(&config.HTTPProxy, "http-proxy", "", "HTTP proxy to use for master and builds") - cmd.Flags().StringVar(&config.HTTPSProxy, "https-proxy", "", "HTTPS proxy to use for master and builds") - cmd.Flags().StringArrayVar(&config.NoProxy, "no-proxy", config.NoProxy, "List of hosts or subnets for which a proxy should not be used") + config.Bind(cmd.Flags()) return cmd } @@ -171,8 +156,7 @@ type task struct { condition conditionFunc } -// ClientStartConfig is the configuration for the client start command -type ClientStartConfig struct { +type CommonStartConfig struct { ImageVersion string Image string ImageStreams string @@ -183,36 +167,37 @@ type ClientStartConfig struct { ShouldInstallLogging bool PortForwarding bool - UseNsenterMount bool - SetPropagationMode bool - Out io.Writer - TaskPrinter *TaskPrinter - Tasks []task - HostName string - ServerIP string - RouterIP string - CACert string - PublicHostname string - RoutingSuffix string - DNSPort int + Out io.Writer + TaskPrinter *TaskPrinter + Tasks []task + HostName string LocalConfigDir string + UseExistingConfig bool + Environment []string + ServerLogLevel int HostVolumesDir string HostConfigDir string HostDataDir string + UsePorts []int + DNSPort int + ServerIP string + UseNsenterMount bool + PublicHostname string + RoutingSuffix string HostPersistentVolumesDir string - UseExistingConfig bool - Environment []string - ServerLogLevel int HTTPProxy string HTTPSProxy string NoProxy []string + SetPropagationMode bool + RouterIP string + CACert string dockerClient *docker.Client engineAPIClient *dockerclient.Client dockerHelper *dockerhelper.Helper hostHelper *host.HostHelper - openShiftHelper *openshift.Helper + openshiftHelper *openshift.Helper factory *clientcmd.Factory originalFactory *clientcmd.Factory command *cobra.Command @@ -226,17 +211,74 @@ type ClientStartConfig struct { containerNetworkErr chan error } -func (c *ClientStartConfig) addTask(name string, fn taskFunc) { +func (c *CommonStartConfig) addTask(name string, fn taskFunc) { c.addConditionalTask(name, fn, nil) } -func (c *ClientStartConfig) addConditionalTask(name string, fn taskFunc, condition conditionFunc) { +func (c *CommonStartConfig) addConditionalTask(name string, fn taskFunc, condition conditionFunc) { c.Tasks = append(c.Tasks, task{name: name, fn: fn, condition: condition}) } -// Complete initializes fields in StartConfig based on command parameters -// and execution environment -func (c *ClientStartConfig) Complete(f *osclientcmd.Factory, cmd *cobra.Command) error { +func (config *CommonStartConfig) Bind(flags *pflag.FlagSet) { + flags.BoolVar(&config.ShouldCreateDockerMachine, "create-machine", false, "Create a Docker machine if one doesn't exist") + flags.StringVar(&config.DockerMachine, "docker-machine", "", "Specify the Docker machine to use") + flags.StringVar(&config.ImageVersion, "version", "", "Specify the tag for OpenShift images") + flags.StringVar(&config.Image, "image", "openshift/origin", "Specify the images to use for OpenShift") + flags.StringVar(&config.ImageStreams, "image-streams", "centos7", "Specify which image streams to use, centos7|rhel7") + flags.BoolVar(&config.SkipRegistryCheck, "skip-registry-check", false, "Skip Docker daemon registry check") + flags.StringVar(&config.PublicHostname, "public-hostname", "", "Public hostname for OpenShift cluster") + flags.StringVar(&config.RoutingSuffix, "routing-suffix", "", "Default suffix for server routes") + flags.BoolVar(&config.UseExistingConfig, "use-existing-config", false, "Use existing configuration if present") + flags.StringVar(&config.HostConfigDir, "host-config-dir", host.DefaultConfigDir, "Directory on Docker host for OpenShift configuration") + flags.StringVar(&config.HostVolumesDir, "host-volumes-dir", host.DefaultVolumesDir, "Directory on Docker host for OpenShift volumes") + flags.StringVar(&config.HostDataDir, "host-data-dir", "", "Directory on Docker host for OpenShift data. If not specified, etcd data will not be persisted on the host.") + flags.StringVar(&config.HostPersistentVolumesDir, "host-pv-dir", host.DefaultPersistentVolumesDir, "Directory on host for OpenShift persistent volumes") + flags.BoolVar(&config.PortForwarding, "forward-ports", config.PortForwarding, "Use Docker port-forwarding to communicate with origin container. Requires 'socat' locally.") + flags.IntVar(&config.ServerLogLevel, "server-loglevel", 0, "Log level for OpenShift server") + flags.StringArrayVarP(&config.Environment, "env", "e", config.Environment, "Specify a key-value pair for an environment variable to set on OpenShift container") + flags.BoolVar(&config.ShouldInstallMetrics, "metrics", false, "Install metrics (experimental)") + flags.BoolVar(&config.ShouldInstallLogging, "logging", false, "Install logging (experimental)") + flags.StringVar(&config.HTTPProxy, "http-proxy", "", "HTTP proxy to use for master and builds") + flags.StringVar(&config.HTTPSProxy, "https-proxy", "", "HTTPS proxy to use for master and builds") + flags.StringArrayVar(&config.NoProxy, "no-proxy", config.NoProxy, "List of hosts or subnets for which a proxy should not be used") +} + +// Validate validates that required fields in StartConfig have been populated +func (c *CommonStartConfig) Validate(out io.Writer) error { + if len(c.Tasks) == 0 { + return fmt.Errorf("no startup tasks to execute") + } + return nil +} + +// Start runs the start tasks ensuring that they are executed in sequence +func (c *CommonStartConfig) Start(out io.Writer) error { + for _, task := range c.Tasks { + if task.condition != nil && !task.condition() { + continue + } + c.TaskPrinter.StartTask(task.name) + w := c.TaskPrinter.TaskWriter() + err := task.fn(w) + if err != nil { + c.TaskPrinter.Failure(err) + return err + } + c.TaskPrinter.Success() + } + return nil +} + +// ClientStartConfig is the configuration for the client start command +type ClientStartConfig struct { + CommonStartConfig +} + +func (config *ClientStartConfig) Bind(flags *pflag.FlagSet) { + config.CommonStartConfig.Bind(flags) +} + +func (c *CommonStartConfig) Complete(f *osclientcmd.Factory, cmd *cobra.Command) error { c.TaskPrinter = NewTaskPrinter(c.Out) c.originalFactory = f c.command = cmd @@ -262,7 +304,7 @@ func (c *ClientStartConfig) Complete(f *osclientcmd.Factory, cmd *cobra.Command) // Ensure that the OpenShift Docker image is available. If not present, // pull it. - c.addTask(fmt.Sprintf("Checking for %s image", c.openShiftImage()), c.CheckOpenShiftImage) + c.addTask(fmt.Sprintf("Checking for %s image", c.openshiftImage()), c.CheckOpenShiftImage) // Ensure that the Docker daemon has the right --insecure-registry argument. If // not, then exit. @@ -289,6 +331,15 @@ func (c *ClientStartConfig) Complete(f *osclientcmd.Factory, cmd *cobra.Command) // Each IP is tested to ensure that it can be accessed from the current client c.addTask("Finding server IP", c.DetermineServerIP) + return nil +} + +// Complete initializes fields based on command parameters and execution environment +func (c *ClientStartConfig) Complete(f *osclientcmd.Factory, cmd *cobra.Command) error { + if err := c.CommonStartConfig.Complete(f, cmd); err != nil { + return err + } + // Create an OpenShift configuration and start a container that uses it. c.addTask("Starting OpenShift container", c.StartOpenShift) @@ -374,7 +425,7 @@ func defaultImageVersion() string { } // CreateDockerMachine will create a new Docker machine to run OpenShift -func (c *ClientStartConfig) CreateDockerMachine(out io.Writer) error { +func (c *CommonStartConfig) CreateDockerMachine(out io.Writer) error { if len(c.DockerMachine) == 0 { c.DockerMachine = defaultDockerMachineName } @@ -384,7 +435,7 @@ func (c *ClientStartConfig) CreateDockerMachine(out io.Writer) error { // CheckOpenShiftClient ensures that the client can be configured // for the new server -func (c *ClientStartConfig) CheckOpenShiftClient(out io.Writer) error { +func (c *CommonStartConfig) CheckOpenShiftClient(out io.Writer) error { kubeConfig := os.Getenv("KUBECONFIG") if len(kubeConfig) == 0 { return nil @@ -425,7 +476,7 @@ func (c *ClientStartConfig) CheckOpenShiftClient(out io.Writer) error { // GetDockerClient obtains a new Docker client from the environment or // from a Docker machine, starting it if necessary -func (c *ClientStartConfig) GetDockerClient(out io.Writer) error { +func (c *CommonStartConfig) GetDockerClient(out io.Writer) error { dockerClient, engineAPIClient, err := getDockerClient(out, c.DockerMachine, true) if err != nil { return err @@ -496,7 +547,7 @@ func getDockerClient(out io.Writer, dockerMachine string, canStartDockerMachine // CheckExistingOpenShiftContainer checks the state of an OpenShift container. If one // is already running, it throws an error. If one exists, it removes it so a new one // can be created. -func (c *ClientStartConfig) CheckExistingOpenShiftContainer(out io.Writer) error { +func (c *CommonStartConfig) CheckExistingOpenShiftContainer(out io.Writer) error { container, running, err := c.DockerHelper().GetContainerState(openshift.OpenShiftContainer) if err != nil { return errors.NewError("unexpected error while checking OpenShift container state").WithCause(err) @@ -516,12 +567,12 @@ func (c *ClientStartConfig) CheckExistingOpenShiftContainer(out io.Writer) error // CheckOpenShiftImage checks whether the OpenShift image exists. If not it tells the // Docker daemon to pull it. -func (c *ClientStartConfig) CheckOpenShiftImage(out io.Writer) error { - return c.DockerHelper().CheckAndPull(c.openShiftImage(), out) +func (c *CommonStartConfig) CheckOpenShiftImage(out io.Writer) error { + return c.DockerHelper().CheckAndPull(c.openshiftImage(), out) } // CheckDockerInsecureRegistry checks whether the Docker daemon is using the right --insecure-registry argument -func (c *ClientStartConfig) CheckDockerInsecureRegistry(out io.Writer) error { +func (c *CommonStartConfig) CheckDockerInsecureRegistry(out io.Writer) error { hasArg, err := c.DockerHelper().HasInsecureRegistryArg() if err != nil { return err @@ -534,7 +585,7 @@ func (c *ClientStartConfig) CheckDockerInsecureRegistry(out io.Writer) error { // CheckNsenterMounter checks whether the Docker host can use the nsenter mounter from Kubernetes. Otherwise, // a shared volume is needed in Docker -func (c *ClientStartConfig) CheckNsenterMounter(out io.Writer) error { +func (c *CommonStartConfig) CheckNsenterMounter(out io.Writer) error { var err error c.UseNsenterMount, err = c.HostHelper().CanUseNsenterMounter() if c.UseNsenterMount { @@ -547,7 +598,7 @@ func (c *ClientStartConfig) CheckNsenterMounter(out io.Writer) error { // CheckDockerVersion checks that the appropriate Docker version is installed based on whether we are using the nsenter mounter // or shared volumes for OpenShift -func (c *ClientStartConfig) CheckDockerVersion(io.Writer) error { +func (c *CommonStartConfig) CheckDockerVersion(io.Writer) error { ver, rh, err := c.DockerHelper().Version() if err != nil { return err @@ -564,17 +615,8 @@ func (c *ClientStartConfig) CheckDockerVersion(io.Writer) error { return nil } -func (c *ClientStartConfig) EnsureHostDirectories(io.Writer) error { - err := c.HostHelper().EnsureHostDirectories() - if err != nil { - return err - } - // A host volume share is not needed if using the nsenter mounter - if c.UseNsenterMount { - glog.V(5).Infof("Volume share is not needed when using nsenter mounter.") - return nil - } - return c.HostHelper().EnsureVolumeShare() +func (c *CommonStartConfig) EnsureHostDirectories(io.Writer) error { + return c.HostHelper().EnsureHostDirectories() } // EnsureDefaultRedirectURIs merges a default URL to an auth client's RedirectURIs array @@ -618,10 +660,18 @@ func (c *ClientStartConfig) EnsureDefaultRedirectURIs(out io.Writer) error { return nil } +// CheckAvailablePorts ensures that ports used by OpenShift are available on the Docker host +func (c *CommonStartConfig) CheckAvailablePorts(out io.Writer) error { + err := c.OpenShiftHelper().TestPorts(openshift.DefaultPorts) + if err == nil { + return nil + } + return errors.NewError("a port needed by OpenShift is not available").WithCause(err) +} + // CheckAvailablePorts ensures that ports used by OpenShift are available on the Docker host func (c *ClientStartConfig) CheckAvailablePorts(out io.Writer) error { - c.DNSPort = openshift.DefaultDNSPort - err := c.OpenShiftHelper().TestPorts(openshift.AllPorts) + err := c.CommonStartConfig.CheckAvailablePorts(out) if err == nil { return nil } @@ -649,7 +699,7 @@ func (c *ClientStartConfig) CheckAvailablePorts(out io.Writer) error { } // DetermineServerIP gets an appropriate IP address to communicate with the OpenShift server -func (c *ClientStartConfig) DetermineServerIP(out io.Writer) error { +func (c *CommonStartConfig) DetermineServerIP(out io.Writer) error { ip, err := c.determineIP(out) if err != nil { return errors.NewError("cannot determine a server IP to use").WithCause(err) @@ -691,22 +741,24 @@ func (c *ClientStartConfig) StartOpenShift(out io.Writer) error { } opt := &openshift.StartOptions{ - ServerIP: c.ServerIP, - RouterIP: c.RouterIP, - UseSharedVolume: !c.UseNsenterMount, - SetPropagationMode: c.SetPropagationMode, - Images: c.imageFormat(), - HostVolumesDir: c.HostVolumesDir, - HostConfigDir: c.HostConfigDir, - HostDataDir: c.HostDataDir, - UseExistingConfig: c.UseExistingConfig, - Environment: c.Environment, - LogLevel: c.ServerLogLevel, - DNSPort: c.DNSPort, - PortForwarding: c.PortForwarding, - HTTPProxy: c.HTTPProxy, - HTTPSProxy: c.HTTPSProxy, - NoProxy: c.NoProxy, + ServerIP: c.ServerIP, + RouterIP: c.RouterIP, + RoutingSuffix: c.RoutingSuffix, + UseSharedVolume: !c.UseNsenterMount, + SetPropagationMode: c.SetPropagationMode, + Images: c.imageFormat(), + HostVolumesDir: c.HostVolumesDir, + HostConfigDir: c.HostConfigDir, + HostDataDir: c.HostDataDir, + HostPersistentVolumesDir: c.HostPersistentVolumesDir, + UseExistingConfig: c.UseExistingConfig, + Environment: c.Environment, + LogLevel: c.ServerLogLevel, + DNSPort: c.DNSPort, + PortForwarding: c.PortForwarding, + HTTPProxy: c.HTTPProxy, + HTTPSProxy: c.HTTPSProxy, + NoProxy: c.NoProxy, } if c.ShouldInstallMetrics { opt.MetricsHost = openshift.MetricsHost(c.RoutingSuffix, c.ServerIP) @@ -750,7 +802,7 @@ func (c *ClientStartConfig) CheckContainerNetworking(out io.Writer) error { return nil } -func (c *ClientStartConfig) imageFormat() string { +func (c *CommonStartConfig) imageFormat() string { return fmt.Sprintf("%s-${component}:%s", c.Image, c.ImageVersion) } @@ -948,23 +1000,23 @@ func (c *ClientStartConfig) Clients() (*client.Client, kclientset.Interface, err } // OpenShiftHelper returns a helper object to work with OpenShift on the server -func (c *ClientStartConfig) OpenShiftHelper() *openshift.Helper { - if c.openShiftHelper == nil { - c.openShiftHelper = openshift.NewHelper(c.dockerClient, c.HostHelper(), c.openShiftImage(), openshift.OpenShiftContainer, c.PublicHostname, c.RoutingSuffix) +func (c *CommonStartConfig) OpenShiftHelper() *openshift.Helper { + if c.openshiftHelper == nil { + c.openshiftHelper = openshift.NewHelper(c.dockerClient, c.HostHelper(), c.openshiftImage(), openshift.OpenShiftContainer, c.PublicHostname, c.RoutingSuffix) } - return c.openShiftHelper + return c.openshiftHelper } // HostHelper returns a helper object to check Host configuration -func (c *ClientStartConfig) HostHelper() *host.HostHelper { +func (c *CommonStartConfig) HostHelper() *host.HostHelper { if c.hostHelper == nil { - c.hostHelper = host.NewHostHelper(c.dockerClient, c.openShiftImage(), c.HostVolumesDir, c.HostConfigDir, c.HostDataDir, c.HostPersistentVolumesDir) + c.hostHelper = host.NewHostHelper(c.dockerClient, c.openshiftImage(), c.HostVolumesDir, c.HostConfigDir, c.HostDataDir, c.HostPersistentVolumesDir) } return c.hostHelper } // DockerHelper returns a helper object to work with the Docker client -func (c *ClientStartConfig) DockerHelper() *dockerhelper.Helper { +func (c *CommonStartConfig) DockerHelper() *dockerhelper.Helper { if c.dockerHelper == nil { c.dockerHelper = dockerhelper.NewHelper(c.dockerClient, c.engineAPIClient) } @@ -978,7 +1030,7 @@ func (c *ClientStartConfig) importObjects(out io.Writer, locations map[string]st } for name, location := range locations { glog.V(2).Infof("Importing %s from %s", name, location) - err = openshift.ImportObjects(f, openShiftNamespace, location) + err = openshift.ImportObjects(f, openshiftNamespace, location) if err != nil { return errors.NewError("cannot import %s", name).WithCause(err).WithDetails(c.OpenShiftHelper().OriginLog()) } @@ -986,7 +1038,7 @@ func (c *ClientStartConfig) importObjects(out io.Writer, locations map[string]st return nil } -func (c *ClientStartConfig) openShiftImage() string { +func (c *CommonStartConfig) openshiftImage() string { return fmt.Sprintf("%s:%s", c.Image, c.ImageVersion) } @@ -1002,8 +1054,8 @@ func getDockerMachineClient(machine string, out io.Writer, canStart bool) (*dock return dockermachine.Client(machine) } -func (c *ClientStartConfig) determineIP(out io.Writer) (string, error) { - if ip := net.ParseIP(c.PublicHostname); ip != nil && !ip.IsUnspecified() { +func (c *CommonStartConfig) determineIP(out io.Writer) (string, error) { + if ip := net.ParseIP(c.HostName); ip != nil && !ip.IsUnspecified() { fmt.Fprintf(out, "Using public hostname IP %s as the host IP\n", ip) return ip.String(), nil } diff --git a/pkg/cmd/admin/admin.go b/pkg/cmd/admin/admin.go index 13bc7f818cb6..2e147c646626 100644 --- a/pkg/cmd/admin/admin.go +++ b/pkg/cmd/admin/admin.go @@ -6,7 +6,7 @@ import ( "github.com/spf13/cobra" - kubectl "k8s.io/kubernetes/pkg/kubectl/cmd" + kubecmd "k8s.io/kubernetes/pkg/kubectl/cmd" kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" "github.com/openshift/origin/pkg/cmd/admin/cert" @@ -66,6 +66,7 @@ func NewCommandAdmin(name, fullName string, in io.Reader, out io.Writer, errout groups.NewCmdGroups(groups.GroupsRecommendedName, fullName+" "+groups.GroupsRecommendedName, f, out, errout), cert.NewCmdCert(cert.CertRecommendedName, fullName+" "+cert.CertRecommendedName, out, errout), admin.NewCommandOverwriteBootstrapPolicy(admin.OverwriteBootstrapPolicyCommandName, fullName+" "+admin.OverwriteBootstrapPolicyCommandName, fullName+" "+admin.CreateBootstrapPolicyFileCommand, out), + kubecmd.NewCmdCertificate(f, out), }, }, { @@ -73,10 +74,10 @@ func NewCommandAdmin(name, fullName string, in io.Reader, out io.Writer, errout Commands: []*cobra.Command{ admin.NewCommandNodeConfig(admin.NodeConfigCommandName, fullName+" "+admin.NodeConfigCommandName, out), node.NewCommandManageNode(f, node.ManageNodeCommandName, fullName+" "+node.ManageNodeCommandName, out, errout), - cmdutil.ReplaceCommandName("kubectl", fullName, templates.Normalize(kubectl.NewCmdCordon(f, out))), - cmdutil.ReplaceCommandName("kubectl", fullName, templates.Normalize(kubectl.NewCmdUncordon(f, out))), - cmdutil.ReplaceCommandName("kubectl", fullName, templates.Normalize(kubectl.NewCmdDrain(f, out, errout))), - cmdutil.ReplaceCommandName("kubectl", fullName, templates.Normalize(kubectl.NewCmdTaint(f, out))), + cmdutil.ReplaceCommandName("kubectl", fullName, templates.Normalize(kubecmd.NewCmdCordon(f, out))), + cmdutil.ReplaceCommandName("kubectl", fullName, templates.Normalize(kubecmd.NewCmdUncordon(f, out))), + cmdutil.ReplaceCommandName("kubectl", fullName, templates.Normalize(kubecmd.NewCmdDrain(f, out, errout))), + cmdutil.ReplaceCommandName("kubectl", fullName, templates.Normalize(kubecmd.NewCmdTaint(f, out))), network.NewCmdPodNetwork(network.PodNetworkCommandName, fullName+" "+network.PodNetworkCommandName, f, out, errout), }, }, diff --git a/pkg/cmd/cli/cli.go b/pkg/cmd/cli/cli.go index 622f56907723..81049c6604ef 100644 --- a/pkg/cmd/cli/cli.go +++ b/pkg/cmd/cli/cli.go @@ -100,8 +100,7 @@ func NewCommandCLI(name, fullName string, in io.Reader, out, errout io.Writer) * cmd.NewCmdProject(fullName+" project", f, out), cmd.NewCmdProjects(fullName, f, out), cmd.NewCmdExplain(fullName, f, out, errout), - cluster.NewCmdCluster(cluster.ClusterRecommendedName, fullName+" "+cluster.ClusterRecommendedName, f, out, errout), - cmd.NewCmdIdle(fullName, f, out, errout), + cluster.NewCmdCluster(cluster.ClusterRecommendedName, fullName+" "+cluster.ClusterRecommendedName, f, in, out, errout), }, }, { @@ -160,6 +159,7 @@ func NewCommandCLI(name, fullName string, in io.Reader, out, errout io.Writer) * cmd.NewCmdProcess(fullName, f, in, out, errout), cmd.NewCmdExport(fullName, f, in, out), cmd.NewCmdExtract(fullName, f, in, out, errout), + cmd.NewCmdIdle(fullName, f, out, errout), observe.NewCmdObserve(fullName, f, out, errout), policy.NewCmdPolicy(policy.PolicyRecommendedName, fullName+" "+policy.PolicyRecommendedName, f, out, errout), cmd.NewCmdConvert(fullName, f, out), diff --git a/pkg/cmd/cli/cmd/cluster/cluster.go b/pkg/cmd/cli/cmd/cluster/cluster.go index 21b5abec66e8..466399d8117d 100644 --- a/pkg/cmd/cli/cmd/cluster/cluster.go +++ b/pkg/cmd/cli/cmd/cluster/cluster.go @@ -22,6 +22,9 @@ var ( may be a local VM (ie. using docker-machine on OS X and Windows clients), remote machine, or the local Unix host. + Use the 'up' command to start a new cluster (master and node) on a single machine. Use the + 'join' command on another machine to connect to the first cluster. + To use an existing Docker connection, ensure that Docker commands are working and that you can create new containers. For OS X and Windows clients, a docker-machine with the VirtualBox driver can be created for you using the --create-machine option. @@ -33,7 +36,7 @@ var ( routing suffix, use the --routing-suffix flag.`) ) -func NewCmdCluster(name, fullName string, f *clientcmd.Factory, out, errout io.Writer) *cobra.Command { +func NewCmdCluster(name, fullName string, f *clientcmd.Factory, in io.Reader, out, errout io.Writer) *cobra.Command { // Parent command to which all subcommands are added. cmds := &cobra.Command{ Use: fmt.Sprintf("%s ACTION", name), @@ -43,6 +46,7 @@ func NewCmdCluster(name, fullName string, f *clientcmd.Factory, out, errout io.W } cmds.AddCommand(docker.NewCmdUp(docker.CmdUpRecommendedName, fullName+" "+docker.CmdUpRecommendedName, f, out, errout)) + cmds.AddCommand(docker.NewCmdJoin(docker.CmdJoinRecommendedName, fullName+" "+docker.CmdJoinRecommendedName, f, in, out)) cmds.AddCommand(docker.NewCmdDown(docker.CmdDownRecommendedName, fullName+" "+docker.CmdDownRecommendedName, f, out)) cmds.AddCommand(docker.NewCmdStatus(docker.CmdStatusRecommendedName, fullName+" "+docker.CmdStatusRecommendedName, f, out)) return cmds diff --git a/pkg/cmd/server/admin/create_nodeconfig.go b/pkg/cmd/server/admin/create_nodeconfig.go index c83a9cddc61d..fd3fe4b4c2bb 100644 --- a/pkg/cmd/server/admin/create_nodeconfig.go +++ b/pkg/cmd/server/admin/create_nodeconfig.go @@ -68,7 +68,7 @@ func NewCommandNodeConfig(commandName string, fullName string, out io.Writer) *c kcmdutil.CheckErr(kcmdutil.UsageError(cmd, err.Error())) } - if err := options.CreateNodeFolder(); err != nil { + if _, err := options.CreateNodeFolder(); err != nil { kcmdutil.CheckErr(err) } }, @@ -238,7 +238,7 @@ func CopyFile(src, dest string, permissions os.FileMode) error { return nil } -func (o CreateNodeConfigOptions) CreateNodeFolder() error { +func (o CreateNodeConfigOptions) CreateNodeFolder() (string, error) { servingCertInfo := DefaultNodeServingCertInfo(o.NodeConfigDir) clientCertInfo := DefaultNodeClientCertInfo(o.NodeConfigDir) @@ -257,34 +257,34 @@ func (o CreateNodeConfigOptions) CreateNodeFolder() error { fmt.Fprintf(o.Output, "Generating node credentials ...\n") if err := o.MakeClientCert(clientCertFile, clientKeyFile); err != nil { - return err + return "", err } if o.UseTLS() { if err := o.MakeAndWriteServerCert(serverCertFile, serverKeyFile); err != nil { - return err + return "", err } if o.UseNodeClientCA() { if err := o.MakeNodeClientCA(nodeClientCAFile); err != nil { - return err + return "", err } } } if err := o.MakeAPIServerCA(apiServerCAFile); err != nil { - return err + return "", err } if err := o.MakeKubeConfig(clientCertFile, clientKeyFile, apiServerCAFile, kubeConfigFile); err != nil { - return err + return "", err } if err := o.MakeNodeConfig(serverCertFile, serverKeyFile, nodeClientCAFile, kubeConfigFile, nodeConfigFile); err != nil { - return err + return "", err } if err := o.MakeNodeJSON(nodeJSONFile); err != nil { - return err + return "", err } fmt.Fprintf(o.Output, "Created node config for %s in %s\n", o.NodeName, o.NodeConfigDir) - return nil + return nodeConfigFile, nil } func (o CreateNodeConfigOptions) MakeClientCert(clientCertFile, clientKeyFile string) error { diff --git a/pkg/cmd/server/bootstrappolicy/infra_sa_policy.go b/pkg/cmd/server/bootstrappolicy/infra_sa_policy.go index 758b534f79df..0ce6aeec03dd 100644 --- a/pkg/cmd/server/bootstrappolicy/infra_sa_policy.go +++ b/pkg/cmd/server/bootstrappolicy/infra_sa_policy.go @@ -7,6 +7,7 @@ import ( "k8s.io/kubernetes/pkg/apis/apps" "k8s.io/kubernetes/pkg/apis/autoscaling" "k8s.io/kubernetes/pkg/apis/batch" + "k8s.io/kubernetes/pkg/apis/certificates" "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/apis/policy" "k8s.io/kubernetes/pkg/apis/storage" @@ -68,6 +69,9 @@ const ( InfraPetSetControllerServiceAccountName = "pet-set-controller" PetSetControllerRoleName = "system:pet-set-controller" + InfraCertificateSigningControllerServiceAccountName = "certificate-signing-controller" + CertificateSigningControllerRoleName = "system:certificate-signing-controller" + InfraUnidlingControllerServiceAccountName = "unidling-controller" UnidlingControllerRoleName = "system:unidling-controller" @@ -79,6 +83,9 @@ const ( InfraServiceIngressIPControllerServiceAccountName = "service-ingress-ip-controller" ServiceIngressIPControllerRoleName = "system:service-ingress-ip-controller" + + InfraNodeBootstrapServiceAccountName = "node-bootstrapper" + NodeBootstrapRoleName = "system:node-bootstrapper" ) type InfraServiceAccounts struct { @@ -996,6 +1003,30 @@ func init() { panic(err) } + err = InfraSAs.addServiceAccount( + InfraCertificateSigningControllerServiceAccountName, + authorizationapi.ClusterRole{ + ObjectMeta: kapi.ObjectMeta{ + Name: CertificateSigningControllerRoleName, + }, + Rules: []authorizationapi.PolicyRule{ + { + APIGroups: []string{certificates.GroupName}, + Verbs: sets.NewString("list", "watch"), + Resources: sets.NewString("certificatesigningrequests"), + }, + { + APIGroups: []string{certificates.GroupName}, + Verbs: sets.NewString("update"), + Resources: sets.NewString("certificatesigningrequests/status", "certificatesigningrequests/approval"), + }, + }, + }, + ) + if err != nil { + panic(err) + } + err = InfraSAs.addServiceAccount( InfraEndpointControllerServiceAccountName, authorizationapi.ClusterRole{ @@ -1065,4 +1096,22 @@ func init() { panic(err) } + err = InfraSAs.addServiceAccount( + InfraNodeBootstrapServiceAccountName, + authorizationapi.ClusterRole{ + ObjectMeta: kapi.ObjectMeta{ + Name: NodeBootstrapRoleName, + }, + Rules: []authorizationapi.PolicyRule{ + { + APIGroups: []string{certificates.GroupName}, + Verbs: sets.NewString("create", "get"), + Resources: sets.NewString("certificatesigningrequests"), + }, + }, + }, + ) + if err != nil { + panic(err) + } } diff --git a/pkg/cmd/server/bootstrappolicy/policy.go b/pkg/cmd/server/bootstrappolicy/policy.go index a0cb9ae5ce58..56adc642af06 100644 --- a/pkg/cmd/server/bootstrappolicy/policy.go +++ b/pkg/cmd/server/bootstrappolicy/policy.go @@ -735,6 +735,8 @@ func GetBootstrapClusterRoles() []authorizationapi.ClusterRole { // TODO: change glusterfs to use DNS lookup so this isn't needed? // Needed for glusterfs volumes authorizationapi.NewRule("get").Groups(kapiGroup).Resources("endpoints").RuleOrDie(), + // Nodes are allowed to request CSRs (specifically, request serving certs) + authorizationapi.NewRule("get", "create").Groups(certificates.GroupName).Resources("certificatesigningrequests").RuleOrDie(), }, }, diff --git a/pkg/cmd/server/kubernetes/master.go b/pkg/cmd/server/kubernetes/master.go index 32aab215fb19..79a60642f62b 100644 --- a/pkg/cmd/server/kubernetes/master.go +++ b/pkg/cmd/server/kubernetes/master.go @@ -13,12 +13,14 @@ import ( kapi "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/apimachinery/registered" + "k8s.io/kubernetes/pkg/apis/certificates" "k8s.io/kubernetes/pkg/apis/componentconfig" kclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" kcoreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion" "k8s.io/kubernetes/pkg/client/record" "k8s.io/kubernetes/pkg/client/restclient" "k8s.io/kubernetes/pkg/client/typed/dynamic" + certcontroller "k8s.io/kubernetes/pkg/controller/certificates" "k8s.io/kubernetes/pkg/controller/cronjob" "k8s.io/kubernetes/pkg/controller/daemon" "k8s.io/kubernetes/pkg/controller/deployment" @@ -43,7 +45,6 @@ import ( "k8s.io/kubernetes/pkg/runtime/serializer" "k8s.io/kubernetes/pkg/storage" utilwait "k8s.io/kubernetes/pkg/util/wait" - "k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume/aws_ebs" "k8s.io/kubernetes/pkg/volume/cinder" @@ -54,7 +55,6 @@ import ( "k8s.io/kubernetes/pkg/volume/nfs" "k8s.io/kubernetes/pkg/volume/rbd" "k8s.io/kubernetes/pkg/volume/vsphere_volume" - "k8s.io/kubernetes/plugin/pkg/scheduler" _ "k8s.io/kubernetes/plugin/pkg/scheduler/algorithmprovider" schedulerapi "k8s.io/kubernetes/plugin/pkg/scheduler/api" @@ -399,3 +399,28 @@ func (c *MasterConfig) createSchedulerConfig() (*scheduler.Config, error) { // if the config file isn't provided, use the default provider return configFactory.CreateFromProvider(factory.DefaultProvider) } + +type noAutoApproval struct{} + +func (noAutoApproval) AutoApprove(csr *certificates.CertificateSigningRequest) (*certificates.CertificateSigningRequest, error) { + return csr, nil +} + +func (c *MasterConfig) RunCertificateSigningController(clientset *kclientset.Clientset) { + if len(c.ControllerManager.ClusterSigningCertFile) == 0 || len(c.ControllerManager.ClusterSigningKeyFile) == 0 { + glog.V(2).Infof("Certificate signer controller will not start - no signing key or cert set") + return + } + resyncPeriod := kctrlmgr.ResyncPeriod(c.ControllerManager)() + certController, err := certcontroller.NewCertificateController( + clientset, + resyncPeriod, + c.ControllerManager.ClusterSigningCertFile, + c.ControllerManager.ClusterSigningKeyFile, + c.ControllerManager.ApproveAllKubeletCSRsForGroup, + ) + if err != nil { + glog.Fatalf("Failed to start certificate controller: %v", err) + } + go certController.Run(1, utilwait.NeverStop) +} diff --git a/pkg/cmd/server/kubernetes/master_config.go b/pkg/cmd/server/kubernetes/master_config.go index 16341c38747e..47ae2aff1515 100644 --- a/pkg/cmd/server/kubernetes/master_config.go +++ b/pkg/cmd/server/kubernetes/master_config.go @@ -206,6 +206,8 @@ func BuildKubernetesMasterConfig(options configapi.MasterConfig, requestContextM // Defaults are tested in TestCMServerDefaults cmserver := cmapp.NewCMServer() // Adjust defaults + cmserver.ClusterSigningCertFile = "" + cmserver.ClusterSigningKeyFile = "" cmserver.Address = "" // no healthz endpoint cmserver.Port = 0 // no healthz endpoint cmserver.EnableGarbageCollector = false // disabled until we add the controller diff --git a/pkg/cmd/server/start/bootstrap_node.go b/pkg/cmd/server/start/bootstrap_node.go new file mode 100644 index 000000000000..75b709a3e99a --- /dev/null +++ b/pkg/cmd/server/start/bootstrap_node.go @@ -0,0 +1,355 @@ +package start + +import ( + "crypto/tls" + "crypto/x509/pkix" + "fmt" + "io/ioutil" + "os" + "path/filepath" + "time" + + "github.com/golang/glog" + + kapi "k8s.io/kubernetes/pkg/api" + kerrors "k8s.io/kubernetes/pkg/api/errors" + "k8s.io/kubernetes/pkg/apis/certificates" + kclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" + "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" + clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api" + utilcert "k8s.io/kubernetes/pkg/util/cert" + "k8s.io/kubernetes/pkg/util/wait" + + "crypto/rsa" + configapilatest "github.com/openshift/origin/pkg/cmd/server/api/latest" + "github.com/openshift/origin/pkg/cmd/server/crypto" +) + +// hasCSRCondition returns the first matching condition with the given type or nil. +func hasCSRCondition(conditions []certificates.CertificateSigningRequestCondition, t certificates.RequestConditionType) *certificates.CertificateSigningRequestCondition { + for i := range conditions { + if conditions[i].Type == t { + return &conditions[i] + } + } + return nil +} + +// readOrCreatePrivateKey attempts to read an rsa private key from the provided path, +// or if that fails, to generate a new private key. +func readOrCreatePrivateKey(path string) (*rsa.PrivateKey, error) { + if data, err := ioutil.ReadFile(path); err == nil { + if key, err := utilcert.ParsePrivateKeyPEM(data); err == nil { + if pkey, ok := key.(*rsa.PrivateKey); ok { + return pkey, nil + } + } + } + return utilcert.NewPrivateKey() +} + +// loadBootstrapClientCertificate attempts to read a node.kubeconfig file from the config dir, +// and otherwise tries to request a client certificate as a node (system:node:NODE_NAME). It will +// reuse a private key if one exists, and exit with an error if the CSR is not completed within +// timeout or if the current CSR does not validate against the local private key. +func (o NodeOptions) loadBootstrapClientCertificate(nodeConfigDir string, c kclientset.Interface, timeout time.Duration) (kclientset.Interface, error) { + nodeConfigPath := filepath.Join(nodeConfigDir, "node.kubeconfig") + + // if the node config exists, try to use it or fail + if _, err := os.Stat(nodeConfigPath); err == nil { + kubeClientConfig, err := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(&clientcmd.ClientConfigLoadingRules{ExplicitPath: nodeConfigPath}, &clientcmd.ConfigOverrides{}).ClientConfig() + if err != nil { + return nil, err + } + return kclientset.NewForConfig(kubeClientConfig) + } + + clientCertPath := filepath.Join(nodeConfigDir, "master-client.crt") + clientKeyPath := filepath.Join(nodeConfigDir, "master-client.key") + + // create and sign a client cert + privateKey, err := readOrCreatePrivateKey(clientKeyPath) + if err != nil { + return nil, err + } + privateKeyData := utilcert.EncodePrivateKeyPEM(privateKey) + csrData, err := utilcert.MakeCSR(privateKey, &pkix.Name{ + Organization: []string{"system:nodes"}, + CommonName: fmt.Sprintf("system:node:%s", o.NodeArgs.NodeName), + // TODO: indicate usage for client + }, nil, nil) + if err != nil { + return nil, err + } + + signingRequest := &certificates.CertificateSigningRequest{ + ObjectMeta: kapi.ObjectMeta{ + Name: fmt.Sprintf("node-bootstrapper-client-%s", safeSecretName(o.NodeArgs.NodeName)), + }, + Spec: certificates.CertificateSigningRequestSpec{ + Request: csrData, + }, + } + + csr, err := c.Certificates().CertificateSigningRequests().Create(signingRequest) + if err != nil { + if !kerrors.IsAlreadyExists(err) { + return nil, err + } + glog.V(3).Infof("Bootstrap client certificate already exists at %s", signingRequest.Name) + csr, err = c.Certificates().CertificateSigningRequests().Get(signingRequest.Name) + if err != nil { + return nil, err + } + } + if err := ioutil.WriteFile(clientKeyPath, privateKeyData, 0600); err != nil { + return nil, err + } + + err = wait.PollImmediate(1*time.Second, timeout, func() (bool, error) { + if deny := hasCSRCondition(csr.Status.Conditions, certificates.CertificateDenied); deny != nil { + glog.V(2).Infof("Bootstrap signing rejected (%s): %s", deny.Reason, deny.Message) + return false, fmt.Errorf("certificate signing request rejected (%s): %s", deny.Reason, deny.Message) + } + if approved := hasCSRCondition(csr.Status.Conditions, certificates.CertificateApproved); approved != nil { + glog.V(2).Infof("Bootstrap client cert approved") + return true, nil + } + csr, err = c.Certificates().CertificateSigningRequests().Get(csr.Name) + return false, err + }) + if err != nil { + return nil, err + } + + if err := ioutil.WriteFile(clientCertPath, csr.Status.Certificate, 0600); err != nil { + return nil, err + } + + if _, err := tls.LoadX509KeyPair(clientCertPath, clientKeyPath); err != nil { + return nil, fmt.Errorf("bootstrap client certificate does not match private key, you may need to delete the client CSR: %v", err) + } + + // write a kube config file for the node that contains the client cert + cfg, err := o.NodeArgs.KubeConnectionArgs.ClientConfig.RawConfig() + if err != nil { + return nil, err + } + if err := clientcmdapi.MinifyConfig(&cfg); err != nil { + return nil, err + } + ctx := cfg.Contexts[cfg.CurrentContext] + if len(ctx.AuthInfo) == 0 { + ctx.AuthInfo = "bootstrap" + } + cfg.AuthInfos = map[string]*clientcmdapi.AuthInfo{ + ctx.AuthInfo: { + ClientCertificateData: csr.Status.Certificate, + ClientKeyData: privateKeyData, + }, + } + if err := clientcmd.WriteToFile(cfg, nodeConfigPath); err != nil { + return nil, err + } + + kubeClientConfig, err := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(&clientcmd.ClientConfigLoadingRules{ExplicitPath: nodeConfigPath}, &clientcmd.ConfigOverrides{}).ClientConfig() + if err != nil { + return nil, err + } + + return kclientset.NewForConfig(kubeClientConfig) +} + +// loadBootstrapServerCertificate attempts to read a server certificate file from the config dir, +// and otherwise tries to request a server certificate for its registered addresses. It will +// reuse a private key if one exists, and exit with an error if the CSR is not completed within +// timeout or if the current CSR does not validate against the local private key. +func (o NodeOptions) loadBootstrapServerCertificate(nodeConfigDir string, hostnames []string, c kclientset.Interface, timeout time.Duration) error { + serverCertPath := filepath.Join(nodeConfigDir, "server.crt") + serverKeyPath := filepath.Join(nodeConfigDir, "server.key") + + if _, err := os.Stat(serverCertPath); err == nil { + if _, err := os.Stat(serverKeyPath); err == nil { + if _, err := tls.LoadX509KeyPair(serverCertPath, serverKeyPath); err != nil { + return fmt.Errorf("bootstrap server certificate does not match private key: %v", err) + } + // continue + return nil + } + } + + privateKey, err := readOrCreatePrivateKey(serverKeyPath) + if err != nil { + return err + } + privateKeyData := utilcert.EncodePrivateKeyPEM(privateKey) + ipAddresses, dnsNames := crypto.IPAddressesDNSNames(hostnames) + csrData, err := utilcert.MakeCSR(privateKey, &pkix.Name{ + CommonName: dnsNames[0], + // TODO: indicate usage for server + }, dnsNames, ipAddresses) + if err != nil { + return err + } + + signingRequest := &certificates.CertificateSigningRequest{ + ObjectMeta: kapi.ObjectMeta{ + Name: fmt.Sprintf("node-bootstrapper-server-%s", safeSecretName(o.NodeArgs.NodeName)), + }, + Spec: certificates.CertificateSigningRequestSpec{ + Request: csrData, + }, + } + + csr, err := c.Certificates().CertificateSigningRequests().Create(signingRequest) + if err != nil { + if !kerrors.IsAlreadyExists(err) { + return err + } + glog.V(3).Infof("Bootstrap server certificate already exists at %s", signingRequest.Name) + csr, err = c.Certificates().CertificateSigningRequests().Get(signingRequest.Name) + if err != nil { + return err + } + } + if err := ioutil.WriteFile(serverKeyPath, privateKeyData, 0600); err != nil { + return err + } + + err = wait.PollImmediate(1*time.Second, 1*time.Minute, func() (bool, error) { + if deny := hasCSRCondition(csr.Status.Conditions, certificates.CertificateDenied); deny != nil { + glog.V(2).Infof("Bootstrap signing rejected (%s): %s", deny.Reason, deny.Message) + return false, fmt.Errorf("certificate signing request rejected (%s): %s", deny.Reason, deny.Message) + } + if approved := hasCSRCondition(csr.Status.Conditions, certificates.CertificateApproved); approved != nil { + glog.V(2).Infof("Bootstrap serving cert approved") + return true, nil + } + csr, err = c.Certificates().CertificateSigningRequests().Get(csr.Name) + return false, err + }) + if err != nil { + return err + } + + if err := ioutil.WriteFile(serverCertPath, csr.Status.Certificate, 0600); err != nil { + return err + } + if _, err := tls.LoadX509KeyPair(serverCertPath, serverKeyPath); err != nil { + return fmt.Errorf("bootstrap server certificate does not match private key, you may need to delete the server CSR: %v", err) + } + + return nil +} + +// loadBootstrap attempts to ensure a bootstrap configuration exists inside the node config dir +// by contacting the server and requesting a client and server certificate. If successful, it +// will attempt to download a node config file from namespace openshift-infra from the node-config +// ConfigMap. If no configuration is found, a new node config will be generated from the arguments +// and used instead. If no error is returned, nodeConfigDir can be used as a valid node configuration. +func (o NodeOptions) loadBootstrap(hostnames []string, nodeConfigDir string) error { + if err := os.MkdirAll(nodeConfigDir, 0700); err != nil { + return err + } + + kubeClientConfig, err := o.NodeArgs.KubeConnectionArgs.ClientConfig.ClientConfig() + if err != nil { + return err + } + var c kclientset.Interface + c, err = kclientset.NewForConfig(kubeClientConfig) + if err != nil { + return err + } + + glog.Infof("Bootstrapping from API server %s (experimental)", kubeClientConfig.Host) + + c, err = o.loadBootstrapClientCertificate(nodeConfigDir, c, 1*time.Minute) + if err != nil { + return err + } + if err := o.loadBootstrapServerCertificate(nodeConfigDir, hostnames, c, 1*time.Minute); err != nil { + return err + } + + nodeClientCAPath := filepath.Join(nodeConfigDir, "node-client-ca.crt") + if len(kubeClientConfig.CAData) > 0 { + if err := ioutil.WriteFile(nodeClientCAPath, []byte(kubeClientConfig.CAData), 0600); err != nil { + return err + } + } + + // try to refresh the latest node-config.yaml + o.ConfigFile = filepath.Join(nodeConfigDir, "node-config.yaml") + config, err := c.Core().ConfigMaps("openshift-infra").Get("node-config") + if err == nil { + // skip all the config we generated ourselves + skipConfig := map[string]struct{}{"server.crt": {}, "server.key": {}, "master-client.crt": {}, "master-client.key": {}, "node.kubeconfig": {}} + for k, v := range config.Data { + if _, ok := skipConfig[k]; ok { + continue + } + b := []byte(v) + // if a node config is provided, override the setup. + if k == "node-config.yaml" { + if err := ioutil.WriteFile(o.ConfigFile, []byte(v), 0600); err != nil { + return err + } + nodeConfig, err := configapilatest.ReadNodeConfig(o.ConfigFile) + if err != nil { + return err + } + if err := o.NodeArgs.MergeSerializeableNodeConfig(nodeConfig); err != nil { + return err + } + nodeConfig.ServingInfo.ServerCert.CertFile = filepath.Join(nodeConfigDir, "server.crt") + nodeConfig.ServingInfo.ServerCert.KeyFile = filepath.Join(nodeConfigDir, "server.key") + nodeConfig.ServingInfo.ClientCA = nodeClientCAPath + nodeConfig.MasterKubeConfig = filepath.Join(nodeConfigDir, "node.kubeconfig") + b, err = configapilatest.WriteYAML(nodeConfig) + if err != nil { + return err + } + } + + if err := ioutil.WriteFile(filepath.Join(nodeConfigDir, k), b, 0600); err != nil { + return err + } + } + glog.V(3).Infof("Received %d bootstrap files into %s", len(config.Data), nodeConfigDir) + } + + // if we had a previous node-config.yaml, continue using it + if _, err2 := os.Stat(o.ConfigFile); err2 == nil { + if err == nil { + glog.V(2).Infof("Unable to load node configuration from the server: %v", err) + } + return nil + } + + // if there is no node-config.yaml and no server config map, generate one + if kerrors.IsNotFound(err) { + glog.V(2).Infof("Generating a local configuration since no server config available") + nodeConfig, err := o.NodeArgs.BuildSerializeableNodeConfig() + if err != nil { + return err + } + if err := o.NodeArgs.MergeSerializeableNodeConfig(nodeConfig); err != nil { + return err + } + nodeConfig.ServingInfo.ServerCert.CertFile = "server.crt" + nodeConfig.ServingInfo.ServerCert.KeyFile = "server.key" + nodeConfig.ServingInfo.ClientCA = "node-client-ca.crt" + nodeConfig.MasterKubeConfig = "node.kubeconfig" + b, err := configapilatest.WriteYAML(nodeConfig) + if err != nil { + return err + } + if err := ioutil.WriteFile(o.ConfigFile, b, 0600); err != nil { + return err + } + return nil + } + + return err +} diff --git a/pkg/cmd/server/start/kube_connection_args.go b/pkg/cmd/server/start/kube_connection_args.go index a10148203323..acf4c39120ca 100644 --- a/pkg/cmd/server/start/kube_connection_args.go +++ b/pkg/cmd/server/start/kube_connection_args.go @@ -69,9 +69,5 @@ func (args KubeConnectionArgs) GetKubernetesAddress(defaultAddress *url.URL) (*u if ok && len(config.Host) > 0 { return url.Parse(config.Host) } - - if defaultAddress == nil { - return nil, errors.New("no default KubernetesAddress present") - } return defaultAddress, nil } diff --git a/pkg/cmd/server/start/master_args.go b/pkg/cmd/server/start/master_args.go index f2637ee8b6b4..4b0ea5001cfc 100644 --- a/pkg/cmd/server/start/master_args.go +++ b/pkg/cmd/server/start/master_args.go @@ -469,15 +469,18 @@ func (args MasterArgs) BuildSerializeableKubeMasterConfig() (*configapi.Kubernet func (args MasterArgs) Validate() error { masterAddr, err := args.GetMasterAddress() - if addr, err := masterAddr, err; err != nil { + if err != nil { return err - } else if len(addr.Path) != 0 { - return fmt.Errorf("master url may not include a path: '%v'", addr.Path) + } + if len(masterAddr.Path) != 0 { + return fmt.Errorf("master url may not include a path: '%v'", masterAddr.Path) } - if addr, err := args.GetMasterPublicAddress(); err != nil { + addr, err := args.GetMasterPublicAddress() + if err != nil { return err - } else if len(addr.Path) != 0 { + } + if len(addr.Path) != 0 { return fmt.Errorf("master public url may not include a path: '%v'", addr.Path) } @@ -485,9 +488,11 @@ func (args MasterArgs) Validate() error { return err } - if addr, err := args.KubeConnectionArgs.GetKubernetesAddress(masterAddr); err != nil { + addr, err = args.KubeConnectionArgs.GetKubernetesAddress(masterAddr) + if err != nil { return err - } else if len(addr.Path) != 0 { + } + if len(addr.Path) != 0 { return fmt.Errorf("kubernetes url may not include a path: '%v'", addr.Path) } diff --git a/pkg/cmd/server/start/node_args.go b/pkg/cmd/server/start/node_args.go index 56dee1d807e9..87226e996a61 100644 --- a/pkg/cmd/server/start/node_args.go +++ b/pkg/cmd/server/start/node_args.go @@ -6,6 +6,7 @@ import ( "net" "net/url" "os/exec" + "regexp" "strconv" "strings" @@ -55,6 +56,9 @@ type NodeArgs struct { // NodeName is the hostname to identify this node with the master. NodeName string + // Bootstrap is true if the node should rely on the server to set initial configuration. + Bootstrap bool + MasterCertDir string ConfigDir flag.StringFlag @@ -137,7 +141,7 @@ func (args NodeArgs) Validate() error { if err := args.KubeConnectionArgs.Validate(); err != nil { return err } - if _, err := args.KubeConnectionArgs.GetKubernetesAddress(args.DefaultKubernetesURL); err != nil { + if addr, _ := args.KubeConnectionArgs.GetKubernetesAddress(args.DefaultKubernetesURL); addr == nil { return errors.New("--kubeconfig must be set to provide API server connection information") } return nil @@ -209,6 +213,24 @@ func (args NodeArgs) BuildSerializeableNodeConfig() (*configapi.NodeConfig, erro return config, nil } +// MergeSerializeableNodeConfig takes the NodeArgs (partially complete config) and overlays them onto an existing +// config. Only a subset of node args are allowed to override this config - those that may reasonably be specified +// as local overrides. +func (args NodeArgs) MergeSerializeableNodeConfig(config *configapi.NodeConfig) error { + if len(args.ClusterDNS) > 0 { + config.DNSIP = args.ClusterDNS.String() + } + if len(args.NodeName) > 0 { + config.NodeName = args.NodeName + } + + config.ServingInfo.BindAddress = net.JoinHostPort(args.ListenArg.ListenAddr.Host, strconv.Itoa(ports.KubeletPort)) + + config.VolumeDirectory = args.VolumeDir + config.AllowDisabledDocker = args.AllowDisabledDocker + return nil +} + // GetServerCertHostnames returns the set of hostnames and IP addresses a serving certificate for node on this host might need to be valid for. func (args NodeArgs) GetServerCertHostnames() (sets.String, error) { allHostnames := sets.NewString(args.NodeName) @@ -276,3 +298,13 @@ func defaultHostname() (string, error) { } return strings.ToLower(strings.TrimSpace(string(fqdn))), nil } + +var invalidNameCharactersRegexp = regexp.MustCompile("[^-a-z0-9]") + +func safeSecretName(s string) string { + // Remove everything except [-0-9a-z] + s = invalidNameCharactersRegexp.ReplaceAllString(strings.ToLower(s), "-") + // Remove leading and trailing hyphen(s) that may be introduced by the previous step + s = strings.Trim(s, "-") + return s +} diff --git a/pkg/cmd/server/start/start_master.go b/pkg/cmd/server/start/start_master.go index 3b1e9e14ad7e..3aafea870045 100644 --- a/pkg/cmd/server/start/start_master.go +++ b/pkg/cmd/server/start/start_master.go @@ -658,6 +658,11 @@ func startControllers(oc *origin.MasterConfig, kc *kubernetes.MasterConfig) erro glog.Fatalf("Could not get client for pet set controller: %v", err) } + _, _, certificateSigningClient, err := oc.GetServiceAccountClients(bootstrappolicy.InfraCertificateSigningControllerServiceAccountName) + if err != nil { + glog.Fatalf("Could not get client for disruption budget controller: %v", err) + } + namespaceControllerClientConfig, _, namespaceControllerKubeClient, err := oc.GetServiceAccountClients(bootstrappolicy.InfraNamespaceControllerServiceAccountName) if err != nil { glog.Fatalf("Could not get client for namespace controller: %v", err) @@ -709,6 +714,8 @@ func startControllers(oc *origin.MasterConfig, kc *kubernetes.MasterConfig) erro kc.RunServiceLoadBalancerController(serviceLoadBalancerClient) + kc.RunCertificateSigningController(certificateSigningClient) + appsEnabled := len(configapi.GetEnabledAPIVersionsForGroup(kc.Options, apps.GroupName)) > 0 if appsEnabled { kc.RunStatefulSetController(statefulSetClient) diff --git a/pkg/cmd/server/start/start_node.go b/pkg/cmd/server/start/start_node.go index 2de541469ed8..65af64ecd56a 100644 --- a/pkg/cmd/server/start/start_node.go +++ b/pkg/cmd/server/start/start_node.go @@ -5,13 +5,13 @@ import ( "fmt" "io" "os" + "path/filepath" "strings" "github.com/coreos/go-systemd/daemon" "github.com/golang/glog" "github.com/spf13/cobra" - "github.com/openshift/origin/pkg/cmd/server/kubernetes" kerrors "k8s.io/kubernetes/pkg/api/errors" kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" @@ -20,6 +20,7 @@ import ( configapilatest "github.com/openshift/origin/pkg/cmd/server/api/latest" "github.com/openshift/origin/pkg/cmd/server/api/validation" "github.com/openshift/origin/pkg/cmd/server/crypto" + "github.com/openshift/origin/pkg/cmd/server/kubernetes" "github.com/openshift/origin/pkg/cmd/templates" cmdutil "github.com/openshift/origin/pkg/cmd/util" "github.com/openshift/origin/pkg/cmd/util/docker" @@ -68,12 +69,13 @@ func NewCommandStartNode(basename string, out, errout io.Writer) (*cobra.Command flags.IntVar(&options.ExpireDays, "expire-days", options.ExpireDays, "Validity of the certificates in days (defaults to 2 years). WARNING: extending this above default value is highly discouraged.") options.NodeArgs = NewDefaultNodeArgs() - BindNodeArgs(options.NodeArgs, flags, "", true) BindListenArg(options.NodeArgs.ListenArg, flags, "") BindImageFormatArgs(options.NodeArgs.ImageFormatArgs, flags, "") BindKubeConnectionArgs(options.NodeArgs.KubeConnectionArgs, flags, "") + flags.BoolVar(&options.NodeArgs.Bootstrap, "bootstrap", false, "Use the provided .kubeconfig file to perform initial node setup (experimental).") + // autocompletion hints cmd.MarkFlagFilename("config", "yaml", "yml") @@ -154,7 +156,7 @@ func (o NodeOptions) Validate(args []string) error { } // if we are starting up using a config file, run no validations here - if !o.IsRunFromConfig() { + if o.NodeArgs.Bootstrap && !o.IsRunFromConfig() { if err := o.NodeArgs.Validate(); err != nil { return err } @@ -189,24 +191,7 @@ func (o NodeOptions) StartNode() error { // 3. Writes the fully specified node config and exits if needed // 4. Starts the node based on the fully specified config func (o NodeOptions) RunNode() error { - if !o.IsRunFromConfig() || o.IsWriteConfigOnly() { - glog.V(2).Infof("Generating node configuration") - if err := o.CreateNodeConfig(); err != nil { - return err - } - } - - if o.IsWriteConfigOnly() { - return nil - } - - var nodeConfig *configapi.NodeConfig - var err error - if o.IsRunFromConfig() { - nodeConfig, err = configapilatest.ReadAndResolveNodeConfig(o.ConfigFile) - } else { - nodeConfig, err = o.NodeArgs.BuildSerializeableNodeConfig() - } + nodeConfig, configFile, err := o.resolveNodeConfig() if err != nil { return err } @@ -218,13 +203,18 @@ func (o NodeOptions) RunNode() error { } } if len(validationResults.Errors) != 0 { - return kerrors.NewInvalid(configapi.Kind("NodeConfig"), o.ConfigFile, validationResults.Errors) + glog.V(4).Infof("Configuration is invalid: %#v", nodeConfig) + return kerrors.NewInvalid(configapi.Kind("NodeConfig"), configFile, validationResults.Errors) } if err := ValidateRuntime(nodeConfig, o.NodeArgs.Components); err != nil { return err } + if o.IsWriteConfigOnly() { + return nil + } + if err := StartNode(*nodeConfig, o.NodeArgs.Components); err != nil { return err } @@ -232,29 +222,71 @@ func (o NodeOptions) RunNode() error { return nil } -func (o NodeOptions) CreateNodeConfig() error { - getSignerOptions := &admin.SignerCertOptions{ - CertFile: admin.DefaultCertFilename(o.NodeArgs.MasterCertDir, admin.CAFilePrefix), - KeyFile: admin.DefaultKeyFilename(o.NodeArgs.MasterCertDir, admin.CAFilePrefix), - SerialFile: admin.DefaultSerialFilename(o.NodeArgs.MasterCertDir, admin.CAFilePrefix), +// resolveNodeConfig creates a new configuration on disk by reading from the master, reads +// the config file from disk if specified, or generates a new config from the incoming arguments. +// After this call returns without an error, config files will exist on disk. It also returns +// a string for messages indicating which config file contains the config. +func (o NodeOptions) resolveNodeConfig() (*configapi.NodeConfig, string, error) { + switch { + case o.NodeArgs.Bootstrap: + glog.V(2).Infof("Bootstrapping from master configuration") + + hostnames, err := o.NodeArgs.GetServerCertHostnames() + if err != nil { + return nil, "", err + } + nodeConfigDir := o.NodeArgs.ConfigDir.Value() + if err := o.loadBootstrap(hostnames.List(), nodeConfigDir); err != nil { + return nil, "", err + } + configFile := o.ConfigFile + if len(configFile) == 0 { + configFile = filepath.Join(o.NodeArgs.ConfigDir.Value(), "node-config.yaml") + } + cfg, err := configapilatest.ReadAndResolveNodeConfig(configFile) + return cfg, configFile, err + + case o.IsRunFromConfig(): + glog.V(2).Infof("Reading node configuration from %s", o.ConfigFile) + cfg, err := configapilatest.ReadAndResolveNodeConfig(o.ConfigFile) + return cfg, o.ConfigFile, err + + default: + glog.V(2).Infof("Generating new node configuration") + configFile, err := o.createNodeConfig() + if err != nil { + return nil, "", err + } + cfg, err := o.NodeArgs.BuildSerializeableNodeConfig() + return cfg, configFile, err } +} +// createNodeConfig writes the appropriate config file to the ConfigDir location and then +// returns the path to that config file or an error. +func (o NodeOptions) createNodeConfig() (string, error) { + hostnames, err := o.NodeArgs.GetServerCertHostnames() + if err != nil { + return "", err + } + nodeConfigDir := o.NodeArgs.ConfigDir.Value() var dnsIP string if len(o.NodeArgs.ClusterDNS) > 0 { dnsIP = o.NodeArgs.ClusterDNS.String() } - masterAddr, err := o.NodeArgs.KubeConnectionArgs.GetKubernetesAddress(o.NodeArgs.DefaultKubernetesURL) if err != nil { - return err + return "", err } - - hostnames, err := o.NodeArgs.GetServerCertHostnames() - if err != nil { - return err + if masterAddr == nil { + return "", errors.New("--kubeconfig must be set to provide API server connection information") } - nodeConfigDir := o.NodeArgs.ConfigDir.Value() + getSignerOptions := &admin.SignerCertOptions{ + CertFile: admin.DefaultCertFilename(o.NodeArgs.MasterCertDir, admin.CAFilePrefix), + KeyFile: admin.DefaultKeyFilename(o.NodeArgs.MasterCertDir, admin.CAFilePrefix), + SerialFile: admin.DefaultSerialFilename(o.NodeArgs.MasterCertDir, admin.CAFilePrefix), + } createNodeConfigOptions := admin.CreateNodeConfigOptions{ SignerCertOptions: getSignerOptions, @@ -279,13 +311,9 @@ func (o NodeOptions) CreateNodeConfig() error { } if err := createNodeConfigOptions.Validate(nil); err != nil { - return err - } - if err := createNodeConfigOptions.CreateNodeFolder(); err != nil { - return err + return "", err } - - return nil + return createNodeConfigOptions.CreateNodeFolder() } func (o NodeOptions) IsWriteConfigOnly() bool { diff --git a/test/testdata/bootstrappolicy/bootstrap_cluster_roles.yaml b/test/testdata/bootstrappolicy/bootstrap_cluster_roles.yaml index e2c2be30b8b3..6e3c31b02917 100644 --- a/test/testdata/bootstrappolicy/bootstrap_cluster_roles.yaml +++ b/test/testdata/bootstrappolicy/bootstrap_cluster_roles.yaml @@ -2160,6 +2160,14 @@ items: - endpoints verbs: - get + - apiGroups: + - certificates.k8s.io + attributeRestrictions: null + resources: + - certificatesigningrequests + verbs: + - create + - get - apiVersion: v1 kind: ClusterRole metadata: @@ -2570,6 +2578,30 @@ items: - create - patch - update +- apiVersion: v1 + kind: ClusterRole + metadata: + annotations: + authorization.openshift.io/system-only: "true" + creationTimestamp: null + name: system:certificate-signing-controller + rules: + - apiGroups: + - certificates.k8s.io + attributeRestrictions: null + resources: + - certificatesigningrequests + verbs: + - list + - watch + - apiGroups: + - certificates.k8s.io + attributeRestrictions: null + resources: + - certificatesigningrequests/approval + - certificatesigningrequests/status + verbs: + - update - apiVersion: v1 kind: ClusterRole metadata: @@ -3019,6 +3051,22 @@ items: - deletecollection - get - list +- apiVersion: v1 + kind: ClusterRole + metadata: + annotations: + authorization.openshift.io/system-only: "true" + creationTimestamp: null + name: system:node-bootstrapper + rules: + - apiGroups: + - certificates.k8s.io + attributeRestrictions: null + resources: + - certificatesigningrequests + verbs: + - create + - get - apiVersion: v1 kind: ClusterRole metadata: diff --git a/test/util/server/server.go b/test/util/server/server.go index beb2c71cf02f..f9ca4e7b9ed8 100644 --- a/test/util/server/server.go +++ b/test/util/server/server.go @@ -218,7 +218,7 @@ func CreateNodeCerts(nodeArgs *start.NodeArgs, masterURL string) error { if err := createNodeConfig.Validate(nil); err != nil { return err } - if err := createNodeConfig.CreateNodeFolder(); err != nil { + if _, err := createNodeConfig.CreateNodeFolder(); err != nil { return err }