Integración de un producto AWS Marketplace de for Containers Anywhere con License Manager - AWS Marketplace

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

Integración de un producto AWS Marketplace de for Containers Anywhere con License Manager

Siga estas instrucciones para realizar la integración AWS License Manager con un AWS Marketplace producto de Containers Anywhere para Amazon EKS Anywhere, Amazon ECS AnywhereEC2, Amazon o una infraestructura local.

Para obtener información general sobre la integración de License Manager con AWS Marketplace, incluidos los modelos de licencia disponibles, consulteContrata los precios de los productos Container con AWS License Manager. Para obtener más información sobre AWS License Manager, consulte la Guía del usuario de AWS License Manager y la sección AWS License Manager de la Referencia de comandos de la AWS CLI .

Integración de un producto AWS Marketplace de for Containers Anywhere con License Manager

Siga las siguientes instrucciones para integrar su AWS Marketplace producto de Containers Anywhere con AWS License Manager.

Para integrar su AWS Marketplace producto de Containers Anywhere con License Manager
  1. Abra un navegador web e inicie sesión en AWS Marketplace Management Portal.

  2. Cree un ID de producto para su producto de contenedor realizando los siguientes pasos. Utilizará este ID en su imagen del contenedor para comprobar las licencias en un paso posterior.

    1. En la barra de menús, expanda Recursos y elija Contenedor.

    2. Introduzca un nombre orientado al cliente para su producto y elija Crear. Puede cambiar este nombre posteriormente.

    3. Anote el ID del proyecto. Lo usará al crear o actualizar los detalles de precios del producto.

      sugerencia

      Si pierde el identificador de su producto, puede encontrarlo AWS Marketplace Management Portal seleccionando Container en el menú Activos. La página Contenedores muestra una lista de tus productos con el producto asociadoIDs.

  3. Descarga la versión pública más reciente AWS SDK e instálala en tu aplicación contenedora. Puede encontrar las instrucciones de instalación que prefiera AWS SDK en Tools to Build on AWS.

    nota

    Para llamar a API las operaciones de License Manager desde Amazon EKS Anywhere o desde un clúster de Kubernetes no proporcionado por AWS, debe utilizar un clúster compatible. AWS SDK Para ver una lista de las compatibles AWS SDKs, consulte Uso de un soporte. AWS SDK

  4. Cree un AWS License Manager cliente con un proveedor de credenciales personalizado para que pueda proporcionar credenciales a la aplicación contenedora implementada tanto en las instalaciones AWS como en las instalaciones. Para ver el código fuente completo de un proveedor de credenciales personalizado, LicenseCredentialProvider, consulte las siguientes secciones:

    LicenseCredentialsProvideramplía la cadena AWS SDK de proveedores de credenciales predeterminada para su uso local mediante la adición de. LicenseManagerTokenCredentialsProvider Esto proporciona credenciales mediante el uso de tokens de identidad OIDC emitidos por License Manager en entornos locales. Debe incluir el código fuente para LicenseCredentialsProvider en la ruta de clases de su aplicación.

    nota

    Ampliar el DefaultCredentialsProvider permite que la misma aplicación contenedora obtenga credenciales cuando se ejecuta en un entorno local AWS y cuando se ejecuta en él. Si la aplicación de contenedor ya usa una cadena de proveedores de credenciales personalizada en lugar de la predeterminada, también se puede ampliar agregando LicenseManagerTokenCredentialsProvider a la cadena personalizada.

    El siguiente fragmento de código es un ejemplo de cómo crear un AWS License Manager cliente con Java.

    LicenseManagerClientBuilder clientBuilder = LicenseManagerClient.builder().credentialsProvider(LicenseCredentialsProvider.create());
  5. Llama a la CheckoutLicense API operación mediante el aws license-manager checkout-license comando de cada imagen de contenedor de pago de tu oferta de productos. Esto comprueba que el comprador tiene derecho a utilizar una licencia para su aplicación. Si el comprador tiene derecho a la solicitud, CheckoutLicense acepta y devuelve los derechos solicitados y sus valores. Si el comprador no tiene derecho a la solicitud, CheckoutLicense arroja una excepción.

    Se requieren los siguientes parámetros para llamar a la CheckoutLicense API operación:

    • CheckoutType: los valores válidos son PROVISIONAL o PERPETUAL:

      • Use PERPETUAL cuando se agote la cantidad de derechos retirados del conjunto.

        Ejemplo: el comprador tiene derecho a procesar 500 GB de datos. A medida que continúa procesando los datos, la cantidad se descuenta y se agota del conjunto de 500 GB.

      • Utilice PROVISIONAL para derechos de licencia flotantes, en los que los derechos se retiran del conjunto y se devuelven después de su uso.

        Ejemplo: el usuario tiene derecho a 500 usuarios simultáneos en la aplicación. A medida que los usuarios inician o cierran sesión, los usuarios son descontados o devueltos al grupo de 500 usuarios. Para obtener más información sobre los derechos de licencia flotantes, consulte Derechos de licencias flotantes con License Manager.

    • ClientToken: un identificador único que distingue entre mayúsculas y minúsculas. Recomendamos usar un valor aleatorio UUID para cada solicitud única.

    • Entitlements: una lista de derechos para retirar.

      • En el caso de derechos de características, proporcione las propiedades Name y Unit como se indica a continuación.

        { "Name": "<Entitlement_Name>", "Unit": "None" }
      • Para los derechos contados, proporcione las propiedades Name, Unit y Count de la siguiente manera.

        { "Name": "<Entitlement_Name>", "Unit": "<Entitlement_Unit>", "Value": <Desired_Count> }
    • KeyFingerprint: la huella digital clave de las licencias emitidas por AWS Marketplace es aws:294406891311:AWS/Marketplace:issuer-fingerprint. El uso de esta huella digital clave garantiza que la licencia sea emitida por una entidad poco fiable AWS Marketplace y no por ella.

    • ProductSKU— El identificador del producto generado AWS Marketplace Management Portal en los pasos anteriores.

    El siguiente fragmento es un ejemplo de una llamada que utiliza la CheckoutLicense API operación que utiliza el. AWS CLI

    aws license-manager checkout-license \ --product-sku "2205b290-19e6-4c76-9eea-377d6bf71a47" \ --checkout-type "PROVISIONAL" \ --client-token "79464194dca9429698cc774587a603a1" \ --entitlements "Name=AWS::Marketplace::Usage/Drawdown/DataConsumption, Value=10, Unit=Gigabytes" \ --key-fingerprint "aws:294406891311:AWS/Marketplace:issuer-fingerprint"
    nota

    Para comprobar las licencias, las aplicaciones de contenedor requieren acceso a la red saliente para poder utilizar License Manager. Es posible que las aplicaciones implementadas en las instalaciones experimenten un acceso lento o poco fiable a la red saliente. Estas aplicaciones deben incluir los reintentos adecuados al llamar a License Manager. Para obtener más información, consulte Prácticas recomendadas para la integración en License Manager para implementaciones en las instalaciones.

  6. Llame a la CheckoutLicense API operación con regularidad para identificar cualquier cambio en las licencias de los clientes debido a renovaciones, actualizaciones o cancelaciones realizadas en ellas. AWS Marketplace La cadencia depende de la aplicación. Recomendamos comprobar las licencias una vez al día para detectar los cambios automáticamente sin la intervención del comprador.

    Es posible que una aplicación implementada en las instalaciones tenga un acceso a la red saliente poco fiable para comprobar las licencias con regularidad. En esos casos, la aplicación debe utilizar licencias almacenadas en caché para garantizar una resiliencia suficiente. Para obtener más información, consulte Prácticas recomendadas para la integración en License Manager para implementaciones en las instalaciones.

  7. Tras integrar la llamada a CheckoutLicense en la aplicación de contenedor, cree una nueva versión de la imagen del contenedor de Docker con los cambios.

  8. Actualice el diagrama de Helm de su aplicación para aceptar un secreto de Kubernetes como entrada opcional que contenga la configuración para acceder a las licencias mediante License Manager. APIs El secreto de configuración contendrá un token de identidad emitido por License Manager y un AWS Identity and Access Management rol que utilizará el proveedor de credenciales personalizadas descrito anteriormente para obtener AWS las credenciales para llamar a License Manager APIs cuando la aplicación contenedora se despliegue localmente. Además, agregue la Región de AWS como entrada con un valor predeterminado de us-east-1.

    Los compradores que desplieguen la aplicación contenedora de forma local pueden crear el secreto de Kubernetes a través de la AWS Marketplace experiencia de compra de productos en contenedores. Proporcione el nombre del secreto de Kubernetes como entrada al comando helm install. El secreto de configuración se configura en el siguiente formato.

    apiVersion: v1 kind: Secret metadata: name: aws-marketplace-license-config type: Opaque stringData: license_token: <token_value> // License Manager issued JWT token iam_role: <role_arn> // AWS Identity and Access Management role to assume with license token
  9. Actualice la plantilla de despliegue de la aplicación en el diagrama de Helm para las imágenes de contenedores integradas con ellas para incluir AWS License Manager lo siguiente:

    • Cuenta de servicio para el pod: la cuenta de servicio es necesaria para las implementaciones de Helm en AmazonEKS. Se usa para obtener permisos para llamar a API las operaciones de License Manager mediante la configuración de IAM roles para la cuenta de servicio en la imagen del contenedor. Para obtener más información sobre las IAM funciones de las cuentas de servicio, consulte las IAMfunciones de las cuentas de servicio.

    • Acceso con licencia para implementaciones locales: el secreto de configuración de la licencia es necesario para proporcionar las credenciales y los permisos adecuados para llamar a las API operaciones de License Manager para las implementaciones de Helm en entornos locales. Los compradores generarán y proporcionarán el secreto de licencia a Helm a partir de su experiencia de compra. AWS Marketplace

    El siguiente fragmento de código es un ejemplo de especificación de implementación con el secreto de la cuenta de servicio, la configuración de la licencia y la imagen extraída.

    apiVersion: apps/v1 kind: Deployment metadata: name: example-app spec: replicas: 1 selector: matchLabels: app: example-app template: metadata: labels: app: example-app spec: // Service account for pod serviceAccountName: {{ .Values.serviceAccountName }} containers: - name: example-app image: example-app ports: - containerPort: 8001 // Add the following conditional attributes {{ - if .Values.awsmp.licenseConfigSecretName }} //Mount the license volume to the container image volumeMounts: - name: awsmp-product-license mountPath: "/var/run/secrets/product-license" //Add following environment variable to container for credential provider env: - name: AWS_WEB_IDENTITY_REFRESH_TOKEN_FILE value: "/var/run/secrets/product-license/license_token" - name: AWS_ROLE_ARN valueFrom: secretKeyRef: name: {{ .Values.aws.licenseConfigSecretName }} key: iam_role //Mount the license secret as a volume to the pod volumes: - name: awsmp-product-license secret: secretName: {{ .Values.aws.licenseConfigSecretName }} optional: true {{ - end }}
    nota

    El secreto de configuración de la licencia es opcional. Los compradores solo utilizan el valor para las implementaciones locales. Para AWS las implementaciones, la especificación de implementación debe incluir una cuenta de servicio para las imágenes integradas de License Manager.

  10. Pruebe la integración de License Manager de forma local y en Amazon EKS siguiendo los pasos de las siguientes secciones:

    1. Prueba de la integración de License Manager localmente

    2. Probando la integración de License Manager en Amazon EKS

  11. Tras comprobar correctamente la integración de License Manager tanto en AWS las instalaciones como en las instalaciones, puede crear su lista de productos de contenedores siguiendo los pasos que se indican enCreación de un producto de contenedor.

Prueba de la integración de License Manager localmente

Puede usar minikube o cualquier otra configuración para probar la integración de License Manager en clústeres de Kubernetes de forma local. Asegúrese de que el clúster de Kubernetes tenga acceso saliente a Internet para llamar a las operaciones de License Manager. API

Para probar una integración de License Manager localmente
  1. Cree una licencia de prueba en una cuenta de vendedor de prueba con los derechos que desee. Para configurar una licencia de prueba, consulte CreateLicensela Referencia.AWS License Manager API O bien, utilice el siguiente script para crear una licencia de prueba y, a continuación, cree una concesión de licencia a una cuenta de comprador de prueba para consumir la licencia. El siguiente script usa las credenciales de la cuenta de vendedor de prueba.

    read -p 'AWS Account for test buyer: ' TEST_BUYER_ACCOUNT_ID read -p 'License entitlements: ' ENTITLEMENTS # TEST_SELLER_ACCOUNT_ID="109876543210" # ENTITLEMENTS="{\"Name\": \"ByData\",\"MaxCount\": 1000,\"Overage\":true,\"Unit\": \"Gigabits\",\"AllowCheckIn\": true}" # Create License NOW=$(date +"%Y-%m-%dT00:00:00+00:00") PRODUCT_NAME="My awesome product" PRODUCT_SKU="c97b7825-44c4-4f42-b025-12baa4c171e0" LICENSE_BENEFICIARY=" arn:aws:iam::$TEST_BUYER_ACCOUNT_ID:root " LICENSE_ISSUER_NAME="test-seller" LICENSE_NAME="test-seller-license" CLIENT_TOKEN="b3920968-a94f-4547-af07-3dd232319367" CONSUMPTION_TTL=180 CONSUMPTION_RENEW_TYPE="None" HOME_REGION="us-east-1" LICENSE_ARN=$(aws license-manager create-license --license-name "$LICENSE_NAME" --product-name "$PRODUCT_NAME" --product-sku "$PRODUCT_SKU" --issuer Name="$LICENSE_ISSUER_NAME" --home-region "$HOME_REGION" --validity Begin="$NOW" --entitlements "$ENTITLEMENTS" --beneficiary "$LICENSE_BENEFICIARY" --consumption-configuration RenewType="$CONSUMPTION_RENEW_TYPE",ProvisionalConfiguration={MaxTimeToLiveInMinutes=$CONSUMPTION_TTL} --client-token "$CLIENT_TOKEN" | jq -r ".LicenseArn" ) echo "License arn: $LICENSE_ARN" # Create Grant GRANT_TOKEN="e9a14140-4fca-4219-8230-57511a6ea6" GRANT_NAME="test-grant" GRANT_ARN=$(aws license-manager create-grant --grant-name "$GRANT_NAME" --license-arn "$LICENSE_ARN" --principals "$LICENSE_BENEFICIARY" --home-region "$HOME_REGION" --client-token "$GRANT_TOKEN" --allowed-operations "CheckoutLicense" "CheckInLicense" "ExtendConsumptionLicense" "CreateToken" | jq -r ".GrantArn") echo "Grant arn: $GRANT_ARN"
  2. Cree un secreto de Kubernetes con el token y el IAM rol de la licencia utilizando el formato de secreto definido anteriormente. Utilice la CreateToken API operación License Manager para generar un token de licencia. A continuación, utilice la IAM CreateRole API operación para crear un IAM rol con permisos y una política de confianza. Vea un ejemplo en el siguiente script. El siguiente script utiliza las credenciales de la cuenta de comprador de prueba.

    read -p 'AWS Account for test license: ' TEST_ACCOUNT_ID read -p 'License Arn' LICENSE_ARN # Create IAM Role ROLE_NAME="AWSLicenseManagerConsumptionTestRole" ROLE_DESCRIPTION="Role to test AWS License Manager integration on-prem" ROLE_POLICY_ARN="arn:aws:iam::aws:policy/service-role/AWSLicenseManagerConsumptionPolicy" ROLE_TRUST_POLICY="{\"Version\": \"2012-10-17\",\"Statement\": [{ \"Effect\":\"Allow\", \"Principal\": { \"Federated\": \"openid-license-manager.amazonaws.com\" }, \"Action\": \"sts:AssumeRoleWithWebIdentity\",\"Condition\": { \"ForAnyValue:StringLike\": { \"openid-license-manager.amazonaws.com:amr\": \"aws:license-manager:token-issuer-account-id:${TEST_ACCOUNT_ID}\" }}}]}" ROLE_SESSION_DURATION=3600 ROLE_ARN=$(aws iam create-role --role-name "$ROLE_NAME" --description "$ROLE_DESCRIPTION" --assume-role-policy-document "$ROLE_TRUST_POLICY" --max-session-duration $ROLE_SESSION_DURATION | jq ".Role" | jq -r ".Arn") aws iam attach-role-policy --role-name "$ROLE_NAME" --policy-arn "$ROLE_POLICY_ARN" echo "Role arn: $ROLE_ARN" # Create Token CLIENT_TOKEN="b3920968-a94f-4547-af07-3dd232319367" TOKEN=$(aws license-manager create-token --license-arn $LICENSE_ARN --role-arns $ROLE_ARN --client-token $CLIENT_TOKEN | jq '.Token') echo "License access token: $TOKEN"c
  3. Configura cualquier clúster de Kubernetes alojado en un entorno externo. AWS Utilícelo para comprobar que las aplicaciones contenedoras se pueden conectar AWS License Manager API a entornos distintos AWS y que el proveedor de credenciales personalizadas está bien integrado en la aplicación.

  4. Implemente el token de licencia y el IAM rol generados anteriormente en el clúster local de Kubernetes.

    kubectl create secret generic "awsmp-license-access-config" \ --from-literal=license_token=${TOKEN} \ --from-literal=iam_role=${ROLE_ARN}
  5. Implemente su aplicación a través de Helm con el nombre secreto como entrada y compruebe que la aplicación puede llamar a API las operaciones de License Manager para realizar comprobaciones de derechos. Para ver los cambios en Helm y en las especificaciones de implementación, consulte el paso 9 de Integración de un producto AWS Marketplace de for Containers Anywhere con License Manager.

Probando la integración de License Manager en Amazon EKS

También puede probar la integración de License Manager en AmazonEKS. Compruebe que la aplicación puede llamar a las API operaciones de License Manager sin el secreto de configuración de la licencia. Asegúrese también de que la cuenta de servicio se pueda utilizar para configurar las IAM funciones de las cuentas de servicio (IRSA) y proporcionar las credenciales pertinentes a la aplicación.

Para probar la integración de License Manager en Amazon EKS
  1. Cree una licencia de prueba en una cuenta de vendedor de prueba con los derechos que desee. Consulte la CreateLicense APIreferencia para configurar su licencia de prueba o utilice el siguiente script para crear una y crear una concesión de licencia a una cuenta de comprador de prueba para consumir la licencia. El siguiente script usa las credenciales de la cuenta de vendedor de prueba.

    read -p 'AWS Account for test buyer: ' TEST_BUYER_ACCOUNT_ID read -p 'License entitlements: ' ENTITLEMENTS # TEST_SELLER_ACCOUNT_ID="109876543210" # ENTITLEMENTS="{\"Name\": \"ByData\",\"MaxCount\": 1000,\"Overage\": true,\"Unit\": \"Gigabits\",\"AllowCheckIn\": true}" # Create License NOW=$(date +"%Y-%m-%dT00:00:00+00:00") PRODUCT_NAME="My awesome product" PRODUCT_SKU="c97b7825-44c4-4f42-b025-12baa4c171e0" LICENSE_BENEFICIARY=" arn:aws:iam::$TEST_BUYER_ACCOUNT_ID:root " LICENSE_ISSUER_NAME="test-seller" LICENSE_NAME="test-seller-license" CLIENT_TOKEN="b3920968-a94f-4547-af07-3dd232319367" CONSUMPTION_TTL=180 CONSUMPTION_RENEW_TYPE="None" HOME_REGION="us-east-1" LICENSE_ARN=$(aws license-manager create-license --license-name "$LICENSE_NAME" --product-name "$PRODUCT_NAME" --product-sku "$PRODUCT_SKU" --issuer Name="$LICENSE_ISSUER_NAME" --home-region "$HOME_REGION" --validity Begin="$NOW" --entitlements "$ENTITLEMENTS" --beneficiary "$LICENSE_BENEFICIARY" --consumption-configuration RenewType="$CONSUMPTION_RENEW_TYPE",ProvisionalConfiguration={MaxTimeToLiveInMinutes=$CONSUMPTION_TTL} --client-token "$CLIENT_TOKEN" | jq -r ".LicenseArn" ) echo "License arn: $LICENSE_ARN" # Create Grant GRANT_TOKEN="e9a14140-4fca-4219-8230-57511a6ea6" GRANT_NAME="test-grant" GRANT_ARN=$(aws license-manager create-grant --grant-name "$GRANT_NAME" --license-arn "$LICENSE_ARN" --principals "$LICENSE_BENEFICIARY" --home-region "$HOME_REGION" --client-token "$GRANT_TOKEN" --allowed-operations "CheckoutLicense" "CheckInLicense" "ExtendConsumptionLicense" "CreateToken" | jq -r ".GrantArn") echo "Grant arn: $GRANT_ARN"
  2. Crea un EKS clúster de Amazon de prueba con las configuraciones deseadas o ejecuta los siguientes comandos para usar una configuración predeterminada.

    aws ec2 create-key-pair --region us-west-2 --key-name eks-key-pair
    eksctl create cluster \ --name awsmp-eks-test-example \ --region us-west-2 \ --with-oidc \ --ssh-access \ --ssh-public-key eks-key-pair
  3. Cree una cuenta de servicio para un clúster existente y asóciela a un IAM rol. El siguiente comando crea un IAM rol conAWSLicenseManagerConsumptionPolicy. A continuación, el comando lo adjunta a la cuenta de test_sa servicio del EKS clúster de Amazon donde se deben implementar las imágenes integradas de License Manager. Como resultado, la cuenta de servicio puede obtener las credenciales adecuadas para llamar a las API operaciones de License Manager.

    eksctl create iamserviceaccount \ --name test_sa \ --namespace test_namespace \ --cluster awsmp-eks-test-example \ --attach-policy-arn "arn:aws:iam::aws:policy/service-role/AWSLicenseManagerConsumptionPolicy" \ --approve \ --override-existing-serviceaccounts
  4. Implemente la aplicación mediante Helm en la cuenta de servicio a la que está asociada la IAM función desde el comando anterior. Compruebe que la aplicación pueda llamar a API las operaciones de License Manager para realizar comprobaciones de derechos.

Derechos de licencias flotantes con License Manager

En el caso de las licencias flotantes, a medida que los usuarios inician sesión en la aplicación, se extrae una licencia del conjunto de licencias disponibles. A medida que los usuarios cierran sesión, las licencias se vuelven a agregar al conjunto de licencias disponibles.

En el caso de las licencias flotantes, la aplicación utiliza la CheckoutLicense API operación para extraer las autorizaciones del fondo de autorizaciones cuando se utiliza el recurso. La respuesta de la CheckoutLicense API operación incluye un token de consumo de licencias, que es un identificador único para el proceso de compra. El token de consumo de licencias puede realizar acciones adicionales en los derechos que se retiran, como reintegrarlos al conjunto de licencias o prolongar el proceso de retirada.

Cuando el recurso ya no está en uso, la aplicación utiliza la CheckInLicense API operación para volver a incluir los derechos en el pool.

aws license-manager check-in-license \ --license-consumption-token "f1603b3c1f574b7284db84a9e771ee12"

Si se produce un error al reintegrar una licencia en el conjunto, por ejemplo, si la aplicación se bloquea durante la operación, el derecho se reintegra automáticamente en el conjunto transcurridos 60 minutos. Por este motivo, si el recurso se utiliza durante más de 60 minutos, se recomienda mantener el derecho retirado del conjunto. Para ello, utilice la ExtendLicenseConsumption API operación mientras se utilice el recurso.

aws license-manager extend-license-consumption \ --license-consumption-token "f1603b3c1f574b7284db84a9e771ee12"

Prácticas recomendadas para la integración en License Manager para implementaciones en las instalaciones

Las implementaciones de aplicaciones de contenedores en un entorno local pueden dar lugar a un acceso a la red saliente poco fiable. Utilice las siguientes prácticas recomendadas para aumentar la resiliencia y evitar que los compradores interrumpan el servicio debido a posibles problemas causados por una mala conectividad a Internet:

  • Reintento adecuado: los problemas transitorios de red pueden impedir que la aplicación se conecte a. AWS License Manager Implemente reintentos para hasta 30 minutos, con una reducción exponencial. Esta opción puede ayudar a evitar interrupciones a corto plazo o problemas de red.

  • Evite límites estrictos: las aplicaciones implementadas en clústeres conectados pueden comprobar periódicamente las licencias para identificar cualquier cambio debido a actualizaciones o renovaciones. Con un acceso saliente poco fiable, es posible que la aplicación no pueda identificar esos cambios. Siempre que sea posible, la aplicación debe evitar la interrupción del servicio a los compradores debido a la imposibilidad de comprobar las licencias a través de License Manager. Las aplicaciones pueden volver a una versión de prueba gratuita o de código abierto cuando la licencia vence y no pueden comprobar si una licencia es válida.

  • Notifique a los clientes: cuando se utiliza una licencia en caché, los cambios en la licencia (incluidas las renovaciones o las actualizaciones) no se reflejan automáticamente en la carga de trabajo en curso. Notifique a sus clientes (que deben volver a permitir el acceso saliente a la aplicación de forma temporal) para que la aplicación pueda actualizar su licencia en caché. Por ejemplo, notifique a los clientes a través de la propia aplicación o a través de su documentación. Del mismo modo, cuando recurra a un conjunto más reducido de funcionalidades, notifique a los clientes que sus derechos están agotados o que la licencia ha caducado. Luego, pueden elegir entre actualizar o renovar.

LicenseManagerCredentialsProvider: implementación de Java

LicenseCredentialsProvideramplía la cadena AWS SDK de proveedores de credenciales predeterminada para su uso local mediante la adición de. LicenseManagerTokenCredentialsProvider

LicenseCredentialsProvider

package com.amazon.awsmp.license; import software.amazon.awssdk.auth.credentials.AwsCredentials; import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider; import software.amazon.awssdk.auth.credentials.AwsCredentialsProviderChain; import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider; import software.amazon.awssdk.auth.credentials.internal.LazyAwsCredentialsProvider; import software.amazon.awssdk.utils.SdkAutoCloseable; public class LicenseCredentialsProvider implements AwsCredentialsProvider, SdkAutoCloseable { private static final LicenseCredentialsProvider CREDENTIALS_PROVIDER = new LicenseCredentialsProvider(); private final LazyAwsCredentialsProvider providerChain; private LicenseCredentialsProvider() { this.providerChain = createChain(); } public static LicenseCredentialsProvider create() { return CREDENTIALS_PROVIDER; } @Override public AwsCredentials resolveCredentials() { return this.providerChain.resolveCredentials(); } @Override public void close() { this.providerChain.close(); } private LazyAwsCredentialsProvider createChain() { return LazyAwsCredentialsProvider.create(() -> { AwsCredentialsProvider[] credentialsProviders = new AwsCredentialsProvider[]{ DefaultCredentialsProvider.create(), LicenseManagerTokenCredentialsProvider.create()}; return AwsCredentialsProviderChain.builder().reuseLastProviderEnabled(true) .credentialsProviders(credentialsProviders).build(); }); } }

LicenseManagerTokenCredentialsProvider

LicenseManagerTokenCredentialsProviderproporciona credenciales mediante el uso de tokens de identidad OIDC emitidos por License Manager en entornos locales. Debe incluir el código fuente para LicenseCredentialsProvider en la ruta de clases de su aplicación.

package com.amazon.awsmp.license; import software.amazon.awssdk.auth.credentials.AnonymousCredentialsProvider; import software.amazon.awssdk.auth.credentials.AwsCredentials; import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider; import software.amazon.awssdk.core.SdkSystemSetting; import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration; import software.amazon.awssdk.core.retry.RetryPolicyContext; import software.amazon.awssdk.core.retry.conditions.OrRetryCondition; import software.amazon.awssdk.core.retry.conditions.RetryCondition; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.regions.providers.DefaultAwsRegionProviderChain; import software.amazon.awssdk.services.licensemanager.LicenseManagerClient; import software.amazon.awssdk.services.licensemanager.model.GetAccessTokenRequest; import software.amazon.awssdk.services.licensemanager.model.GetAccessTokenResponse; import software.amazon.awssdk.services.sts.StsClient; import software.amazon.awssdk.services.sts.auth.StsAssumeRoleWithWebIdentityCredentialsProvider; import software.amazon.awssdk.services.sts.model.AssumeRoleWithWebIdentityRequest; import software.amazon.awssdk.services.sts.model.IdpCommunicationErrorException; import software.amazon.awssdk.utils.IoUtils; import software.amazon.awssdk.utils.SdkAutoCloseable; import software.amazon.awssdk.utils.StringUtils; import software.amazon.awssdk.utils.SystemSetting; import java.io.IOException; import java.io.InputStream; import java.io.UncheckedIOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.time.Duration; import java.util.function.Supplier; public class LicenseManagerTokenCredentialsProvider implements AwsCredentialsProvider, SdkAutoCloseable { private final StsAssumeRoleWithWebIdentityCredentialsProvider credentialsProvider; private final RuntimeException loadException; private Path licenseAccessTokenFile; private String roleArn; private String roleSessionName; private StsClient stsClient; private LicenseManagerClient lmClient; public static LicenseManagerTokenCredentialsProvider create() { return new Builder().build(); } @Override public AwsCredentials resolveCredentials() { if (this.loadException != null) { throw this.loadException; } return this.credentialsProvider.resolveCredentials(); } @Override public void close() { IoUtils.closeQuietly(this.credentialsProvider, null); IoUtils.closeQuietly(this.stsClient, null); IoUtils.closeIfCloseable(this.lmClient, null); } private LicenseManagerTokenCredentialsProvider(Builder builder) { StsAssumeRoleWithWebIdentityCredentialsProvider credentialsProvider = null; RuntimeException loadException = null; try { this.licenseAccessTokenFile = Paths.get(StringUtils.trim(LicenseSystemSetting.AWS_WEB_IDENTITY_REFRESH_TOKEN_FILE.getStringValueOrThrow())); this.roleArn = SdkSystemSetting.AWS_ROLE_ARN.getStringValueOrThrow(); this.roleSessionName = SdkSystemSetting.AWS_ROLE_SESSION_NAME.getStringValue().orElse("aws-sdk-java-" + System.currentTimeMillis()); this.stsClient = builder.stsClient != null ? builder.stsClient : StsClientFactory.create(); this.lmClient = builder.lmClient != null ? builder.lmClient : LicenseManagerClientFactory.create(); AssumeRoleWithWebIdentityRequest request = AssumeRoleWithWebIdentityRequest.builder() .roleArn(this.roleArn).roleSessionName(this.roleSessionName).build(); Supplier<AssumeRoleWithWebIdentityRequest> supplier = new AssumeRoleRequestSupplier(request, this.licenseAccessTokenFile, this.lmClient); credentialsProvider = StsAssumeRoleWithWebIdentityCredentialsProvider.builder() .stsClient(this.stsClient).refreshRequest(supplier).build(); } catch (RuntimeException ex) { loadException = ex; } this.credentialsProvider = credentialsProvider; this.loadException = loadException; } public static final class Builder { private Path licenseAccessTokenFile; private String roleArn; private String roleSessionName; private StsClient stsClient; private LicenseManagerClient lmClient; public LicenseManagerTokenCredentialsProvider build() { return new LicenseManagerTokenCredentialsProvider(this); } public LicenseManagerTokenCredentialsProvider.Builder licenseAccessTokenFile(Path licenseAccessTokenFile) { this.licenseAccessTokenFile = licenseAccessTokenFile; return this; } public LicenseManagerTokenCredentialsProvider.Builder roleArn(String roleArn) { this.roleArn = roleArn; return this; } public LicenseManagerTokenCredentialsProvider.Builder roleSessionName(String roleSessionName) { this.roleSessionName = roleSessionName; return this; } public LicenseManagerTokenCredentialsProvider.Builder stsClient(StsClient stsClient) { this.stsClient = stsClient; return this; } public LicenseManagerTokenCredentialsProvider.Builder lmClient(LicenseManagerClient lmClient) { this.lmClient = lmClient; return this; } } private static final class AssumeRoleRequestSupplier implements Supplier { private final LicenseManagerClient lmClient; private final AssumeRoleWithWebIdentityRequest request; private final Path webIdentityRefreshTokenFile; AssumeRoleRequestSupplier(final AssumeRoleWithWebIdentityRequest request, final Path webIdentityRefreshTokenFile, final LicenseManagerClient lmClient) { this.lmClient = lmClient; this.request = request; this.webIdentityRefreshTokenFile = webIdentityRefreshTokenFile; } public AssumeRoleWithWebIdentityRequest get() { return this.request.toBuilder() .webIdentityToken(getIdentityToken()) .build(); } private String getIdentityToken() { return refreshIdToken(readRefreshToken(this.webIdentityRefreshTokenFile)); } private String readRefreshToken(Path file) { try (InputStream webIdentityRefreshTokenStream = Files.newInputStream(file)) { return IoUtils.toUtf8String(webIdentityRefreshTokenStream); } catch (IOException e) { throw new UncheckedIOException(e); } } private String refreshIdToken(String licenseRefreshToken) { final GetAccessTokenRequest request = GetAccessTokenRequest.builder() .token(licenseRefreshToken) .build(); GetAccessTokenResponse response = this.lmClient.getAccessToken(request); return response.accessToken(); } } private static final class LicenseManagerClientFactory { private static final Duration DEFAULT_API_TIMEOUT = Duration.ofSeconds(30); private static final Duration DEFAULT_API_ATTEMPT_TIMEOUT = Duration.ofSeconds(10); public static LicenseManagerClient create() { return getLicenseManagerClient(); } private static LicenseManagerClient getLicenseManagerClient() { ClientOverrideConfiguration configuration = ClientOverrideConfiguration.builder() .apiCallTimeout(DEFAULT_API_TIMEOUT) .apiCallAttemptTimeout(DEFAULT_API_ATTEMPT_TIMEOUT) .build(); LicenseManagerClient client = LicenseManagerClient.builder() .region(configureLicenseManagerRegion()) .credentialsProvider(AnonymousCredentialsProvider.create()) .overrideConfiguration(configuration).build(); return client; } private static Region configureLicenseManagerRegion() { Region defaultRegion = Region.US_EAST_1; Region region; try { region = (new DefaultAwsRegionProviderChain()).getRegion(); } catch (RuntimeException ex) { region = defaultRegion; } return region; } } private static final class StsClientFactory { private static final Duration DEFAULT_API_TIMEOUT = Duration.ofSeconds(30); private static final Duration DEFAULT_API_ATTEMPT_TIMEOUT = Duration.ofSeconds(10); public static StsClient create() { return getStsClient(); } private static StsClient getStsClient() { OrRetryCondition retryCondition = OrRetryCondition.create(new StsRetryCondition(), RetryCondition.defaultRetryCondition()); ClientOverrideConfiguration configuration = ClientOverrideConfiguration.builder() .apiCallTimeout(DEFAULT_API_TIMEOUT) .apiCallAttemptTimeout(DEFAULT_API_ATTEMPT_TIMEOUT) .retryPolicy(r -> r.retryCondition(retryCondition)) .build(); return StsClient.builder() .region(configureStsRegion()) .credentialsProvider(AnonymousCredentialsProvider.create()) .overrideConfiguration(configuration).build(); } private static Region configureStsRegion() { Region defaultRegion = Region.US_EAST_1; Region stsRegion; try { stsRegion = (new DefaultAwsRegionProviderChain()).getRegion(); } catch (RuntimeException ex) { stsRegion = defaultRegion; } return stsRegion; } private static final class StsRetryCondition implements RetryCondition { public boolean shouldRetry(RetryPolicyContext context) { return context.exception() instanceof IdpCommunicationErrorException; } } } private enum LicenseSystemSetting implements SystemSetting { AWS_WEB_IDENTITY_REFRESH_TOKEN_FILE("aws.webIdentityRefreshTokenFile"); private String systemProperty; private String defaultValue = null; LicenseSystemSetting(String systemProperty) { this.systemProperty = systemProperty; } @Override public String property() { return this.systemProperty; } @Override public String environmentVariable() { return this.name(); } @Override public String defaultValue() { return this.defaultValue; } } }

LicenseManagerCredentialsProvider: implementación de Golang

LicenseCredentialsProvider

LicenseCredentialsProvideramplía la cadena AWS SDK de proveedores de credenciales predeterminada para su uso local mediante la adición de. LicenseManagerTokenCredentialsProvider

package lib import ( "context" "fmt" "sync" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/config" ) // LicenseCredentialsProvider is the custom credential provider that can retrieve valid temporary aws credentials type LicenseCredentialsProvider struct { fallBackProvider aws.CredentialsProvider mux sync.RWMutex licenseCredentials aws.Credentials err error } // NewLicenseCredentialsProvider method will create a LicenseCredentialProvider Object which contains valid temporary aws credentials func NewLicenseCredentialsProvider() (*LicenseCredentialsProvider, error) { licenseCredentialProvider := &LicenseCredentialsProvider{} fallBackProvider, err := createCredentialProvider() if err != nil { return licenseCredentialProvider, fmt.Errorf("failed to create LicenseCredentialsProvider, %w", err) } licenseCredentialProvider.fallBackProvider = fallBackProvider return licenseCredentialProvider, nil } // Retrieve method will retrieve temporary aws credentials from the credential provider func (l *LicenseCredentialsProvider) Retrieve(ctx context.Context) (aws.Credentials, error) { l.mux.RLock() defer l.mux.RUnlock() l.licenseCredentials, l.err = l.fallBackProvider.Retrieve(ctx) return l.licenseCredentials, l.err } func createCredentialProvider() (aws.CredentialsProvider, error) { // LoadDefaultConfig will examine all "default" credential providers ctx := context.TODO() cfg, err := config.LoadDefaultConfig(ctx) if err != nil { return nil, fmt.Errorf("failed to create FallBackProvider, %w", err) } var useFallbackProvider bool if cfg.Credentials != nil { if _, err := cfg.Credentials.Retrieve(ctx); err != nil { // If the "default" credentials provider cannot retrieve credentials, enable fallback to customCredentialsProvider. useFallbackProvider = true } } else { useFallbackProvider = true } if useFallbackProvider { customProvider, err := newLicenseManagerTokenCredentialsProvider() if err != nil { return cfg.Credentials, fmt.Errorf("failed to create fallBackProvider, %w", err) } // wrap up customProvider with CredentialsCache to enable caching cfg.Credentials = aws.NewCredentialsCache(customProvider) } return cfg.Credentials, nil }

LicenseManagerTokenCredentialsProvider

LicenseManagerTokenCredentialsProviderproporciona credenciales mediante el uso de tokens de identidad OIDC emitidos por License Manager en entornos locales. Debe incluir el código fuente para LicenseCredentialsProvider en la ruta de clases de su aplicación.

package lib import ( "context" "fmt" "io/ioutil" "os" "sync" "time" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/sts" ) const awsRefreshTokenFilePathEnvVar = "AWS_LICENSE_ACCESS_FILE" // licenseManagerTokenCredentialsProvider defines and contains StsAssumeRoleWithWebIdentityProvider type licenseManagerTokenCredentialsProvider struct { stsCredentialProvider *stsAssumeRoleWithWebIdentityProvider mux sync.RWMutex licenseCredentials aws.Credentials err error } // Retrieve method will retrieve credentials from credential provider. // Make this method public to make this provider satisfies CredentialProvider interface func (a *licenseManagerTokenCredentialsProvider) Retrieve(ctx context.Context) (aws.Credentials, error) { a.mux.RLock() defer a.mux.RUnlock() a.licenseCredentials, a.err = a.stsCredentialProvider.Retrieve(ctx) return a.licenseCredentials, a.err } // newLicenseManagerTokenCredentialsProvider will create and return a LicenseManagerTokenCredentialsProvider Object which wraps up stsAssumeRoleWithWebIdentityProvider func newLicenseManagerTokenCredentialsProvider() (*licenseManagerTokenCredentialsProvider, error) { // 1. Retrieve variables From yaml environment envConfig, err := config.NewEnvConfig() if err != nil { return &licenseManagerTokenCredentialsProvider{}, fmt.Errorf("failed to create LicenseManagerTokenCredentialsProvider, %w", err) } roleArn := envConfig.RoleARN var roleSessionName string if envConfig.RoleSessionName == "" { roleSessionName = fmt.Sprintf("aws-sdk-go-v2-%v", time.Now().UnixNano()) } else { roleSessionName = envConfig.RoleSessionName } tokenFilePath := os.Getenv(awsRefreshTokenFilePathEnvVar) b, err := ioutil.ReadFile(tokenFilePath) if err != nil { return &licenseManagerTokenCredentialsProvider{}, fmt.Errorf("failed to create LicenseManagerTokenCredentialsProvider, %w", err) } refreshToken := aws.String(string(b)) // 2. Create stsClient cfg, err := config.LoadDefaultConfig(context.TODO()) if err != nil { return &licenseManagerTokenCredentialsProvider{}, fmt.Errorf("failed to create LicenseManagerTokenCredentialsProvider, %w", err) } stsClient := sts.NewFromConfig(cfg, func(o *sts.Options) { o.Region = configureStsClientRegion(cfg.Region) o.Credentials = aws.AnonymousCredentials{} }) // 3. Configure StsAssumeRoleWithWebIdentityProvider stsCredentialProvider := newStsAssumeRoleWithWebIdentityProvider(stsClient, roleArn, roleSessionName, refreshToken) // 4. Build and return return &licenseManagerTokenCredentialsProvider{ stsCredentialProvider: stsCredentialProvider, }, nil } func configureStsClientRegion(configRegion string) string { defaultRegion := "us-east-1" if configRegion == "" { return defaultRegion } else { return configRegion } }