v1-testing (#1)
All checks were successful
Actions Build Binary / Build-Binary (push) Successful in 5s
Actions Build Binary / Build-Docker-Image (push) Successful in 13s

Simple way to share your objects from MinIO

Reviewed-on: #1
Co-authored-by: Alex Borisov <79996669747@ya.ru>
Co-committed-by: Alex Borisov <79996669747@ya.ru>
This commit is contained in:
Alex Borisov 2024-02-01 22:32:40 +03:00 committed by soaska
parent 6cf99fe9b2
commit f42e9b381c
9 changed files with 329 additions and 0 deletions

View File

@ -0,0 +1,83 @@
name: Actions Build Binary
run-name: ${{ gitea.actor }} is building new image 🚀
on: push
jobs:
Build-Binary:
runs-on: soaska
steps:
- run: echo "🎉 The job was automatically triggered by a ${{ gitea.event_name }} event."
- name: Install Node.js, curl and go
run: |
apk add --no-cache nodejs curl go git
- name: Check out repository code
uses: actions/checkout@v3
- name: List files in the repository
run: |
ls ${{ gitea.workspace }}
- run: echo "🍏 This job's status is ${{ job.status }}."
- name: Install go dependencies
run: |
go mod download
- name: Build Binary
run: |
go build -o $(basename ${{ gitea.repository }}) .
env:
ENVIRONMENT: production
- name: Upload binary to soaska.ru
run: |
package_name=$(basename ${{ gitea.repository }})
branch_name=$(git rev-parse --abbrev-ref HEAD)
current_date=$(git log -1 --format=%cd --date=format:'%Y-%m-%d-%H-%M-%S')
curl --user ${{ secrets.username }}:${{ secrets.password }} \
--upload-file $package_name \
https://soaska.ru/api/packages/${{ secrets.username }}/generic/$package_name-$branch_name/$current_date/$package_name
env:
ENVIRONMENT: production
Build-Docker-Image:
runs-on: soaska
needs: Build-Binary
steps:
- run: echo "🎉 The job was automatically triggered by a ${{ gitea.event_name }} event."
- name: Install Node.js and curl
run: |
apk add --no-cache nodejs curl git
- name: Check out repository code
uses: actions/checkout@v3
- name: List files in the repository
run: |
ls ${{ gitea.workspace }}
- run: echo "🍏 This job's status is ${{ job.status }}."
- name: Install Docker
run: |
apk add --no-cache docker
- name: Start Docker service
run: |
dockerd &
sleep 5
docker info
- name: Get Binary from soaska.ru
run: |
package_name=$(basename ${{ gitea.repository }})
branch_name=$(git rev-parse --abbrev-ref HEAD)
current_date=$(git log -1 --format=%cd --date=format:'%Y-%m-%d-%H-%M-%S')
curl --user ${{ secrets.username }}:${{ secrets.password }} \
--output main \
https://soaska.ru/api/packages/${{ secrets.username }}/generic/$package_name-$branch_name/$current_date/$package_name
- name: List files in the repository
run: |
ls ${{ gitea.workspace }}
- name: Build Dockerfile
run: |
docker build -t $(basename ${{ github.repository}} | tr '[:upper:]' '[:lower:]') .
docker image ls
- name: Upload Docker image to soaska.ru
run: |
package_name=$(basename ${{ github.repository}} | tr '[:upper:]' '[:lower:]')
branch_name=$(git rev-parse --abbrev-ref HEAD | tr '[:upper:]' '[:lower:]')
docker login -u ${{ secrets.username }} -p ${{ secrets.password }} soaska.ru
docker tag $package_name:latest soaska.ru/${{ secrets.username }}/$package_name:$branch_name
docker tag $package_name:latest soaska.ru/${{ secrets.username }}/$package_name:latest
docker push soaska.ru/${{ secrets.username }}/$package_name:$branch_name
docker push soaska.ru/${{ secrets.username }}/$package_name:latest

12
.gitignore vendored
View File

@ -1,3 +1,5 @@
<<<<<<< HEAD
<<<<<<< HEAD
# ---> Go # ---> Go
# If you prefer the allow list template instead of the deny list, see community template: # If you prefer the allow list template instead of the deny list, see community template:
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore # https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
@ -21,3 +23,13 @@
# Go workspace file # Go workspace file
go.work go.work
=======
.env
.vscode
icon.jpg
>>>>>>> beta
=======
.env
.vscode
icon.jpg
>>>>>>> beta

4
Dockerfile Normal file
View File

@ -0,0 +1,4 @@
FROM alpine
WORKDIR /root/
COPY main .
CMD ["./main"]

View File

@ -6,4 +6,12 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
<<<<<<< HEAD
<<<<<<< HEAD
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
=======
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
>>>>>>> beta
=======
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
>>>>>>> beta

6
example.env Normal file
View File

@ -0,0 +1,6 @@
# Примеры переменных
S3_ACCESS_KEY_ID=your_access_key_id
S3_SECRET_ACCESS_KEY=your_secret_access_key
S3_BUCKET_NAME=your_bucket_name
S3_ENDPOINT_URL=your_endpoint
PORT=8080

20
go.mod Normal file
View File

@ -0,0 +1,20 @@
module soaska.ru/soaska/MinIO-Share-S3
go 1.21
require (
github.com/gorilla/mux v1.8.1
github.com/minio/minio-go v6.0.14+incompatible
)
require github.com/stretchr/testify v1.8.4 // indirect
require (
github.com/go-ini/ini v1.67.0 // indirect
github.com/joho/godotenv v1.5.1
github.com/mitchellh/go-homedir v1.1.0 // indirect
golang.org/x/crypto v0.18.0 // indirect
golang.org/x/net v0.20.0 // indirect
golang.org/x/sys v0.16.0 // indirect
golang.org/x/text v0.14.0 // indirect
)

26
go.sum Normal file
View File

@ -0,0 +1,26 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A=
github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/minio/minio-go v6.0.14+incompatible h1:fnV+GD28LeqdN6vT2XdGKW8Qe/IfjJDswNVuni6km9o=
github.com/minio/minio-go v6.0.14+incompatible/go.mod h1:7guKYtitv8dktvNUGrhzmNlA5wrAABTQXCoesZdFQO8=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

40
readme.md Normal file
View File

@ -0,0 +1,40 @@
# MinIO Share S3
MinIO Share S3 is a project that enables users to embed links to objects in MinIO and easily share them with others.
## Features
- **Object Embedding**: Users can generate embeddable links for objects stored in MinIO.
- **Easy Sharing**: The generated links can be easily shared with others, allowing them to access the objects.
- **Access Control**: Users can control the access permissions for the shared objects, ensuring data security using MinIO polices.
- **Simplified Workflow**: MinIO Share S3 provides a simple usage to share all your files in bucket
## Installation
To install MinIO Share S3, follow these steps:
1. Clone the repository: `git clone https://soaska.ru/soaska/minio-share-s3.git`
2. Install the required dependencies: `go mod download`
3. Configure the MinIO connection settings in the `.env` file.
4. Start the application: `go run`
You also can download precompiled binary from packages or set up docker container using `soaska.ru/soaska/minio-share-s3:master` image.
## Usage
Once the application is running, you can perform the following actions:
1. Upload objects to MinIO.
2. Generate access key and set up polices.
3. Set up MinIO Share S3.
4. Share links!
All environment variables are described in `sample.env` file.
## Contributing
Contributions are welcome! If you would like to contribute to MinIO Share S3, please open issue.
## License
MinIO Share S3 is licensed under the [MIT License](https://opensource.org/licenses/MIT).

130
run.go Normal file
View File

@ -0,0 +1,130 @@
package main
import (
"fmt"
"io"
"log"
"net/http"
"os"
"time"
"github.com/gorilla/mux"
"github.com/joho/godotenv"
"github.com/minio/minio-go"
)
func main() {
// Get environment variables
accessKeyID, secretAccessKey, bucketName, endpoint, port := getEnv()
// Initialize MinIO client
minioClient, err := minio.New(endpoint, accessKeyID, secretAccessKey, true)
if err != nil {
log.Fatal(err)
}
// Create a new router
router := mux.NewRouter()
// Define the file handler
router.HandleFunc("/{path:.*}", func(w http.ResponseWriter, r *http.Request) {
log.Printf("Received request: %s %s", r.Method, r.RequestURI)
vars := mux.Vars(r)
path := vars["path"]
log.Print("Path: ", path)
// Get the file from S3
object, err := minioClient.GetObject(bucketName, path, minio.GetObjectOptions{})
if err != nil {
if minio.ToErrorResponse(err).Code == "NoSuchKey" {
log.Printf("Object not found in S3: %s", err)
http.Error(w, "Object not found", http.StatusNotFound)
return
}
log.Printf("Error getting object from S3: %s", err)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// Get the object info
info, err := object.Stat()
if err != nil {
if minio.ToErrorResponse(err).Code == "NoSuchKey" {
log.Printf("Object not found in S3: %s", err)
http.Error(w, "Object not found", http.StatusNotFound)
return
}
log.Printf("Error getting object info: %s", err)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// Set the content type header
contentType := info.ContentType
w.Header().Set("Content-Type", contentType)
// Copy the file to the response writer
_, err = io.Copy(w, object)
if err != nil {
log.Printf("Error copying file to response writer: %s", err)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}).Methods("GET")
router.Use(loggingMiddleware)
// Start the server
if port == "" {
port = "8080"
}
addr := fmt.Sprintf(":%s", port)
log.Printf("Server listening on %s", addr)
log.Fatal(http.ListenAndServe(addr, router))
}
func getEnv() (string, string, string, string, string) {
if os.Getenv("ENVIRONMENT") != "production" {
err := godotenv.Load()
if err != nil {
log.Fatal("Error loading .env file")
}
}
// Get environment variables
port := os.Getenv("PORT")
accessKeyID := os.Getenv("S3_ACCESS_KEY_ID")
secretAccessKey := os.Getenv("S3_SECRET_ACCESS_KEY")
bucketName := os.Getenv("S3_BUCKET_NAME")
endpoint := os.Getenv("S3_ENDPOINT_URL")
return accessKeyID, secretAccessKey, bucketName, endpoint, port
}
func loggingMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
startTime := time.Now()
next.ServeHTTP(w, r)
duration := time.Since(startTime)
log.Printf("Processed request: %s %s. Duration: %v\n", r.Method, r.RequestURI, duration)
})
}
func GetObjectList(bucketName string, minioClient *minio.Client) ([]string, error) {
var objectList []string
// Get the list of objects
objectCh := minioClient.ListObjects(bucketName, "", true, nil)
for object := range objectCh {
if object.Err != nil {
return nil, object.Err
}
objectList = append(objectList, object.Key)
}
return objectList, nil
}