-
Notifications
You must be signed in to change notification settings - Fork 175
Support alibaba cloud manual mode #412
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
4fb14a2
4f2a895
2e757c8
0ecbd8a
ca9ab61
2a768ba
567919b
de9cc73
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -215,3 +215,126 @@ This command will delete the service id from the IBM Cloud | |
| ```bash | ||
| ccoctl ibmcloud delete-service-id --credentials-requests-dir <path-to-directory-with-list-of-credentials-requests> --name <name> | ||
| ``` | ||
|
|
||
| ## Alibaba Cloud | ||
|
|
||
| This is a guide for using manual mode on alibaba cloud, for more info about manual mode, please refer to [cco-mode-manual](https://github.com/openshift/cloud-credential-operator/blob/master/docs/mode-manual-creds.md). | ||
|
|
||
| For alibaba cloud, the CCO utility (`ccoctl`) binary will create credentials Secret manifests for the OpenShift installer. It will also create a user along with a long-lived RAM AccessKey (AK) for each OpenShift in-cluster component. Every RAM user who owns the AK would be attached RAM policies with the permission defined in each component's CredentialsRequest. To do all this, ccoctl consumes AK of a root RAM user with permissions required for creating user/policy and also attaching the policy to the user. | ||
|
|
||
| ### Prerequisite | ||
|
|
||
| 1. Extract and prepare the ccoctl binary from the release image. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Show a command for how to do this; don't assume you users know how to do this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed, we show this for the AWS version and I will be modelling the structure for new platform support on what we have for AWS
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @sferich888 thanks for the review! I could only found a Chinese doc for these on https://help.aliyun.com/document_detail/311677.html, and I will check if there is an English version with my colleague |
||
|
|
||
| 2. Choose an existing RAM user who has the below permissions, and get this user's accesskey id/secret for creating the RAM users and policies for each in-cluster component. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need to tell the user where/how to get the accesskey id/secret for the user account they will use? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Generally these are given to a user when they are assigned an account. Users can manage their keys with their RAM (resource access management console). This document explains a littl emore about getting AccessKeys https://www.alibabacloud.com/help/doc-detail/53045.htm There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Excellent - that documentation is very helpful. |
||
|
|
||
| ```bash | ||
| ram:CreatePolicy | ||
| ram:GetPolicy | ||
| ram:CreatePolicyVersion | ||
| ram:DeletePolicy | ||
| ram:DetachPolicyFromUser | ||
| ram:ListPoliciesForUser | ||
| ram:AttachPolicyToUser | ||
| ram:CreateUser | ||
| ram:GetUser | ||
| ram:DeleteUser | ||
| ram:CreateAccessKey | ||
| ram:ListAccessKeys | ||
| ram:DeleteAccessKey | ||
| ``` | ||
|
|
||
| 3. Use the selected RAM user’s accesskey id/secret to configure the Alibaba Cloud SDK client's credential provider chain with [Envionment Creadentials](https://github.com/aliyun/alibaba-cloud-sdk-go/blob/master/docs/2-Client-EN.md#1-environment-credentials) mode or through [Credentials File](https://github.com/aliyun/alibaba-cloud-sdk-go/blob/master/docs/2-Client-EN.md#2-credentials-file) mode | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are these links official Alibaba Cloud documentation intended for end user consumption?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, this sdk is our official supported, and these docs are also for end user consumption. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks! 👍 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @DahuK is there something more official? When we downstream these docs; we don't want to link to github; if at all possible. |
||
|
|
||
| ### Procedure | ||
|
|
||
| 1. Extract the list of CredentialsRequest custom resources (CRs) from the OpenShift Container Platform release image: | ||
|
|
||
| ```bash | ||
| $ oc adm release extract --credentials-requests --cloud=alibabacloud --to=<path_to_directory_with_list_of_credentials_requests>/credrequests quay.io/<path_to>/ocp-release:<version> | ||
|
|
||
|
Comment on lines
+253
to
+255
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This functionality is not implemented yet in |
||
| ``` | ||
|
|
||
| > step 2&3 are only needed when preparing for upgrading clusters with manually maintained credentials. When doing a fresh installation please skip step 2&3** | ||
|
|
||
| 2. For each CredentialsRequest CR in the release image, ensure that a namespace that matches the text in the spec.secretRef.namespace field exists in the cluster. This field is where the generated secrets that hold the credentials configuration are stored. | ||
|
|
||
| Sample Alibaba Cloud CredentialsRequest object | ||
|
|
||
| ```yaml | ||
| apiVersion: cloudcredential.openshift.io/v1 | ||
| kind: CredentialsRequest | ||
| metadata: | ||
| name: cloud-credential-operator-ram-ro | ||
| namespace: openshift-cloud-credential-operator | ||
| spec: | ||
| providerSpec: | ||
| apiVersion: cloudcredential.openshift.io/v1 | ||
| kind: AlibabaCloudProviderSpec | ||
| statementEntries: | ||
| - action: | ||
| - ecs:CopySnapshot | ||
| - ecs:DeleteDisk | ||
| - ecs:DescribeInstanceAttribute | ||
| - ecs:DescribeInstances | ||
| effect: Allow | ||
| resource: '*' | ||
| secretRef: | ||
| namespace: cloud-credential-operator-ram-ro-creds | ||
| name: openshift-cloud-credential-operator | ||
| ``` | ||
|
|
||
| 3. For any `CredentialsRequest` CR for which the cluster does not already have a namespace with the name specified in `spec.secretRef.namespace`, create the namespace: | ||
|
|
||
| ```bash | ||
| $ oc create namespace <component_namespace> | ||
| ``` | ||
|
|
||
| 4. Use the `ccoctl` tool to process all `CredentialsRequest` objects in the `credrequests` directory: | ||
|
|
||
| ```bash | ||
| $ ccoctl alibabacloud create-ram-users --name <name> --region=<region> --credentials-requests-dir=<path_to_directory_with_list_of_credentials_requests>/credrequests --output-dir=xxxxxx | ||
| ``` | ||
|
|
||
| where: | ||
|
|
||
| - `name` is the name used to tag any cloud resources that are created for tracking. | ||
| - `region` is the Alibaba Cloud region in which cloud resources will be created. | ||
| - `credentials-requests-dir` is the directory containing files of component CredentialsRequests. | ||
| - `output-dir`/manifests is the directory containing files of component credentials secret. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What does There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm interpreting that to mean
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jeana-redhat your interpretation is correct, the manifests will be placed inside ccoctl alibabacloud create-ram-users \
--region ${ALIBABA_REGION_ID} \
--name <cluster_name> \
--credentials-requests-dir ${PWD}/cco-credrequests \
--output-dir ${PWD}/cco-manifestsI will get that structure: $ tree cco-manifests/
cco-manifests/
└── manifests
├── openshift-cluster-csi-drivers-alibaba-disk-credentials-credentials.yaml
├── openshift-image-registry-installer-cloud-credentials-credentials.yaml
├── openshift-ingress-operator-cloud-credentials-credentials.yaml
└── openshift-machine-api-alibabacloud-credentials-credentials.yaml
|
||
|
|
||
| > Note: A ram user can have up to two accesskeys at the same time, so when the `ccoctl alibabacloud create-ram-users` command is run more than twice, the previous generated manifests secret will become stale and you should apply the new generated secrets again.** | ||
|
|
||
| 5. Prepare to run the OpenShift Container Platform installer: | ||
|
|
||
| a. Create the install-config.yaml file: | ||
| ```bash | ||
| $ openshift-install create install-config --dir ./path/to/installation/dir | ||
| ``` | ||
| b. Configure the cluster to install with the CCO in manual mode: | ||
|
|
||
| ```bash | ||
| $ echo "credentialsMode: Manual" >> ./path/to/installation/dir/install-config.yaml | ||
| ``` | ||
|
|
||
| c. Create install manifests: | ||
|
|
||
| ```bash | ||
| $ openshift-install create manifests --dir ./path/to/installation/dir | ||
| ``` | ||
|
|
||
| d. Copy the generated credential files to the target manifests directory: | ||
|
|
||
| ```bash | ||
| $ cp <output_dir>/manifests/*credentials.yaml ./path/to/installation/dir/manifests/ | ||
| ``` | ||
| 6. To delete resources created by ccoctl, run | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should the user always delete after installing? Or is this a cleanup step for uninstalling (I am asking based on other provider docs)? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These keys will most likely live until the cluster is uninstalled. The keys are being used by the cluster's internal components that require API access. They MUST not be deleted after installation or the cluster will not continue to function properly. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, so a cleanup after uninstall step similar to other platforms then. Thanks! |
||
|
|
||
| ```bash | ||
| $ ccoctl alibabacloud delete-ram-users --name <name> --region=<region> --credentials-requests-dir=<path_to_directory_with_list_of_credentials_requests>/credrequests | ||
| ``` | ||
| where: | ||
| - `name` is the name used to tag any cloud resources that are created for tracking. | ||
| - `region` is the Alibaba Cloud region in which cloud resources will be created. | ||
| - `credentials-requests-dir` is the directory containing files of component CredentialsRequests. | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,130 @@ | ||
| /* | ||
| Copyright 2021 The OpenShift Authors. | ||
|
|
||
| Licensed under the Apache License, Version 2.0 (the "License"); | ||
| you may not use this file except in compliance with the License. | ||
| You may obtain a copy of the License at | ||
|
|
||
| http://www.apache.org/licenses/LICENSE-2.0 | ||
|
|
||
| Unless required by applicable law or agreed to in writing, software | ||
| distributed under the License is distributed on an "AS IS" BASIS, | ||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| See the License for the specific language governing permissions and | ||
| limitations under the License. | ||
| */ | ||
|
|
||
| package alibabacloud | ||
|
|
||
| import ( | ||
| "github.com/aliyun/alibaba-cloud-sdk-go/sdk" | ||
| "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider" | ||
| "github.com/aliyun/alibaba-cloud-sdk-go/services/ram" | ||
| "log" | ||
| ) | ||
|
|
||
| //go:generate mockgen -source=./client.go -destination=./mock/client_generated.go -package=mock | ||
|
|
||
| // Client is a wrapper object for actual Alibaba Cloud SDK clients to allow for easier testing. | ||
| type Client interface { | ||
| //RAM | ||
| CreatePolicy(*ram.CreatePolicyRequest) (*ram.CreatePolicyResponse, error) | ||
| GetPolicy(*ram.GetPolicyRequest) (*ram.GetPolicyResponse, error) | ||
| CreatePolicyVersion(*ram.CreatePolicyVersionRequest) (*ram.CreatePolicyVersionResponse, error) | ||
| AttachPolicyToUser(*ram.AttachPolicyToUserRequest) (*ram.AttachPolicyToUserResponse, error) | ||
| CreateUser(*ram.CreateUserRequest) (*ram.CreateUserResponse, error) | ||
| GetUser(*ram.GetUserRequest) (*ram.GetUserResponse, error) | ||
| DeleteUser(*ram.DeleteUserRequest) (*ram.DeleteUserResponse, error) | ||
| CreateAccessKey(*ram.CreateAccessKeyRequest) (*ram.CreateAccessKeyResponse, error) | ||
| ListAccessKeys(*ram.ListAccessKeysRequest) (*ram.ListAccessKeysResponse, error) | ||
| DeleteAccessKey(*ram.DeleteAccessKeyRequest) (*ram.DeleteAccessKeyResponse, error) | ||
| DeletePolicy(request *ram.DeletePolicyRequest) (response *ram.DeletePolicyResponse, err error) | ||
| DetachPolicyFromUser(request *ram.DetachPolicyFromUserRequest) (response *ram.DetachPolicyFromUserResponse, err error) | ||
| ListPoliciesForUser(request *ram.ListPoliciesForUserRequest) (response *ram.ListPoliciesForUserResponse, err error) | ||
| DeletePolicyVersion(request *ram.DeletePolicyVersionRequest) (response *ram.DeletePolicyVersionResponse, err error) | ||
| ListPolicyVersions(request *ram.ListPolicyVersionsRequest) (response *ram.ListPolicyVersionsResponse, err error) | ||
| } | ||
|
|
||
| type alibabaCloudClient struct { | ||
| ramClient *ram.Client | ||
| } | ||
|
|
||
| func (c *alibabaCloudClient) CreatePolicy(request *ram.CreatePolicyRequest) (response *ram.CreatePolicyResponse, err error) { | ||
| return c.ramClient.CreatePolicy(request) | ||
| } | ||
|
|
||
| func (c *alibabaCloudClient) GetPolicy(request *ram.GetPolicyRequest) (response *ram.GetPolicyResponse, err error) { | ||
| return c.ramClient.GetPolicy(request) | ||
| } | ||
|
|
||
| func (c *alibabaCloudClient) CreatePolicyVersion(request *ram.CreatePolicyVersionRequest) (response *ram.CreatePolicyVersionResponse, err error) { | ||
| return c.ramClient.CreatePolicyVersion(request) | ||
| } | ||
|
|
||
| func (c *alibabaCloudClient) AttachPolicyToUser(input *ram.AttachPolicyToUserRequest) (*ram.AttachPolicyToUserResponse, error) { | ||
| return c.ramClient.AttachPolicyToUser(input) | ||
| } | ||
|
|
||
| func (c *alibabaCloudClient) DeletePolicy(request *ram.DeletePolicyRequest) (response *ram.DeletePolicyResponse, err error) { | ||
| return c.ramClient.DeletePolicy(request) | ||
| } | ||
|
|
||
| func (c *alibabaCloudClient) DetachPolicyFromUser(request *ram.DetachPolicyFromUserRequest) (response *ram.DetachPolicyFromUserResponse, err error) { | ||
| return c.ramClient.DetachPolicyFromUser(request) | ||
| } | ||
|
|
||
| func (c *alibabaCloudClient) ListPoliciesForUser(request *ram.ListPoliciesForUserRequest) (response *ram.ListPoliciesForUserResponse, err error) { | ||
| return c.ramClient.ListPoliciesForUser(request) | ||
| } | ||
|
|
||
| func (c *alibabaCloudClient) CreateUser(input *ram.CreateUserRequest) (*ram.CreateUserResponse, error) { | ||
| return c.ramClient.CreateUser(input) | ||
| } | ||
|
|
||
| func (c *alibabaCloudClient) GetUser(input *ram.GetUserRequest) (*ram.GetUserResponse, error) { | ||
| return c.ramClient.GetUser(input) | ||
| } | ||
|
|
||
| func (c *alibabaCloudClient) DeleteUser(input *ram.DeleteUserRequest) (*ram.DeleteUserResponse, error) { | ||
| return c.ramClient.DeleteUser(input) | ||
| } | ||
|
|
||
| func (c *alibabaCloudClient) ListAccessKeys(input *ram.ListAccessKeysRequest) (*ram.ListAccessKeysResponse, error) { | ||
| return c.ramClient.ListAccessKeys(input) | ||
| } | ||
|
|
||
| func (c *alibabaCloudClient) CreateAccessKey(input *ram.CreateAccessKeyRequest) (*ram.CreateAccessKeyResponse, error) { | ||
| return c.ramClient.CreateAccessKey(input) | ||
| } | ||
|
|
||
| func (c *alibabaCloudClient) DeleteAccessKey(input *ram.DeleteAccessKeyRequest) (*ram.DeleteAccessKeyResponse, error) { | ||
| return c.ramClient.DeleteAccessKey(input) | ||
| } | ||
|
|
||
| func (c *alibabaCloudClient) DeletePolicyVersion(input *ram.DeletePolicyVersionRequest) (*ram.DeletePolicyVersionResponse, error) { | ||
| return c.ramClient.DeletePolicyVersion(input) | ||
| } | ||
|
|
||
| func (c *alibabaCloudClient) ListPolicyVersions(input *ram.ListPolicyVersionsRequest) (*ram.ListPolicyVersionsResponse, error) { | ||
| return c.ramClient.ListPolicyVersions(input) | ||
| } | ||
|
|
||
| // NewClient creates our client wrapper object for the actual Alibaba Cloud clients we use. | ||
| func NewClient(regionId string) (Client, error) { | ||
| envProvider := provider.NewEnvProvider() | ||
| profileProvider := provider.NewProfileProvider() | ||
| pc := provider.NewProviderChain([]provider.Provider{envProvider, profileProvider}) | ||
| credential, err := pc.Resolve() | ||
| if err != nil { | ||
| log.Fatalf("Failed to resolve an authentication provider: %v", err) | ||
| } | ||
| config := sdk.NewConfig().WithScheme("https") | ||
|
|
||
| rc, err := ram.NewClientWithOptions(regionId, config, credential) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
| return &alibabaCloudClient{ | ||
| ramClient: rc, | ||
| }, nil | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jeana-redhat while this is fine for 'upstream docs' when we downstream these docs we need to remove / redirect this to docs we have that don't reside on github.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, would def be pointing to the product docs version of this content 👍