{"id":33,"date":"2023-11-29T09:16:29","date_gmt":"2023-11-29T14:16:29","guid":{"rendered":"https:\/\/coding101.xyz\/?p=33"},"modified":"2023-12-02T20:00:44","modified_gmt":"2023-12-03T01:00:44","slug":"bucket-storage-similar-with-s3-at-linode","status":"publish","type":"post","link":"https:\/\/coding101.xyz\/?p=33","title":{"rendered":"Bucket Storage similar with S3 at Linode"},"content":{"rendered":"\n<p>This shows how to access the bucket storage at Linode with the code you normally use for AWS.<\/p>\n\n\n\n<!--more-->\n\n\n\n<p>More and more cloud providers are rolling out bucket storage solutions similar with S3. The similarity goes to the point that you can merely repoint your application from AWS related urls to the new ones and it works out of the box. <\/p>\n\n\n\n<p>The only thing needed is to change the configuration. The main points around the new configuration<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>New endpoint. AWS S3 commands typically work without endpoint, if you selected the correct region. Any provider other than AWS <strong>must<\/strong> have the endpoint set. <\/li>\n\n\n\n<li>AWS key and secret key are of course set on the provider. Linode allows setting those keys specifically for the bucket storage service. <\/li>\n<\/ul>\n\n\n\n<p>The endpoint for the region Newark \/ New Jersey in Linode looks like that:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>https:&#47;&#47;us-east-1.linodeobjects.com<\/code><\/pre>\n\n\n\n<p>Note that the region name is us-east-1 in our situation. With this new region, provided that we ran AWS configure and set the right key and secret key  (yes, AWS cli works as well out of the box with the Linode bucket services) then this would be the required command to list for example the existing buckets under our account<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>aws s3 ls --endpoint=https:\/\/us-east-1.linodeobjects.com<\/code><\/pre>\n\n\n\n<p>This lists the buckets inside our linode bucket storage. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Example of accessing bucket Linode services from Java<\/h2>\n\n\n\n<p>Here is the maven dependency needed to get this<\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;\"><pre style=\"margin: 0; line-height: 125%\">        <span style=\"color: #007700\">&lt;dependency&gt;<\/span>\n            <span style=\"color: #007700\">&lt;groupId&gt;<\/span>com.amazonaws<span style=\"color: #007700\">&lt;\/groupId&gt;<\/span>\n            <span style=\"color: #007700\">&lt;artifactId&gt;<\/span>aws-java-sdk-s3<span style=\"color: #007700\">&lt;\/artifactId&gt;<\/span>\n            <span style=\"color: #007700\">&lt;version&gt;<\/span>1.12.470<span style=\"color: #007700\">&lt;\/version&gt;<\/span>\n        <span style=\"color: #007700\">&lt;\/dependency&gt;<\/span>\n<\/pre><\/div>\n\n\n\n<p>And here is the code, including the imports<\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;\"><pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #008800; font-weight: bold\">package<\/span> org<span style=\"color: #333333\">.<\/span><span style=\"color: #0000CC\">example<\/span><span style=\"color: #333333\">;<\/span>\n\n<span style=\"color: #008800; font-weight: bold\">import<\/span> <span style=\"color: #0e84b5; font-weight: bold\">com.amazonaws.auth.AWSStaticCredentialsProvider<\/span><span style=\"color: #333333\">;<\/span>\n<span style=\"color: #008800; font-weight: bold\">import<\/span> <span style=\"color: #0e84b5; font-weight: bold\">com.amazonaws.auth.BasicAWSCredentials<\/span><span style=\"color: #333333\">;<\/span>\n<span style=\"color: #008800; font-weight: bold\">import<\/span> <span style=\"color: #0e84b5; font-weight: bold\">com.amazonaws.client.builder.AwsClientBuilder<\/span><span style=\"color: #333333\">;<\/span>\n<span style=\"color: #008800; font-weight: bold\">import<\/span> <span style=\"color: #0e84b5; font-weight: bold\">com.amazonaws.services.s3.AmazonS3<\/span><span style=\"color: #333333\">;<\/span>\n<span style=\"color: #008800; font-weight: bold\">import<\/span> <span style=\"color: #0e84b5; font-weight: bold\">com.amazonaws.services.s3.AmazonS3ClientBuilder<\/span><span style=\"color: #333333\">;<\/span>\n<span style=\"color: #008800; font-weight: bold\">import<\/span> <span style=\"color: #0e84b5; font-weight: bold\">com.amazonaws.services.s3.model.Bucket<\/span><span style=\"color: #333333\">;<\/span>\n\n<span style=\"color: #008800; font-weight: bold\">import<\/span> <span style=\"color: #0e84b5; font-weight: bold\">java.util.List<\/span><span style=\"color: #333333\">;<\/span>\n\n<span style=\"color: #008800; font-weight: bold\">public<\/span> <span style=\"color: #008800; font-weight: bold\">class<\/span> <span style=\"color: #BB0066; font-weight: bold\">Main<\/span> <span style=\"color: #333333\">{<\/span>\n    <span style=\"color: #008800; font-weight: bold\">public<\/span> <span style=\"color: #008800; font-weight: bold\">static<\/span> <span style=\"color: #333399; font-weight: bold\">void<\/span> <span style=\"color: #0066BB; font-weight: bold\">main<\/span><span style=\"color: #333333\">(<\/span>String<span style=\"color: #333333\">[]<\/span> args<span style=\"color: #333333\">)<\/span> <span style=\"color: #333333\">{<\/span>\n        <span style=\"color: #008800; font-weight: bold\">try<\/span> <span style=\"color: #333333\">{<\/span>\n            <span style=\"color: #008800; font-weight: bold\">new<\/span> <span style=\"color: #0066BB; font-weight: bold\">Main<\/span><span style=\"color: #333333\">().<\/span><span style=\"color: #0000CC\">start<\/span><span style=\"color: #333333\">();<\/span>\n        <span style=\"color: #333333\">}<\/span> <span style=\"color: #008800; font-weight: bold\">catch<\/span> <span style=\"color: #333333\">(<\/span>Exception e<span style=\"color: #333333\">)<\/span> <span style=\"color: #333333\">{<\/span>\n            e<span style=\"color: #333333\">.<\/span><span style=\"color: #0000CC\">printStackTrace<\/span><span style=\"color: #333333\">();<\/span>\n        <span style=\"color: #333333\">}<\/span>\n    <span style=\"color: #333333\">}<\/span>\n\n    <span style=\"color: #008800; font-weight: bold\">private<\/span> <span style=\"color: #333399; font-weight: bold\">void<\/span> <span style=\"color: #0066BB; font-weight: bold\">start<\/span><span style=\"color: #333333\">()<\/span> <span style=\"color: #008800; font-weight: bold\">throws<\/span> Exception <span style=\"color: #333333\">{<\/span>\n        String endpoint <span style=\"color: #333333\">=<\/span> <span style=\"background-color: #fff0f0\">&quot;https:\/\/us-east-1.linodeobjects.com&quot;<\/span><span style=\"color: #333333\">;<\/span>\n        String region <span style=\"color: #333333\">=<\/span> <span style=\"background-color: #fff0f0\">&quot;us-east-1&quot;<\/span><span style=\"color: #333333\">;<\/span>\n        BasicAWSCredentials credentials <span style=\"color: #333333\">=<\/span> <span style=\"color: #008800; font-weight: bold\">new<\/span> BasicAWSCredentials<span style=\"color: #333333\">(<\/span><span style=\"background-color: #fff0f0\">&quot;akey&quot;<\/span><span style=\"color: #333333\">,<\/span> <span style=\"background-color: #fff0f0\">&quot;secret key&quot;<\/span><span style=\"color: #333333\">);<\/span>\n        AWSStaticCredentialsProvider credentialsProvider <span style=\"color: #333333\">=<\/span> <span style=\"color: #008800; font-weight: bold\">new<\/span> AWSStaticCredentialsProvider<span style=\"color: #333333\">(<\/span>credentials<span style=\"color: #333333\">);<\/span>\n\n        AwsClientBuilder<span style=\"color: #333333\">.<\/span><span style=\"color: #0000CC\">EndpointConfiguration<\/span> configuration <span style=\"color: #333333\">=<\/span> <span style=\"color: #008800; font-weight: bold\">new<\/span> AwsClientBuilder<span style=\"color: #333333\">.<\/span><span style=\"color: #0000CC\">EndpointConfiguration<\/span><span style=\"color: #333333\">(<\/span>endpoint<span style=\"color: #333333\">,<\/span> region<span style=\"color: #333333\">);<\/span>\n        AmazonS3ClientBuilder builder <span style=\"color: #333333\">=<\/span> AmazonS3ClientBuilder<span style=\"color: #333333\">.<\/span><span style=\"color: #0000CC\">standard<\/span><span style=\"color: #333333\">().<\/span><span style=\"color: #0000CC\">withCredentials<\/span><span style=\"color: #333333\">(<\/span>credentialsProvider<span style=\"color: #333333\">);<\/span>\n        AmazonS3 client <span style=\"color: #333333\">=<\/span> builder<span style=\"color: #333333\">.<\/span><span style=\"color: #0000CC\">withEndpointConfiguration<\/span><span style=\"color: #333333\">(<\/span>configuration<span style=\"color: #333333\">).<\/span><span style=\"color: #0000CC\">build<\/span><span style=\"color: #333333\">();<\/span>\n\n        List<span style=\"color: #333333\">&lt;<\/span>Bucket<span style=\"color: #333333\">&gt;<\/span> buckets <span style=\"color: #333333\">=<\/span> client<span style=\"color: #333333\">.<\/span><span style=\"color: #0000CC\">listBuckets<\/span><span style=\"color: #333333\">();<\/span>\n        buckets<span style=\"color: #333333\">.<\/span><span style=\"color: #0000CC\">forEach<\/span><span style=\"color: #333333\">(<\/span>bucket <span style=\"color: #333333\">-&gt;<\/span> System<span style=\"color: #333333\">.<\/span><span style=\"color: #0000CC\">out<\/span><span style=\"color: #333333\">.<\/span><span style=\"color: #0000CC\">println<\/span><span style=\"color: #333333\">(<\/span>bucket<span style=\"color: #333333\">.<\/span><span style=\"color: #0000CC\">getName<\/span><span style=\"color: #333333\">()));<\/span>\n    <span style=\"color: #333333\">}<\/span>\n<span style=\"color: #333333\">}<\/span>\n<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Example of accessing bucket Linode services from Python<\/h2>\n\n\n\n<p>There is a package called boto3 which is advertised on AWS website, so this is the standard, it seems. The calls are very easy to instrument, here is a sample<\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;\"><pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #008800; font-weight: bold\">import<\/span> <span style=\"color: #0e84b5; font-weight: bold\">boto3<\/span>\n\n\n<span style=\"color: #008800; font-weight: bold\">def<\/span> <span style=\"color: #0066BB; font-weight: bold\">starting<\/span>():\n    client <span style=\"color: #333333\">=<\/span> boto3<span style=\"color: #333333\">.<\/span>client(<span style=\"background-color: #fff0f0\">&#39;s3&#39;<\/span>, region_name<span style=\"color: #333333\">=<\/span><span style=\"background-color: #fff0f0\">&#39;us-east-1&#39;<\/span>,\n                 endpoint_url<span style=\"color: #333333\">=<\/span><span style=\"background-color: #fff0f0\">&#39;https:\/\/us-east-1.linodeobjects.com&#39;<\/span>,\n                 aws_access_key_id<span style=\"color: #333333\">=<\/span><span style=\"background-color: #fff0f0\">&#39;key id&#39;<\/span>,\n                 aws_secret_access_key<span style=\"color: #333333\">=<\/span><span style=\"background-color: #fff0f0\">&#39;secret access key&#39;<\/span>)\n\n    buckets <span style=\"color: #333333\">=<\/span> client<span style=\"color: #333333\">.<\/span>list_buckets()\n    raw_data <span style=\"color: #333333\">=<\/span> buckets[<span style=\"background-color: #fff0f0\">&#39;Buckets&#39;<\/span>];\n    <span style=\"color: #008800; font-weight: bold\">for<\/span> dt <span style=\"color: #000000; font-weight: bold\">in<\/span> raw_data:\n        <span style=\"color: #008800; font-weight: bold\">print<\/span>(<span style=\"background-color: #fff0f0\">&#39;current name: &#39;<\/span>, dt[<span style=\"background-color: #fff0f0\">&#39;Name&#39;<\/span>])\n\n\n<span style=\"color: #008800; font-weight: bold\">if<\/span> __name__ <span style=\"color: #333333\">==<\/span> <span style=\"background-color: #fff0f0\">&#39;__main__&#39;<\/span>:\n    starting()\n<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Example of accessing bucket Linode services from Golang<\/h2>\n\n\n\n<p>In golang there are a number of libraries recommended to be used to connect to AWS. All of them of course are developed at Amazon. S3, as expected, works everywhere. Here is the program that lists the buckets in a S3 account end to end &#8211; including the imports. <\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;\"><pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #008800; font-weight: bold\">package<\/span> main\n\n<span style=\"color: #008800; font-weight: bold\">import<\/span> (\n<span style=\"background-color: #fff0f0\">&quot;fmt&quot;<\/span>\n<span style=\"background-color: #fff0f0\">&quot;github.com\/aws\/aws-sdk-go\/aws&quot;<\/span>\n<span style=\"background-color: #fff0f0\">&quot;github.com\/aws\/aws-sdk-go\/aws\/credentials&quot;<\/span>\n<span style=\"background-color: #fff0f0\">&quot;github.com\/aws\/aws-sdk-go\/aws\/session&quot;<\/span>\n<span style=\"background-color: #fff0f0\">&quot;github.com\/aws\/aws-sdk-go\/service\/s3&quot;<\/span>\n)\n\n<span style=\"color: #008800; font-weight: bold\">func<\/span> main() {\nerr <span style=\"color: #333333\">:=<\/span> proceed()\n<span style=\"color: #008800; font-weight: bold\">if<\/span> err <span style=\"color: #333333\">!=<\/span> <span style=\"color: #008800; font-weight: bold\">nil<\/span> {\nfmt.Println(<span style=\"background-color: #fff0f0\">&quot;there was an error: &quot;<\/span>, err.Error())\n}\n}\n\n<span style=\"color: #008800; font-weight: bold\">func<\/span> proceed() <span style=\"color: #333399; font-weight: bold\">error<\/span> {\ncreds <span style=\"color: #333333\">:=<\/span> credentials.NewCredentials(<span style=\"color: #333333\">&amp;<\/span>credentials.StaticProvider{Value: credentials.Value{\nAccessKeyID:     <span style=\"background-color: #fff0f0\">&quot;access key&quot;<\/span>,\nSecretAccessKey: <span style=\"background-color: #fff0f0\">&quot;secret access key&quot;<\/span>,\n}})\n\nsess, err <span style=\"color: #333333\">:=<\/span> session.NewSession(<span style=\"color: #333333\">&amp;<\/span>aws.Config{\nCredentials: creds,\nEndpoint:    aws.String(<span style=\"background-color: #fff0f0\">&quot;https:\/\/us-east-1.linodeobjects.com&quot;<\/span>),\nRegion:      aws.String(<span style=\"background-color: #fff0f0\">&quot;us-east-1&quot;<\/span>),\n})\n\n<span style=\"color: #008800; font-weight: bold\">if<\/span> err <span style=\"color: #333333\">!=<\/span> <span style=\"color: #008800; font-weight: bold\">nil<\/span> {\n<span style=\"color: #008800; font-weight: bold\">return<\/span> err\n}\n\nsvc <span style=\"color: #333333\">:=<\/span> s3.New(sess)\nout, err <span style=\"color: #333333\">:=<\/span> svc.ListBuckets(<span style=\"color: #008800; font-weight: bold\">nil<\/span>)\n<span style=\"color: #008800; font-weight: bold\">if<\/span> err <span style=\"color: #333333\">!=<\/span> <span style=\"color: #008800; font-weight: bold\">nil<\/span> {\n<span style=\"color: #008800; font-weight: bold\">return<\/span> err\n}\n\nbuckets <span style=\"color: #333333\">:=<\/span> out.Buckets\n<span style=\"color: #008800; font-weight: bold\">for<\/span> _, bucket <span style=\"color: #333333\">:=<\/span> <span style=\"color: #008800; font-weight: bold\">range<\/span> buckets {\nfmt.Println(<span style=\"color: #333333\">*<\/span>bucket.Name)\n}\n\n<span style=\"color: #008800; font-weight: bold\">return<\/span> <span style=\"color: #008800; font-weight: bold\">nil<\/span>\n}\n<\/pre><\/div>\n\n\n\n<p>Note a couple of things<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Endpoint must be mentioned if you do not connect to AWS but to another provider<\/li>\n\n\n\n<li>It is possible to omit the credentials in which case will take them from .aws folder, however in a containerized Docker or Kubernetes solution this is not at all recommended, typically the credentials come from an adjacent artifact like Cyber Ark or similar <\/li>\n<\/ul>\n\n\n\n<p>The above is just an idea of how to connect. Of course there are a gazillion of methods and packages that support the S3 access in Go but all of them go through this connectivity step. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>This shows how to access the bucket storage at Linode with the code you normally use for AWS.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-33","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/coding101.xyz\/index.php?rest_route=\/wp\/v2\/posts\/33","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/coding101.xyz\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/coding101.xyz\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/coding101.xyz\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/coding101.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=33"}],"version-history":[{"count":7,"href":"https:\/\/coding101.xyz\/index.php?rest_route=\/wp\/v2\/posts\/33\/revisions"}],"predecessor-version":[{"id":97,"href":"https:\/\/coding101.xyz\/index.php?rest_route=\/wp\/v2\/posts\/33\/revisions\/97"}],"wp:attachment":[{"href":"https:\/\/coding101.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=33"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/coding101.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=33"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/coding101.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=33"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}