最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

In my Portainer container: How can I export stack details (services) of stacks that are created outside of Portainer (type=swarm

programmeradmin6浏览0评论

I have a portainer on a remote server with containers inside. With following code I can list stacks and the stack details of the containers without problem, when the control of the stacks are "total" and the type is "compose". But for stacks that are built outside of Portainer (control=limited, type=swarm), I get them not listed. I am looking for a code that can list also these.

My current code:

public static async Task Export_Portainer_Main()
    {
        string baseUrl = "myurl"; // 
        string username = "myuser";
        string password = "mypassword";
        string exportPath = @"C:\temp\Portainer\Export"; // 
        string stacksFilePath = @"C:\temp\Portainer\Export\stacks.txt"; // 

        try
        {
            // Authenticate and get token
            string token = await Authenticate(baseUrl, username, password);

            // List endpoints and stacks
            await ListEndpointsAndStacks(baseUrl, token, stacksFilePath);

            // Export all stacks
            await ExportAllStacks(baseUrl, token, exportPath);
            Console.WriteLine("All stacks exported successfully.");
            Console.ReadKey();
            
        }
        catch (Exception ex)
        {
            Console.WriteLine($"An error occurred: {ex.Message}");
            Console.ReadKey();
        }
    }



    private static async Task<string> Authenticate(string baseUrl, string username, string password)
    {
        using (var client = new HttpClient())
        {
            var authData = new { Username = username, Password = password };
            var content = new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(authData));
            content.Headers.ContentType = new MediaTypeHeaderValue("application/json");

            var response = await client.PostAsync($"{baseUrl}/api/auth", content);
            response.EnsureSuccessStatusCode();

            var responseData = await response.Content.ReadAsStringAsync();
            return JObject.Parse(responseData)["jwt"].ToString(); // Extract JWT token
        }
    }

    private static async Task ListEndpointsAndStacks(string baseUrl, string token, string filePath)
    {
        using (var client = new HttpClient())
        {
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);

            var sb = new StringBuilder();

            // Fetch all endpoints
            var endpointsResponse = await client.GetAsync($"{baseUrl}/api/endpoints");
            endpointsResponse.EnsureSuccessStatusCode();

            var endpoints = JArray.Parse(await endpointsResponse.Content.ReadAsStringAsync());

            // Fetch all stacks globally
            var stacksResponse = await client.GetAsync($"{baseUrl}/api/stacks");
            stacksResponse.EnsureSuccessStatusCode();

            var stacks = JArray.Parse(await stacksResponse.Content.ReadAsStringAsync());

            sb.AppendLine("Endpoints and Stacks:");
            sb.AppendLine("=====================");

            foreach (var endpoint in endpoints)
            {
                string endpointId = endpoint["Id"].ToString();
                string endpointName = endpoint["Name"].ToString();

                sb.AppendLine($"Endpoint: {endpointName} (ID: {endpointId})");

                // Filter stacks for this endpoint
                var stacksForEndpoint = stacks.Where(stack => stack["EndpointId"].ToString() == endpointId);

                if (!stacksForEndpoint.Any())
                {
                    sb.AppendLine("  No stacks found.");
                }
                else
                {
                    foreach (var stack in stacksForEndpoint)
                    {
                        string stackName = stack["Name"].ToString();
                        sb.AppendLine($"  Stack: {stackName}");
                    }
                }

                sb.AppendLine(); // Blank line between endpoints
            }

            // Write all data to file
            File.WriteAllText(filePath, sb.ToString());

            Console.WriteLine($"Endpoints and stack names written to: {filePath}");
        }
    }




    private static async Task ExportAllStacks(string baseUrl, string token, string exportPath)
    {
        using (var client = new HttpClient())
        {
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);

            // Ensure the export directory exists
            Directory.CreateDirectory(exportPath);

            try
            {
                // Fetch all endpoints
                var endpointsResponse = await client.GetAsync($"{baseUrl}/api/endpoints");
                endpointsResponse.EnsureSuccessStatusCode();

                var endpoints = JArray.Parse(await endpointsResponse.Content.ReadAsStringAsync());

                // Fetch all stacks globally
                var stacksResponse = await client.GetAsync($"{baseUrl}/api/stacks");
                stacksResponse.EnsureSuccessStatusCode();

                var stacks = JArray.Parse(await stacksResponse.Content.ReadAsStringAsync());

                // Group stacks by endpoint
                foreach (var endpoint in endpoints)
                {
                    string endpointId = endpoint["Id"].ToString();
                    string endpointName = endpoint["Name"].ToString();

                    Console.WriteLine($"Processing Endpoint: {endpointName} (ID: {endpointId})");

                    var endpointStacks = stacks.Where(stack => stack["EndpointId"].ToString() == endpointId).ToList();

                    if (!endpointStacks.Any())
                    {
                        Console.WriteLine($"  No stacks found for endpoint '{endpointName}' (ID: {endpointId})");
                        continue;
                    }

                    foreach (var stack in endpointStacks)
                    {
                        string stackId = stack["Id"].ToString();
                        string stackName = stack["Name"].ToString();

                        try
                        {
                            Console.WriteLine($"Exporting Stack: {stackName} (ID: {stackId}) for Endpoint: {endpointName}");

                            // Fetch stack file content
                            var stackFileResponse = await client.GetAsync($"{baseUrl}/api/stacks/{stackId}/file");

                            if (!stackFileResponse.IsSuccessStatusCode)
                            {
                                Console.WriteLine($"  Failed to export stack '{stackName}' for endpoint '{endpointName}': {stackFileResponse.ReasonPhrase}");
                                continue; // Skip this stack and continue with the next one
                            }

                            string stackFileContent = await stackFileResponse.Content.ReadAsStringAsync();

                            // Save to a file, including the endpoint name for uniqueness
                            string sanitizedFileName = Path.Combine(exportPath, $"{endpointName}_{stackName.Replace(" ", "_")}.txt");
                            File.WriteAllText(sanitizedFileName, stackFileContent);

                            Console.WriteLine($"  Stack '{stackName}' exported to '{sanitizedFileName}'");
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine($"  Error exporting stack '{stackName}' for endpoint '{endpointName}': {ex.Message}");
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"An error occurred: {ex.Message}");
            }
        }
    }

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论