1package storage
2
3// Copyright 2017 Microsoft Corporation
4//
5//  Licensed under the Apache License, Version 2.0 (the "License");
6//  you may not use this file except in compliance with the License.
7//  You may obtain a copy of the License at
8//
9//      http://www.apache.org/licenses/LICENSE-2.0
10//
11//  Unless required by applicable law or agreed to in writing, software
12//  distributed under the License is distributed on an "AS IS" BASIS,
13//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14//  See the License for the specific language governing permissions and
15//  limitations under the License.
16
17import (
18	"net/http"
19	"net/url"
20	"strconv"
21)
22
23// ServiceProperties represents the storage account service properties
24type ServiceProperties struct {
25	Logging       *Logging
26	HourMetrics   *Metrics
27	MinuteMetrics *Metrics
28	Cors          *Cors
29}
30
31// Logging represents the Azure Analytics Logging settings
32type Logging struct {
33	Version         string
34	Delete          bool
35	Read            bool
36	Write           bool
37	RetentionPolicy *RetentionPolicy
38}
39
40// RetentionPolicy indicates if retention is enabled and for how many days
41type RetentionPolicy struct {
42	Enabled bool
43	Days    *int
44}
45
46// Metrics provide request statistics.
47type Metrics struct {
48	Version         string
49	Enabled         bool
50	IncludeAPIs     *bool
51	RetentionPolicy *RetentionPolicy
52}
53
54// Cors includes all the CORS rules
55type Cors struct {
56	CorsRule []CorsRule
57}
58
59// CorsRule includes all settings for a Cors rule
60type CorsRule struct {
61	AllowedOrigins  string
62	AllowedMethods  string
63	MaxAgeInSeconds int
64	ExposedHeaders  string
65	AllowedHeaders  string
66}
67
68func (c Client) getServiceProperties(service string, auth authentication) (*ServiceProperties, error) {
69	query := url.Values{
70		"restype": {"service"},
71		"comp":    {"properties"},
72	}
73	uri := c.getEndpoint(service, "", query)
74	headers := c.getStandardHeaders()
75
76	resp, err := c.exec(http.MethodGet, uri, headers, nil, auth)
77	if err != nil {
78		return nil, err
79	}
80	defer resp.Body.Close()
81
82	if err := checkRespCode(resp, []int{http.StatusOK}); err != nil {
83		return nil, err
84	}
85
86	var out ServiceProperties
87	err = xmlUnmarshal(resp.Body, &out)
88	if err != nil {
89		return nil, err
90	}
91
92	return &out, nil
93}
94
95func (c Client) setServiceProperties(props ServiceProperties, service string, auth authentication) error {
96	query := url.Values{
97		"restype": {"service"},
98		"comp":    {"properties"},
99	}
100	uri := c.getEndpoint(service, "", query)
101
102	// Ideally, StorageServiceProperties would be the output struct
103	// This is to avoid golint stuttering, while generating the correct XML
104	type StorageServiceProperties struct {
105		Logging       *Logging
106		HourMetrics   *Metrics
107		MinuteMetrics *Metrics
108		Cors          *Cors
109	}
110	input := StorageServiceProperties{
111		Logging:       props.Logging,
112		HourMetrics:   props.HourMetrics,
113		MinuteMetrics: props.MinuteMetrics,
114		Cors:          props.Cors,
115	}
116
117	body, length, err := xmlMarshal(input)
118	if err != nil {
119		return err
120	}
121
122	headers := c.getStandardHeaders()
123	headers["Content-Length"] = strconv.Itoa(length)
124
125	resp, err := c.exec(http.MethodPut, uri, headers, body, auth)
126	if err != nil {
127		return err
128	}
129	defer drainRespBody(resp)
130	return checkRespCode(resp, []int{http.StatusAccepted})
131}
132