I'm using Spotify's Docker-Client, but have ran into a documentation wall. I'm trying to figure out how to pass docker secrets that are already created in the environment to the containers built using docker-client. The documentation only shows how to create secrets, but this isn't very useful since the secrets already exist. I'm able to get a list of secrets in the environment using the listSecrets in DockerClient, but I have no way to convert them from Secret to SecretBind. Any help is very much appreciated.
I figured this out looking through all of the code spotify/docker-client code. The documentation does not show a way to convert a Secret to SecretBind that ContainerSpec needs to pass in the Docker Secrets.
public SecretBind createBind(Secret secret) {
SecretFile file = SecretFile.builder()
.name(secret.secretSpect().name())
.uid("0")
.gid("0")
.build();
SecretBind bind = SecretBind.builder()
.secretName(secret.secretSpec().name())
.secretId(secret.id())
.file(file)
.build();
return bind;
}
Related
I am trying to programmatically start Google Cloud virtual machine instances. It occurred to me that in order to have internet access, have to set an external IP address.
// Access Config
AccessConfig accessConfig = AccessConfig.newBuilder()
.setNatIP("foo")
.setType("ONE_TO_ONE_NAT")
.setName("External NAT")
.setExternalIpv6("bar")
.build();
// Use the network interface provided in the networkName argument.
NetworkInterface networkInterface = NetworkInterface.newBuilder()
.setName(networkName)
.setAccessConfigs(0, accessConfig)
.build();
That is my status quo. It is inspired by this article post. I hoped that would work in Java, too, but currently, I am stuck.
All I get is:
com.google.api.gax.rpc.InvalidArgumentException: Bad Request
Unfortunately, Google Cloud Compute Engine Docs doesn't really provide any further information, on how to set the external IP properly.
Thanks in advance.
I have encountered the answer. In the Google Cloud Compute Engine Docs it is explained for Windows Instances. It took me a while to recognize it because I've focused only Linux Instances' related questions.
The solution:
instanceResource = Instance.newBuilder()
.setName(instanceName)
.setMachineType(machineType)
.addDisks(disk)
// Add external internet to instance
.addNetworkInterfaces(NetworkInterface.newBuilder()
.addAccessConfigs(AccessConfig.newBuilder()
.setType("ONE_TO_ONE_NAT")
.setName("External NAT")
.build())
.setName("global/networks/default")
.build())
.setMetadata(buildMetadata())
.build();
I have successfully provisioned a device in Azure IoT using TPM authentication by following this sample and the following guide: https://learn.microsoft.com/en-us/azure/iot-dps/quick-enroll-device-tpm-java
Now that my device is provisioned I'm trying to figure out the simplest way to connect to the IoT Hub using the keys stored on the TPM chip. I've tried the following code snippet:
SecurityProviderTpm securityClientTPM = new SecurityProviderTPMHsm();
DeviceClient client = DeviceClient.createFromSecurityProvider("myhub.azure-devices.net", "my-device", securityClientTPM, IotHubClientProtocol.HTTPS);
but this fails with:
Exception in thread "main" java.io.IOException: com.microsoft.azure.sdk.iot.provisioning.security.exceptions.SecurityProviderException: activateIdentityKey first before signing
at com.microsoft.azure.sdk.iot.device.auth.IotHubSasTokenHardwareAuthenticationProvider.generateSasTokenSignatureFromSecurityProvider(IotHubSasTokenHardwareAuthenticationProvider.java:169)
at com.microsoft.azure.sdk.iot.device.auth.IotHubSasTokenHardwareAuthenticationProvider.<init>(IotHubSasTokenHardwareAuthenticationProvider.java:51)
at com.microsoft.azure.sdk.iot.device.DeviceClientConfig.<init>(DeviceClientConfig.java:192)
at com.microsoft.azure.sdk.iot.device.InternalClient.<init>(InternalClient.java:109)
at com.microsoft.azure.sdk.iot.device.DeviceClient.<init>(DeviceClient.java:284)
at com.microsoft.azure.sdk.iot.device.DeviceClient.createFromSecurityProvider(DeviceClient.java:250)
at samples.com.microsoft.azure.sdk.iot.SendEvent.main(SendEvent.java:88)
Caused by: com.microsoft.azure.sdk.iot.provisioning.security.exceptions.SecurityProviderException: activateIdentityKey first before signing
at com.microsoft.azure.sdk.iot.provisioning.security.hsm.SecurityProviderTPMHsm.signWithIdentity(SecurityProviderTPMHsm.java:371)
at com.microsoft.azure.sdk.iot.device.auth.IotHubSasTokenHardwareAuthenticationProvider.generateSasTokenSignatureFromSecurityProvider(IotHubSasTokenHardwareAuthenticationProvider.java:155)
... 6 more
Searching the SDK code shows that activateIdentityKey is only called during the provisioning process though.
Re-invoking the provisioning proceedure everytime I want to connect the client doesn't seem right. Is there a better way to connect the device to the IoT Hub once it's been provisioned?
I was able to work around this by removing the check in the signWithIdentity function and removing the need to pass the publicArea to the signData function.
The publicArea is only used to derive the hash algorithm which can be set to a constant given that we know how the key was created.
My updated signData function looks like:
private byte[] signData(Tpm tpm, byte[] tokenData) throws SecurityProviderException {
TPM_ALG_ID idKeyHashAlg = TPM_ALG_ID.SHA256;
...
This has been working well for us so far, but it would be nice to get some feedback from the library authors :)
There are several notes on how to run Instance with given IAM Role and create one. But what about retrieving such data from EC2 service using Amazon Client (Java SDK) or http-requests via Amazon API? Can I get such list of IAM Roles somehow (they were preliminary created in EC2 console by devOps team, so I must somehow expose them in other web-application)? Thanks in advance.
Okay. Seems like AmazonIdentityManagementClient listInstanceProfiles() call does the trick.
Some kind of solution should work. Sorry for bother.
public Collection<String> getIAMRolesRange() {
AmazonIdentityManagementClient identityManagementClient = new AmazonIdentityManagementClient(new BasicAWSCredentials(awsAccount.getAccessKeyId(), awsAccount.getAccessSecret()));
ListInstanceProfilesResult listInstanceProfilesResult = identityManagementClient.listInstanceProfiles();
List<String> iamRoles = new LinkedList<String>();
for(InstanceProfile instanceProfile: listInstanceProfilesResult.getInstanceProfiles()) {
iamRoles.addAll(Collections2.transform(instanceProfile.getRoles(), iamRoleToStringFunction));
}
return iamRoles;
}
I'll first say that I'm sure it is just me since people have probably got this to work out of the box without having to edit the ADAL 4 Android Library without editing the source.
When running the sample program and authenticating with a token I get an error from AZURE that it is not passing the client_secret in the message body. I can confirm that this is in fact the case - it is not passing the client_secret.
Although if I edit the OAuth2.java file and change the method buildTokenRequestMessage to something like the following the workflow works perfectly
public String buildTokenRequestMessage(String code) throws UnsupportedEncodingException {
String message = String.format("%s=%s&%s=%s&%s=%s&%s=%s&%s=%s",
AuthenticationConstants.OAuth2.GRANT_TYPE,
StringExtensions.URLFormEncode(AuthenticationConstants.OAuth2.AUTHORIZATION_CODE),
AuthenticationConstants.OAuth2.CODE, StringExtensions.URLFormEncode(code),
AuthenticationConstants.OAuth2.CLIENT_ID,
StringExtensions.URLFormEncode(mRequest.getClientId()),
AuthenticationConstants.OAuth2.REDIRECT_URI,
StringExtensions.URLFormEncode(mRequest.getRedirectUri())
// these are the two lines I've added to make it work
AuthenticationConstants.OAuth2.CLIENT_SECRET,
StringExtensions.URLFormEncode("<MY CLIENT SECRET>")
);
return message;
}
Am I doing something wrong? If not, what is the correct way to access the client secret?
My implementation is straight from the demo application with only changes being setting up the strings to match my endpoints.
Thanks
You need to register your app as a Native application at Azure AD portal. You don't need client secret for native app.
So I have a java program running within an Amazon EC2 instance. Is there a way to programatically get its own tags? I have tried instantiating a new AmazonEC2Client to us the describeTags() function but it only gives me null. Any help would be appreciated thank you.
Edit: To make things clearer, the instances are going to be unmanned worker machines spun up to solely do some computations
This should help you get started...
String instanceId = EC2MetadataUtils.getInstanceId();
AmazonEC2 client = AmazonEC2ClientBuilder.standard()
.withCredentials(new DefaultAWSCredentialsProviderChain())
.build();
DescribeTagsRequest req = new DescribeTagsRequest()
.withFilters(new Filter("resource-id", Collections.singletonList(instanceId)));
DescribeTagsResult describeTagsResult = client.describeTags(req);
List<TagDescription> tags = describeTagsResult.getTags()
You should be able to get the current instance id by sending a request to: http://169.254.169.254/latest/meta-data/instance-id. This only works within ec2. With this you can access quite a bit of information about the instance. However, tags do not appear to be included.
You should be able to take the instance id along with the correct authentication to get the instance tags. If you are going to run this on an instance, you may want to provide an IAM user with limited access instead of a user which has access to everything in case the instance is compromised.
While using user-data may be the simplest solution, the OP was asking specifically about the tagging, and unfortunately amazon hasn't made this as easy as it could be. However, It can be done. You want to use a combination of 2 amazon services.
First you need to retrieve the Instance ID. This can be achieved by hitting the URL from within your instance:
http://169.254.169.254/latest/meta-data/instance-id
Once you have the resource ID, you'll want to use Amazon's EC2 API to access the tags. Since you said you're using Java, I would suggest the Using the AWS SDK amazon makes available. Within this SDK you'll find a method called describeTags (documentation). You can use a Resource ID as one of the filters to get the specific tags to your instance. Supported filters are
tag key
resource-id
resource-type
I suggest doing this retrieval at boot using something like cloud-init and caching the tags on your server for use later if necessary.